Otis wrote:
All saves of an entity call SaveEntity(), if you call SaveEntityCollection() or commit a UoW, it doesn't matter.
Ooooo. Very nice. I didn't think it did that. Of course, I didn't take the time to figure out it did that, but you know what they say about programmers.
Also, if you pass in a derived class of the DataAccessAdapter to the commit method, your derived SaveEntity() method will be called whenever a save is done, as you override a virtual method
That's polymorphism
. To break a recursive save in the SaveEntity() for example, override it, do tests and if tests fail throw an exception for example
Yes, OO is a wonderful thing.
MarcoP wrote:
I would love to have all the business validation flow through the controller classes, but say for example, the user creates a Customer Object, adds 3 addresses to the customer and saves the customer object recursive. How do I guard against any business rules, such as what is required or not? Should I set the EntityValidatorToUse property in the constructor of the sub-classes?
Aye, that's a problem.
I still don't think you should put the logic in the Entity Validators, but that may just be a purist/nitpicky thing. I recognize that the mechanism they provide is perfect for what you need, but they're for validating, not changing data.
Another idea would be, as IDataAccessAdapter raises an event on Entity Save, perhaps you could hook that event, test for entity type, and inject your logic there. Not very nice, really, but workable.
Another possibility would be to use the Derived Adapter Entity Templates available in the third party section and modify them to include your logic in the .Save() method call.
Taking it a bit further, if you wanted to be consistent with the architecture of LLBLGen, and if you wanted to make that kind of functionality reusable across entities you could use a little Strategy action, and:
- Create an interface called ISaveLogic
- Create classes that contain the logic you want performed when your entities are saved, that implement ISaveLogic.
- Create a property on the derived templates called SaveLogic
- Delegate the logic you want performed on Save to that object
- Bingo, you've got a nice reusable interface to program against when you want things done on save.
Of course, this is exactly what IEntityValidator does, but now your logic can be implemented apart from validation.
What are your thoughts on having a BusinessEntityFactory() class that is responsible for creating the appropriate derived entities and setting their individual EntityValidator objects? This way, when the objects make it down to the BL, the validators are already present.
I use an Entity Factory myself and it works very well. In fact all of my core object instantiation happens through it. Anyway, I think you should do what you're saying, but implement it as I described above, with your own ISaveLogic interface.
Jeff...