-
-
Save liammclennan/798133 to your computer and use it in GitHub Desktop.
| // tell don't ask means I might do something like this | |
| var folder = new Folder("foo"); | |
| folder.Delete(); | |
| // but for that to work the folder class needs to depend on a file IO service (to do the deleting). | |
| // the alternative is procedural | |
| public class FolderService | |
| { | |
| public FolderService(IFileSystem fileSystem) {...} | |
| public void Bar() | |
| { | |
| var folder = new Folder("foo"); | |
| fileSystem.Delete(folder.Path); // here is the tell-dont-ask violation | |
| } | |
| } | |
| // what is the right way to do this? |
Interesting idea. In this case each domain class would have a dependency on an event aggregator.
It violates my requirement to not take dependencies, but it also reduces the set of dependencies to one.
One of the reasons I don't want domain classes to have dependencies is to facilitate testing. If they need access to an event aggregator that means that every time I create a Folder (or any other domain class) object I have to give it a reference to the aggregator, or the aggregator has to be static. A static aggregator might work well because when testing there would be no registered listeners so nothing happens.
There are parallels here with normal DB related CRUD. "Folder" = domain object, "file system" = DB.
What about using the Repository pattery?
"folder.Delete();" is more like active record.
If you look at posts e.g. from Udi Dahan about Domain Events, the Domain objects do have a possibility to raise events (messages, whatever). It also lends itself well to a certain kind of blackbox testing. If you use some kind of event aggregator (I prefer to think of it as Bus) in your test you can assert whether certain messages/events have been generated by the parts of the domain under test.
FWIW, I've build a number of large systems using Event Sourcing - I'm giving a talk next week as it happens - and I would never go back to using anything else. Testing is a breeze.
Thanks everyone. Udi talks about Domain Events at http://www.udidahan.com/2009/06/14/domain-events-salvation/. Domain Events appear to be an elegant partial solution to the original problem. I say partial because an external dependency is still required.
depending on your requirement you could use a message in wherever it is decided to notify the outside world that a deletion is required
bus.Publish(new RequestForDeletionOfFolder("foo"));