Repository, Specification, Unit of Work, Persistence Ignorance POCO with Microsoft ADO.NET Entity Framework 4.0 Beta 2 - Code Update

kick it on DotNetKicks.com
StumbleUpon.com
Save to delicious Saved by 0 users



Code Re-factoring for the sample project attached with the post Repository, Specification, Unit of Work, Persistence Ignorance POCO with Microsoft ADO.NET Entity Framework 4.0 Beta 2. Brief explanation of the changes are included.


Hi,  while I was preparing my post on Tame Your Software Dependencies with Dependency Injection & Common Service Locator Library, I have further refactored the sample project codes for my post on Repository, Specification, Unit of Work, Persistence Ignorance POCO with Microsoft ADO.NET Entity Framework 4.0 Beta 2.

The changes that I have made center around the MyCompany.Data.Entity project under the FrameworkSource logical folder as indicated  below. Figure 1.0 and Figure 1.1 show the solution view of  MyCompany.Data.Entity before and after code refactoring. After the code refactoring, you will see an additional project solution; MyCompany.Data holds all the interfaces/abstraction for implementing the Repository, Unit of Work and Specification pattern. The MyCompany.Data is totally decoupled from any data infrastructure concern (data access technology agnostic).



 Figure 1.0 MyCompany.Data.Entity Solution View before Code Update.



 Figure 1.1 MyCompany.Data and MyCompany.Data.Entity Solution View after Code Update.


The changes are for better level of abstraction in which I have included the IUnitOfWork, IUnitOfWorkFactory, IUnitOfWorkScope interface in the MyCompany.Data framework project. The ObjectContextLifetimeManager has been renamed to ObjectSourceLifetimeManager and is moved from the MyCompany.Data.Entity to MyCompany.Data project. The rationale is the ObjectContext form part of the ObjectContextLifetimeManager name implies that it is highly tied to the ObjectContext type used in the Entity Framework. Renaming it to ObjectSourceLifetimeManager will give a better impression that it is an abstract class for anyone wants to implement a lifetime manager for managing the data source of a particular data access technology. For e.g. the ISession used in the NHibernate for the persistence context.

The UnitOfWork has been made an abstract class in the MyCompany.Data project from the concrete class in the MyCompany.Data.Entity. It includes a few abstract methods and a template method; CommitCore that the concrete class must implement. You can notice that the EntityUnitOfWork implement UnitOfWork abstract class in the MyCompany.Data.Entity. The EntityUnitOfWork provides unit of work implementation for any application that make use of the Entity Framework as data access infrastructure. However, anyone intends to implement a totally different unit of work implementation can choose to implement the IUnitOfWork interface which exposes only the Commit interface method.

The Repository class remain as an abstract class in the MyCompany.Data project. However, its protected properties; ObjectContext and ObjectSet have been moved into the higher level assembly/project; MyCompany.Data.Entity to break the coupling to the Microsoft Entity Framework in the MyCompany.Data project/assembly. So, I can say that the MyCompany.Data project/assembly is data access technology agnostic. The Repository class that provides an in-memory like collection interface for accessing domain objects against the Entity Data Source (ObjectContext) is now named as EntityRepository in the MyCompany.Data.Entity assembly/project.

The rest of the changes you can easily spot in the MyCompany.Data.Entity project. The changes are pretty on the names of the types such as the AspNetObjectSourceLifetimeManager, ScopeObjectSourceLifetimeManager and StaticObjectSourceLifetimeManager. The changes in their name are not necessary but I think changing it to ObjectSource instead of using the ObjectContext will more reflect the concrete data source lifetime manager inherits from the abstract class ObjectSourceLifetimeManager even though the three concrete class are actually managing the ObjectContext in the Entity Framework. By looking at ScopeObjectSourceLifetimeManager, you will know that it inherits from the abstract class ObjectSourceLifetimeManager.

The last, you will see there is an additional EntityUnitOfWorkFactory in the MyCompany.Data.Entity project which implements the IUnitOfWorkFactory interface. The simple static factory, UnitOfWorkFactory inside the MyCompany.Data.Entity project previously has been removed. The rationale is not to fix a particular UnitOfWorkFactory implementation required by the UnitOfWorkScope in MyCompany.Data project. Anyone can implement the IUnitOfWorkFactory interface to provide his own implementation of Unit of Work factory used by the UnitOfWorkScope. Anyway, the default implementation of UnitOfWorkScope is provided as it is. It is the way I think it should work and it may not meet the all the needs and expectations of some applications. Anyone can implement his own version of the UnitOfWorkScope in his own project or assembly to replace this default implementation. As you can see, the UnitOfWorkScope is being used in the higher level component; MyCompany.Data.Entity and MyCompany.Business.AppName business layer project. You can replace it with your own implementation in your higher level framework or bussiness project.

Finally, the idea of creating a separate MyCompany.Data project is to have a better level of abstraction and separation of concern. You can see better level of abstraction with several interfaces and abstract classes such as IUnitOfWork, IUnitOfWorkFactory, IUnitOfWorkScope, UnitOfWork and etc because the concrete implementations can be varied by programming against the abstraction or contract. By programming against the abstraction or contract, changes in the implementation of the abstraction won't affect the higher level component that depends on it.

Decoupling the higher level component from its lower level dependencies by interacting with the dependencies via interfaces rather than their concrete classes give another advantage. It facilitates unit testing as we can simply substitute the interface with fakes or mocks for any of the dependencies. Another term is called dependency inversion because we can supply any implementation of the dependencies via the interfaces to the higher level components normally through the parameterized constructors of the higher level type.

I have included the new updated project source codes in the code download section below. This source code will be used as reference project for my next post on Tame Your Software Dependencies with Dependency Injection & Common Service Locator Library.


Code Download : Repository, Specification, Unit of Work, Persistence Ignorance POCO with Microsoft. ADO.NET Entity Framework 4.0 Beta 2 - Code Update . (This application sample requires Visual Studio 2010 Beta 2/RC that can open C# project. Right click on the above link and choose Save Target As. Rename the extension from .pdf to .zip once you have downloaded the file. Let me know if you have any problem running the code.)

See you in my next post.
Bye and stay tune...



6 comments:

  Anonymous

February 21, 2010 at 12:13 AM

Hi, good article. Keep up your good work.

  Anonymous

March 12, 2010 at 6:15 AM

Why not provide a .zip download link?

I like your articles but think you talk too much and show too little code ;)

  Anonymous

March 12, 2010 at 3:22 PM

test

  kitchaiyong

March 12, 2010 at 4:12 PM

Hi,

The .pdf file is hosted on kitchaiyong.wordpress.com before I moved to blogspot.com. It was named .pdf because wordpress doesn't allow the upload of .zip (if I was right).

This post is a follow up for my previous post on Repository, Specification, Unit of Work, Persistence Ignorance POCO with Microsoft ADO.NET Entity Framework 4.0 Beta 2. If you want to know more at http://www.kitchaiyong.net/2009/10/repository-specification-unit-of-work.html.

If you compare the source code attached with this post and the source code attached with the above mentioned post, you will see the changes I have made.

Regards

kitchaiyong.net

  Will 保哥

June 20, 2010 at 11:34 PM

Would you like to provide "Paging" feature in the Repository?

  KITCHAIYONG.NET

June 21, 2010 at 2:30 PM

Hi 保哥,

I do have some intention on writing some futher stuff on the repository. But it is not now. Let me finish my post on service factory first.

I am sure you can get some tips and hits on how to do paging from all over the net. You can play around and modify the codes as you wish.

Regards

kitchaiyong.net

Post a Comment