1: public class PhysicianPipe : IPhysicianPipe
2: {
3: IRepositoryGarden repositoryGarden;
4: public PhysicianPipe(IRepositoryGarden RepositoryGarden)
5: {
6: repositoryGarden = RepositoryGarden;
7: }
8:
9: public void AddPhysician(Domain.Entities.Physician physician)
10: {
11: repositoryGarden.PhysicianRepository.Add(physician);
12: repositoryGarden.SaveRepositoryChanges();
13: }
14: }
Basically I handed over the UnitOfWork responsibility to the repository garden where it gets injected in the constructor, that way i can use an IoC container (StructureMap, Unity, Ninject, etc..) and can configure it to inject a real UnitOfWork or a Fake one for testing purposes. We'll look at how the repository garden (this acts as a repository factory) class looks like later. I am also archtecting the application in a way that everything is implemented thru interfaces. I dont want the client code to be aware of how things are implemented but rather just how to use them. A real world example is a car for example, the manufacturer makes the car and to be able to drive it, we just need to know how to interact with its interfaces (streering wheel, brakes,etc..) we dont need to know how they work internally. So, all my client code need to be concerned about is how to use the interfaces i hand over to it. Now, looking at the PhysicianPipe class we can see that we can easily add some method that involve work across multiple repositories, then when we are done we can save the changes - we can have something like this:
1: public void DoWork(Domain.Entities.Physician physician)
2: {
3: repositoryGarden.PhysicianRepository.Add(physician);
4: repositoryGarden.ClinicRepository.DoSomework();
5: repositoryGarden.SaveRepositoryChanges();
6: }
Let's take a look at how I signed the repository garden class:
1: public class RepositoryGarden : IRepositoryGarden,IDisposable
2: {
3: IUnitOfWork _CurrentUoW;
4: public RepositoryGarden(IUnitOfWork unitOfWork)
5: {
6: if (unitOfWork == (IUnitOfWork)null)
7: throw new ArgumentNullException("unitOfWork",
8: "Can Not Be Null");
9: _CurrentUoW = unitOfWork;
10: }
11: IPhysicianRepository physicianRepository =
12: default(IPhysicianRepository);
13: IClinicRepository clinicRepository = default(IClinicRepository);
14:
15: public IPhysicianRepository PhysicianRepository
16: {
17: get
18: {
19: if (physicianRepository == null)
20: {
21: physicianRepository = new PhysicianRepository(_CurrentUoW);
22: }
23: return physicianRepository;
24: }
25: }
26:
27: public IClinicRepository ClinicRepository
28: {
29: get
30: {
31: if (clinicRepository == null)
32: {
33: clinicRepository = new ClinicRepository(_CurrentUoW);
34: }
35: return clinicRepository;
36: }
37: }
38:
39: //... More repositories
40:
41: public void SaveRepositoryChanges()
42: {
43: _CurrentUoW.Commit();
44: }
45:
46: public void Dispose()
47: {
48: if (_CurrentUoW != null)
49: {
50: _CurrentUoW.Dispose();
51: }
52: GC.SuppressFinalize(this);
53: }
54: }
And the signiture of IRepositoryGarden :
1: public interface IRepositoryGarden
2: {
3: IPhysicianRepository PhysicianRepository { get; }
4: IClinicRepository ClinicRepository { get; }
5: // More Repository interfaces.....
6: void SaveRepositoryChanges();
7: }
In this post I did not go over the details of each repository or the UnitOfWork, my goal was to show how easy we can create a central Repository Factory class that takes care of picking out desired repositories as needed then saving the changes once we're done. In my next post i will show how to use the Specification Pattern as well as using DataAnnotations to validate data in subsequent posts.