I'm using EF4.3.1 in a .Net4.0 web forms (not MVC!) application.
I tend to use the repository pattern with an IUnitOfWork interface. But I'm wondering if I'm following best practices, especially since most examples I've followed are based on MVC apps.
I will say it's only a small web app, so that may affect the solution choices.
The solution currently has 3 projects, Model, Logic and Site. Model contains the codefirst entities and the IUnitOfWork interface. Logic contains the repositories and service layer. Site obviously contains the website, codebehind, etc.
I don't use any third-party inject utility (ninject, etc). I manually inject repositories with an IUnitOfWork i.e.
public BookingRepository(IUnitOfWork unitOfWork)
I'm less clear what to do with the service layers, should the IUnitOfWork also exisit in the Site project, or only exist in the Logic and Model layers.
Currently I inject a repository and a unit of work into a service i.e.
public BookingService(IUnitOfWork unitOfWork, IBookingRepository repository, IAppSettings appSettings)
But this means the commiting (save to db) is done at the Site level, but I wonder if it should be done in the service layer. It also means, that since my IUnitOfWork is declared in my model layer, I need a reference to Model in my site also.
What can I do better? Am I doing anything right? lol
Dmitry is right. Here is a sample implementation of a Unit of work. The benefit here is that the unit of work pattern coordinates the work of the multiple repositories by enforcing a single database context class shared by all of them.
This is a good resource for beginning to understand how these patterns can be used together. It is valid for both MVC and web Forms development. Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC Application
public class UnitOfWork : IDisposable
{
private DbContext _context;
private PersonRepository _personRepository;
private CompanyRepository _companyRepository;
public UnitOfWork(DbContext context)
{
this._context = context;
}
public void Commit()
{
_context.SaveChanges();
}
// We lazy-load our repositories...
public PersonRepository PersonRepository
{
get
{
if (this._personRepository == null)
{
this._personRepository = new PersonRepository(context);
}
return _personRepository;
}
}
public CompanyRepository
{
get
{
if (this._companyRepository == null)
{
this._companyRepository = new CompanyRepository(context);
}
return _companyRepository;
}
}
//IDisposable implementation removed for brevity...
}
Related
I need guidance on designing data layer for my Web API services. The Web API controllers call the service layer which calls the data layer.
I am planning to use Entity Framework along with Dapper. It might not be a good solution to use both of them together, but I need both. I need EF as it is easier to use and developers in my team are familiar. I need Dapper for performance. So, it will be a mix depending on where the dapper can make significant impact and where we can compromise on being a little late.
When using EF, I wanted to use unit of work with repository for each entity. My repository will be like
public class StudentRepository : IStudentRepository, IDisposable
{
private SchoolContext context;
public StudentRepository(SchoolContext context)
{
this.context = context;
}
public IEnumerable<Student> GetStudents()
{
return context.Students.ToList();
}
}
I took that sample code from http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
So, now I wanted to introduce Dapper.
Approach 1: Initially I thought of having multiple repositories for Dapper and for Entity Framework and I can register the one which I need in my dependency injection container. But in this case, all the methods from IStudentRepository interface needs to be implemented in both the EF and Dapper concrete repository classes (if I could do this in Dapper completely, then I don't need EF at all).
Approach 2 : Then I thought about a more ugly approach and it is like exposing a property of IDbConnection along with the DbContext property (in this case SchoolContext) in the above StudentRepository class.
So the example would be like
public class StudentRepository : IStudentRepository, IDisposable
{
private SchoolContext context;
private IDbConnection Db;
public StudentRepository(SchoolContext context)
{
this.context = context;
this.db = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
}
public IEnumerable<Student> GetStudents()
{
return context.Students.ToList();
}
public IEnumerable<Student> GetStudentsBasedOnSomeComplexCondition()
{
//I can use the db property here and work with dapper in this case.
}
(The inclusion of the IDbConnection property can be done through an abstract class so as not to repeat the instantiation code of this property and to easily change the connection string in case if needed. I am adding it in the same class for simplicity).
Approach 3 : Now, I thought of separating it further which I again think is an ugly way. Along with StudentRepository which has only EF stuff (like the first example), I will have another concrete class called StudentDapperRepository which inherits from StudentRepository.
All the methods in StudentRepository will be changed to virtual. So, I will be using StudentDapperRepository for my actual data layer and this will have the Dapper implementations where needed and where not needed, it will use the base class StudentRepository methods (which is in EF).
I think all my solutions are ugly and adding more complexity and confusion. So, can I have some light into how I can do this.
I know similar questions have been discussed several times, but my problem is slightly different, I guess. I'm experimenting with application architecture based on Domain Driven Design, using repository pattern for data access and Entity Framework infrastructure.
What I'm trying to accomplish is to have unit testable system which would have awareness of unit of works as well.
I like a design where there are core services in the system which take care of all the business logic in the application, i.e. you have some sort of CustomerService.AddOrder(int customerId, Order order) instead of ICustomerRepository.Find(int id).Orders.Add(Order order). You have a easier and intuitive interface to work with using this approach.
(Of course the CustomerService is dependent on ICustomerRepository and probably IOrderRepository as well, but it'll take care of the logic itself).
But! here comes the unit of work problem with this approach:
I'd like to have controllable unit of works inside the core services, i.e. I need to be able to start a new unit of work, do the job and DISPOSE it.
One way of doing this that I came up with is:
public interface IUnitOfWork
{
ICustomerRepository CustomerRepository { get; set; }
IOrderRepository OrderRepository { get; set; }
}
public interface IUnitOfWorkFactory
{
void New(Action<IUnitOfWork> work); // this will let you create and then dispose a new instance of IUnitOfWork implementation
}
public class CustomerService
{
private IUnitOfWorkFactory _uow { get; private set; }
public CustomerService(IUnitOfWorkFactory uowFactory)
{
_uow = uowFactory;
}
public void AddNewOrder(int id, string newName)
{
_uow.New(work =>
{
var customer = work.CustomerRepository.Find(id);
// Do some other required stuff
work.Commit();
});
}
}
After that you just have to create implementations for IUnitOfWorkFactory, IUnitOfWork and repositories; in the client code you just have to depend on CustomerService and that will be easily taken care of by IOC containers.
I like this approach, because it's kinda compact, well structured, logically organised and intuitive, but THE PROBLEM is that I don't know how to correctly UNIT test the services (e.g. behavioral testing). Integration tests are easy, but they are not my concern at this point.
Any ideas will be appreciated.
Many thanks!
What you just described are a form of domain services. I tend not to expose my domain code to the UoW, but admittedly, that's a personal preference. Having domain services control UoW scope gives them a responsibility they shouldn't have (it's an application service at that point). Instead, I'd have the domain service depend on the repositories (and optionally other services) it needs to collaborate with (makes it explicit enough but not confusing). You seem to be introducing interfaces for the purpose of making it testable/pluggable, but you're not gaining much from them at this point. Might a better strategy not be to take a dependency on an inmemory dbcontext (EF)? I believe there's a nuget package for that. That way, you could inject the inmemory dbcontext in the repository (I'm assuming you'd want to keep these) implementations. The SUT factory (the thing that creates the system under test, i.e. something that creates a domain service in this case) could then wire everything together, allowing you to control and assert using the inmemory dbcontext. Alternatively you could create your own inmemory repositories, or use mocking (but that's gonna be brittle and a world of pain). As you write your first few tests, keep watching out for verbosity, and refactor it relentlessly. Not doing so is going to make those tests either cumbersome to write or a burden to maintain in the long haul.
Maybe you could create a UnitOfWorkScope class that manages your active UnitOfWorks:
private CustomerRepository customerRepository;
'...
using (UnitOfWorkScope scope = new UnitOfWorkScope())
{
customer = customerRepository.GetByID(id);
customer.BuySomething(price)
'...
scope.complete()
}
End Using
I use the repository pattern and UnitOfWork. This is kept in a separate project together with my domain model. I realize it might be tempting for users to go to the DbContext directly and add i.e. a child of a aggregate root.
Should I mark everything internal except for repositories and UnitOfWork? The reason for asking is that I've not seen this done in any of the documentation, examples or even the subject addressed in what I've read so far.
Do not expose the DbContext to your domain layer and UI layer. Your repository pattern implementation is a leaky abstraction.
Domain Layer
public interface IUnitOfWork : IDisposable
{
int SaveChanges();
}
public interface IRepository<TEntity>
{
}
Data Access layer
internal class UnitOfWork : DbContext, UnitOfWork
{
}
internal class Repository<TEntity> : IRepository<TEntity>
{
}
I'm very familiar with UoW, Repository Pattern, etc. but in seeing various implementations of the pattern for Entity Framework, I'm curious why anyone would have a Save or Add method on their repository. If you use the repository to get you a new instance of an object that I would imagine someone would already
public Customer GetNewCustomer()
{
Customer customer = new Customer();
... any initialization code here ...
_context.Customers.AddObject(customer);
return customer;
}
I know in some designs, you can simply use
Customer customer = new Customer();
and its not attached anywhere to the context. However I'm a fan of private constructors so there is a single point of instantiation for a Customer object. With that in mind wouldn't it makes sense to never have an add/save method on the repository when using a UoW pattern and only have this functionality on the IUnitOfWork interface?
When I follow the Spring idiom in Java, units of work (and transactions) are associated with services. They use model and persistence objects to fulfill a request. Transactions are demarked using aspects.
I don't know whether .NET follows a similar idea, but it'd be worth exploring. Have interface-based POCO services and let them own transactions.
I don't think that your solution is correct. That will add empty customer to current unit of work. That means that later code will have a hard time if it decide not to save customer by the current unit of work.
It is quite common that repository have method to save entity. You are combining two patterns used in Domain driven design
Repository
Object factory
Repository's responsibility is to retrieve or store entities. Object factory's responsibility is to handle entity construction.
Btw. private constructor of your entity will not be accessible in your repository if repository is not the entity (which would be quite bad).
...wouldn't it makes sense to never have an add/save method on the
repository when using a UoW pattern and only have this functionality
on the IUnitOfWork interface?
Yes I think it makes sense to only have the Save method on the IUnitOfWork interface. However, I no longer use the repository pattern with EF. Instead, I now use these variations of the command & query patterns.
If you think about it, the EF DbContext is really doing 3 things: 1.) it functions as your repository for reading entity state, 2.) as your repository for mutating entity state, and 3.) as a UnitOfWork for tracking multiple changes and combining them into a single transaction to persist state mutations.
So, why not separate these 3 responsibilities into 3 different interfaces?
public interface IUnitOfWork
{
int SaveChanges();
}
public interface ICommandEntities : IQueryEntities
{
void Create(Entity entity);
void Update(Entity entity);
void Purge(Entity entity);
}
public interface IQueryEntities
{
IQueryable<AggregateRoot1> AggregateRoot1s { get; }
IQueryable<AggregateRoot2> AggregateRoot2s { get; }
IQUeryable<AggregateRootN> AggregateRootNs { get; }
IQueryable<TEntity> EagerLoad<TEntity>(IQueryable<TEntity> query,
Expression<Func<TEntity, object>> expression)
where TEntity : Entity;
}
You can then implement these 3 interfaces on your DbContext class. This keeps the interfaces nice and segregated, and lets you dependency inject only those methods of the DbContext which you need.
For example, your domain should be persistence ignorant, right? In that case, don't give any of your domain classes dependencies on the IUnitOfWork interface. Instead, handle the IUnitOfWork in your IoC composition root (or in an MVC action filter). Then, your query and command handlers deal only with the ICommandEntities and IQueryEntities interfaces.
I see several questions relating somewhat to this, but I still can't find the answer I'm looking for, so I'm posting my question. If another question holds the answer (and I'm just not seeing it), please point me to it.
I'm trying to figure out where my UnitOfWork belongs -- and specifically, gets created -- when using EF4 and Unity with the Repository pattern.
Basically, I have a service that is used to implement my business logic. This service constructor takes in the repository, so the service gets injected with my repository. The service then uses the injected repository to carry out actions against the data store -- but I need to wrap these in a unit of work.
My unit of work, however, needs to be injected with the EF4 context (or, in my case, and interface of the context -- IObjectContext). And I'm not sure where the UoW should be created and injected w/ the context.
Here are the possible options I can think of, none of which seem ideal:
Include the UoW in the service constructor, thus having the service injected w/ the unit of work, which in turn is injected w/ my EF4 context. But this seems wrong because I don't want my UoW created on every instance of the repository.
Do an on-demand creation using container.Resolve to get an instance of the UoW, injecting my EF4 context. This seems excessive having to constantly hit the IoC container, rather than already having access to the UoW.
Inject the context directly into the service, allowing me to create a UoW(context). This seems bad since I've now exposed the context to the service, and this should be isolated to the repository.
So my question is, is one of these methods acceptable, or is there another method I'm not thinking of?
Thanks in advance.
There are probably several ways how to use this so I will describe one which I found useful.
Imho the place to define UoW is in Application logic - the logic which calls your business layer (business services). The reason for this is that UoW should represent logical business trasaction - application logic (or service facade in case of remote calls) defines what is logical transaction. So for example in MVC you can go with architecture where each controller action represents single UoW:
public class MyController : Controller
{
public MyController(IFirstService firstService, ISecondService secondService,
IUnitOfWork unitOfWork)
{ ... }
[HttpPost]
public ActionResult SomeAction(Model data)
{
_firstService.SomeProcessing(data);
_secondService.SomeProcessing(data);
_unitOfWork.SaveChanges();
return RedirectToAction(...);
}
}
In this example my controller is depenent on two business services and action calls them both - UoW then save changes performed by both services. That is the reason why I think the UoW should be available in controller because if your application layer don't have access to UoW you can't compose (reuse) your logic from several service calls (because each probably calls its own SaveChanges).
Other approach is with service facade. Facade will be public interface of your business layer and it will hide service composition:
_firstService.SomeProcessing(data);
_secondService.SomeProcessing(data);
_unitOfWork.SaveChanges();
In such case UoW will not be passed to controller but to service facade and service facade will be injected to controller. You will definitely use this approach if your business logic will be exposed over web service (or other remote technology).
The last problem which you have to deal with is passing UoW to services. Services as well as UoW are injected into controller (presenter, service facade or whatever) but in the same time UoW (or ObjectContext) must be injected into services so that internally used repositories can work with it. For this you need correct IoC lifetime manager so that it returns same instance for all injections within same "request". In case of web application you need PerHttpRequest lifetime manager (which you must implement by yourselves because Unity does not provide it).
One way is to manage this is to use the method described in http://mfelicio.wordpress.com/2010/02/07/managing-the-entity-framework-objectcontext-instance-lifetime-in-wcf-and-sharing-it-among-repositories/ That article implements the ContextManager for Wcf services. For ASP.NET app we could use something like this.
public class AspNetDBContextManager<TContext> : IDBContextManager
where TContext : IDBContext, new()
{
#region IDBContextManager Members
public IDBContext GetDBContext()
{
return this.GetOrCreateDbContext();
}
private IDBContext GetOrCreateDbContext()
{
if (HttpContext.Current == null)
{
throw new InvalidOperationException("Can be used only within ASP.NET applications");
}
string dbContextKey = string.Format("__AspNetDBCM__{0}__", HttpContext.Current.GetHashCode());
object dbContext = HttpContext.Current.Items[dbContextKey];
if (dbContext == null)
{
dbContext = new TContext();
if (dbContext != null)
{
HttpContext.Current.Items[dbContextKey] = dbContext;
}
}
return dbContext as IDBContext;
}
#endregion
}
public interface IDBContext
{
object Context { get; }
}
public interface IDBContextManager
{
IDBContext GetDBContext();
}