-
-
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"));