First, you must recognize that this is a data rule, and can only be really enforced at the time of delete - in the database. So you must check for data integrity during the delete operation. That's unavoidable, and if there's a failure at this time you should throw an exception (thus rolling back the transaction, and effectively notifying the UI layer).
You might also implement client-side code as a convenience for the user, to inform them that their delete attempt will fail before you actually try. Doing this incurs overhead, but can make for a nicer user experience, especially for Windows Forms or WPF apps. The plumbing for such a check is similar to the Exists() command you can find in the Project and Resource classes in ProjectTracker - probably Employee.Exists().
Given that, if your use case is as focused as it sounds, we can assume you'll have some read-only object(s) to allow the user to select the location to delete. You may then have a confirmation dialog, displaying the location info to the user and asking if they are sure they want to delete the location.
The object behind that confirmation dialog could be a read-only root, or an editable root - depends on how you want to approach the issue.
If you use a read-only root to display the confirmation info, then you'll likely use a command object to actually do the delete. Remember that command objects can execute code on the client, then on the server, then on the client. So it can easily call Employee.Exists() before it tries to do the delete. Or, your LocationDeleter could expose a static/Shared method like CanDelete() that does any "pre-flight" checks it can do, like calling Employee.Exists(). Of course you UI itself could also call Employee.Exists() before even trying to execute the command - either way works.
If you use an editable root to display the confirmation info, then you have access to the business rules infrastructure, and you could call Employee.Exists() from within a rule method. This method would probably be invoked as you create the editable root, and so the user would immediately see the ErrorProvider icon (in Windows Forms) when the confirm dialog appears - and the OK button could be disabled.
On the whole though, I'd probably do the following (with LocationDeleter being a command object):
Just remember that even with this model, LocationDeleter.Delete() can still fail, because some other user could have added an Employee record between step 2 and the time Delete() is actually executing!
|
Say the delete does fail because of this. How should we bubble this back up to the UI? Should the BO intercept it and build a collection (IE the BrokenRules collection) and expose that to the UI? Or should the error go straight back up to the UI, and the UI will catch it and respond appropriately?
Along the same lines for the "pre-flight" checks, would it make sense to write them to a collection (in particular the BrokenRules collection)? The reason I ask, is because the CanDelete() check just returns true or false basically, and the reason it can't be deleted may be able to be fixed by the user if they knew what it was.
Thanks
stan
Copyright (c) Marimer LLC