For the past week I have been attempting to write a proof-of-concept project using dependency injection, a service layer, unit of work pattern + repository.
I am looking to design something that can easily be consumed by any type of application - be it a Windows desktop application, a CLI application, an ASP.NET MVC application, even an iOS application running Mono. Please, bear in mind that this is just for a proof-of-concept.
Until now, I have written
- A Unit of Work + Unit of Work Factory for NHibernate and Entity Framework (2 OR/M frameworks for .NET)
- (Generic) repository. There is one repository per OR/M implementation, taking it's respective Unit of Work Factory as a constructor parameter. It needs this to grab the current unit of work (since it's implementation contains stuff necessary for each OR/M framework to function)
This has accomplished:
- I can swap out implementations of the repository and Unit of Work factory with NHibernate and Entity Framework, and it will just work. This is good, except I haven't implemented a real application yet, only unit-tests.
These are the problems/challenges I am facing:
Each application type (Desktop, CLI, ASP.NET MVC, iOS, Android, whatever) do not define a unit of work the same way. A desktop application (AFAIK) should have a Unit of Work per screen - a Web application should have a Unit of Work per request, etc. I don't know how I would share a single unit of work with all the repositories/services (see below) that needs it.- Michael is right.
- I want all my logic to reside in a service layer. The service layer decides when a Unit of Work should commit. The idea is that whoever calls the service, knows what to pass to it, and knows what to expect as a result. If something goes wrong, the service logs it. If I had to do this on a per-application basis, DRY would be violated (right?).
It seems that if I had to implement this totally separated design, the amount of code I got to reuse would not be as much as the amount of code I'd have to write in order to implement it in each application type, which would, in the end, most likely leak my IoC container into the application.
Am I totally crazy for even attempting this?
EDIT: The actual problem I am facing, is providing my service layer and repositories with the same instance of a Unit of Work, no matter what application type is being used.