I asked a question a while back about why the default equality comparer didn't seem to work when I was union two collections of entities.
EF Code First - Linq to Entities Union EqualityComparer
The answer was due to the fact that I was using two difference instances of my DbContext hence different references.
So now I am trying to share my DbContent across the request. I see a few "complicated" examples but I thought I'd try for a more simple solution.
So I created a IDbContext interface which simply outlines my Entities
public interface IDbContext {
int SaveChanges();
DbSet<News> News { get; set; }
DbSet<Category> Categories { get; set; }
}
My DbContext is then implement like this:
public class SiteContext : DbContext, IDbContext {
public DbSet<News> News { get; set; }
public DbSet<Category> Categories { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
...
}
}
Then in my two repositories (NewsRepository and CategoryRespository) I have the IDbContext as a constructor parameter
IDbContext _db;
public NewsRepository(IDbContext db) {
_db = db;
}
So now I assume that if I bind IDbContext to SiteContext in the request scope my repositories will share the same context?
kernel.Bind<IDbContext>().To<SiteContext>().InRequestScope();
However, when I try my union again from the previous question I still receive duplicate entities! What I am doing wrong? How can I tell if I am definitely using the same context in one request?
Because when each repository is constructed Ninject will is providing you with a new instance of SiteContext per repository. Thats why its not working. Its a good idea to use a unitofwork implementation which means all repositories use the same context.
The UnitOfWork would take in a IDbContext on construction.
Some thing like this would work
private IDbContext _context;
public UnitOfWork(IDbContext context)
{
_context = context
}
private _INewsRepository;
public INewsRepoitory
{
get{
if(_INewsRepository == null)
{
_INewsRepository = new NewsREpository(_context);
return _INewsRepository;
}
else
{
return _INewsRepository;
}
}
To improve the solution of feanz I would still do property injection of the INewsRepository with Ninject:
[Inject]
public INewsRepository NewsRepo {get;set;}
Every time an IUnitOfWork is created there is also an INewsRepository created. This must still be added to your ninject bindings.
Related
I followed an online tutorial of the UnitOfWork pattern with Entity Framework as it has been awhile since I have used it. I am confused as to why in the tutorial the DataContext is a parameter of the public UnitOfWork constructor. This means if I use the UnitOfWork in another layer of the application, the other layer must be aware of the DataContext. This does not seem like a good separation of concerns. Am I missing something?
UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly PurchasingDataContext _context;
public UnitOfWork(PurchasingDataContext context)
{
_context = context;
Items = new ItemRepository(_context);
Manufacturers = new LabelerRepository(_context);
Quotes = new QuoteRepository(_context);
Vendors = new VendorRepository(_context);
Contacts = new ContactRepository(_context);
}
public IItemRepository Items { get; private set; }
public ILabelerRepository Manufacturers { get; private set; }
public IQuoteRepository Quotes { get; private set; }
public IVendorRepository Vendors { get; private set; }
public IContactRepository Contacts { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
Interface:
public interface IUnitOfWork : IDisposable
{
IContactRepository Contacts { get; }
IItemRepository Items { get; }
ILabelerRepository Manufacturers { get; }
IQuoteRepository Quotes { get; }
IVendorRepository Vendors { get; }
int Complete();
}
I am confused as to why in the tutorial the DataContext is a parameter of the public UnitOfWork constructor.
This is to make injecting the dependency into the UoW possible. By doing this, you can honor SRP easily.
With it, you can manage the scope of DataContext separately outside the UoW. This gives you much flexibility while using same UoW in different scenario (windows application vs web application for example). With this, you can expand database transactions the way you want.
This means if I use the UnitOfWork in another layer of the application, the other layer must be aware of the DataContext.
Yes; but not entirely true. Yes, the instance of DataContext should be managed (create, inject and dispose) by calling layer. That's it. That layer does not need to interact with with this instance in any way.
This does not seem like a good separation of concerns.
In continuation to earlier point, calling layer does not need to know how that instance work. All that part is abstracted in your UoW class. This is clean separation of concerns.
Am I missing something?
Hope you know that now.
I would start by asking why you are creating and exposing these repositories in your UnitOfWork. Having a single class that is responsible for a unit of work and the ownership of all of your repositories violates the Single Responsibility Principle. Your IUnitOfWork exposing every single repository that may or may not be needed by a caller violates the Interface Segregation Principle.
Instead of this approach, you should be using a dependency injection framework to manage the lifetimes of the context, repositories, and unit of work. The framework should ensure that one instance is created per request and shared across dependencies where needed.
A typical EntityFramework UnitOfWork would look similar to:
public interface IUnitOfWork
{
void SaveChanges();
}
with an implementation like:
public class UnitOfWork : IUnitOfWork
{
private readonly PurchasingDataContext _context;
public UnitOfWork(PurchasingDataContext context)
{
_context = context;
}
public void SaveChanges()
{
return _context.SaveChanges();
}
}
I have two connections to database: MsSQL and MySQL. For mssql I do the following:
public class MssqlDbContext: DbContext
{
public DbSet<ReportPhone> ReportPhones { get; set; }
public DbSet<ReportPhoneDetail> ReportPhoneDetails { get; set; }
public DbSet<Operator> Operators { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ReportPhoneConfiguration());
modelBuilder.Configurations.Add(new CompanyPhoneConfiguration());
}
}
and make DI in ioc container:
public static void WebConfigure(Container container)
{
container.RegisterPerWebRequest<DbContext, MssqlDbContext>();
Configure(container);
}
how can i do the same for MysqlDbContext to?
for example:
public static void WebConfigure(Container container)
{
container.RegisterPerWebRequest<DbContext, MysqlDbContext>();
container.RegisterPerWebRequest<DbContext, MssqlDbContext>();
Configure(container);
}
When you register the DbContext using:
container.RegisterPerWebRequest<DbContext, MssqlDbContext>()
this implies that you want to inject it as a DbContext rather than the concrete type. In other words, using this approach, its consumers will have DbContext as a constructor argument, rather than MssqlDbContext.
When you have two different DbContext implementations, both with their seperate database schema, it doesn't make sense to inject a DbContext. That would be a Liskov Substitution Principle violation.
Depending on DbContext would be useless for the consumer, because it can't access its ReportPhones and ReportPhoneDetails. It can only do this by casting the DbContext back to MssqlDbContext, but that cumbersome and error prone: an incompatible DbContext implementation could have been injected.
So instead, you should let consumer depend on either MssqlDbContext or MysqlDbContext and use them directly. For instance:
public class HomeController : Controller
{
private readonly MssqlDbContext context;
public HomeController(MssqlDbContext context)
{
this.context = context;
}
// class members here
}
In your WebConfigure method, you should register the DbContext implementations using their concrete type:
container.RegisterPerWebRequest<MysqlDbContext>();
container.RegisterPerWebRequest<MssqlDbContext>();
TIP: Since both have a different schema, try coming up with a more functional name. Mssql and Mysql only describes the technology, not what is stored in those databases.
I'm having some problems with getting unity to provide dependencies for my MVC controllers.
I want my ApplicationUser data and my business data in the same database and I am using code-first migrations with Entity Framework. To that end my DbContext inherits from IdentityDbContext and then implements an interface which represents my business data:
public class DealFinderDb : IdentityDbContext<ApplicationUser>, IDealFinderDb
{
public DealFinderDb() : base("name=DealFinderConnectionString", false)
{
}
public IDbSet<Deal> Deals { get; set; }
public IDbSet<Category> Categories { get; set; }
public IDbSet<SavedSearch> SavedSearches { get; set; }
public static DealFinderDb Create()
{
return new DealFinderDb();
}
}
public interface IDealFinderDb : IDisposable
{
IDbSet<Deal> Deals { get; set; }
IDbSet<Category> Categories { get; set; }
IDbSet<SavedSearch> SavedSearches { get; set; }
int SaveChanges();
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity)
where TEntity : class;
}
In my controller I need to be able to get the current user which means my controller has a dependency, not only on a IDealFinderDb but also on a UserManager. I understand that the best way to test this is to mock an IUserStore and pass that into the constructor of my controller. I have written the tests that mock both the IUserStore and the controller's HttpContext and these tests work as expected. This means my controller looks like this:
public class SavedSearchesController : Controller
{
private readonly IDealFinderDb dealFinderDb;
private readonly UserManager<ApplicationUser> userManager;
public SavedSearchesController(IDealFinderDb dealFinderDb, IUserStore<ApplicationUser> userStore)
{
this.dealFinderDb = dealFinderDb;
this.userManager = new UserManager<ApplicationUser>(userStore);
}
public ActionResult Index()
{
var user = this.userManager.FindById(this.User.Identity.GetUserId());
var usersSavedSearches = this.dealFinderDb.SavedSearches.Where(s => s.User.Id == user.Id);
return this.View(usersSavedSearches);
}
// Snip unrelated action methods.
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.dealFinderDb.Dispose();
}
base.Dispose(disposing);
}
}
This seems fine but I am using Unity to provide implementations for these interfaces at run-time and this is where I'm stuck. My first attempt at my UnityConfig looks like this:
container.RegisterType<IDealFinderDb, DealFinderDb>();
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
new InjectionConstructor(typeof(DealFinderDb)));
...but the problem with that is I end up with a DbContext being instantiated twice leading to an error of "System.InvalidOperationException: 'An entity object cannot be referenced by multiple instances of IEntityChangeTracker.'" when I call Add() on any of my IDBSets in my DbContext I guess this is because unity is instantiating my DbContext twice.
So my next attempt was to ensure that only a single instance of DealFinderDb is created and that looks like this in my UnityConfig:
container.RegisterType<DealFinderDb, DealFinderDb>(new ContainerControlledLifetimeManager());
container.RegisterType<IDealFinderDb, DealFinderDb>();
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
new InjectionConstructor(typeof(DealFinderDb)));
...but when this.userManager.FindById() is called in my controller I get the error "System.InvalidOperationException: 'The operation cannot be completed because the DbContext has been disposed.'". Obviously I could avoiding calling Dispose on my Context but this is bad as I assume means I am actually using the same DBContext instance for the entire life-cycle of my application.
What should I put in my UnityConfig to ensure that both the IDealFinderDb and IUserStore dependencies are satisfied and that only a single context is instantiated each time my controller is instantiated?
Thanks
What should I put in my UnityConfig to ensure that both the
IDealFinderDb and IUserStore dependencies are satisfied and that only
a single context is instantiated each my controller is instantiated?
You should use per-graph lifetime manager which is called PerResolveLifetimeManager in Unity:
container.RegisterType<IDealFinderDb, DealFinderDb>(new PerResolveLifetimeManager());
According to best practice to software design pattern, you should always follow Singleton Pattern while creating database context and logger context and many other things as per business requirement if you feel there is a need for singleton object go for that and while using singleton pattern do take care of thread safety singleton if you are implementing threads.its so easy and for help, you can refer MSDN, it has an implementation of the singleton.
https://msdn.microsoft.com/en-us/library/ff647854.aspx
Hope this helps.
Is it good to resolve the dependencies dynamically like the way i'm doing. Everywhere, it is suggested to use Constructor injection. I really don't understand the drawbacks of doing it the way i'm doing it. Code snippets as below..
Employee.cs
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Department Department { get; set; }
}
IRepository.cs
public interface IRepository<TModel> where TModel : class
{
void Add();
IEnumerable<TModel> GetAll();
IEnumerable<TModel> GetByID();
}
Repository.cs
public class Repository<TModel> : IRepository<TModel> where TModel : class
{
public void Add()
{
throw new NotImplementedException();
}
public IEnumerable<TModel> GetAll()
{
throw new NotImplementedException();
}
public IEnumerable<TModel> GetByID()
{
throw new NotImplementedException();
}
}
EmployeeController.cs
public class HomeController : ApiController
{
IComponentContext _container;
public HomeController(IComponentContext container)
{
this._container = container;
}
public Repository<TModel> Using<TModel>() where TModel :class
{
var repository = _container.Resolve(typeof(IRepository<TModel>));
return repository as Repository<TModel>;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return Using<Employee>().GetAll();
}
}
Global.asax
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
var container = builder.Build(Autofac.Builder.ContainerBuildOptions.None);
var webApiResolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;
}
Say i've 5 repositories, Constructor injection will resolve all the 5 dependencies for a request i make. I might not use 5 repositories for each and every request. SO i thought of resolving dependencies dynamically by passing the type like i'm doing it in Using<TModel>(). Any suggestions would be appreciated..!! Thank you...!!
Refrain from using the container directly inside your application components; this leads to all kinds of troubles such as maintainability and testability issues. Directly resolving instances from within application code is a well-known anti-pattern known as Service Locator.
As a first refactoring, you can instead apply the Unit of Work pattern. A Unit of Work allows access to underlying repositories. For instance:
public interface IUnitOfWork
{
IRepository<TModel> Repository<TModel>();
}
public sealed class HomeController : ApiController
{
private readonly IUnitOfWork _unitOfWork;
public HomeController(IUnitOfWork unitOfWork)
{
this._unitOfWork = unitOfWork;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return this._unitOfWork.Repository<Employee>().GetAll();
}
}
Within the Composition Root (where it is allowed to access the container), we can now create an IUnitOfWork implementation that resolves repositories dynamically:
private sealed class AutofacUnitOfWork : IUnitOfWork
{
private readonly IComponentContext _container;
public AutofacUnitOfWork(IComponentContext container)
{
this._container = container;
}
public IRepository<TModel> Repository<TModel>()
{
return _container.Resolve<IRepository<TModel>>();
}
}
This pattern simplifies your application components considerably and prevents downsides that the Service Locator anti-pattern typically causes.
Although applying the Unit of Work pattern might be a useful step into the right direction, an even better approach is to skip the Unit of Work directly and simply inject a required repository directly into application components:
public sealed class HomeController : ApiController
{
private readonly IRepository<Employee> _employeeRepository;
public HomeController(IRepository<Employee> employeeRepository)
{
this._employeeRepository = employeeRepository;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return this._employeeRepository.GetAll();
}
}
Say i've 5 repositories, Constructor injection will resolve all the 5 dependencies for a request i make. I might not use 5 repositories for each and every request.
Note that from a performance perspective, you should typically not be concerned whether dependencies are used or not. Autofac is in most cases fast enough and it is unlikely that this will actually cause any performance problems in your production systems.
From a design perspective however you should be more worried if a class has many dependencies, while methods just use a few of them. This means that the methods in the class have little cohesion. This is an indication that the class should be split up into multiple smaller classes; it has multiple responsibilities.
How do you implement the unit of work and repository pattern in MVC 5 and EF6? Previously I've avoided any need for unit of work by using a single repository which was injected into my controller as follows:
public class ProductController : BaseController
{
private IShopRepository _repository;
public ClassController()
: this(new ShopRepository())
{
}
public ClassController(IShopRepository repository)
{
_repository = repository;
}
....
}
But now I want to refactor the code so that I have a separate repository for each entity type eg. ProductRepository, CustomerRepository etc and be able to inject multiple repositories into a controller whilst ensuring the same dbcontext is used.
Reading through the microsoft tutorial on http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application, the architects now advise the repository and unit of work pattern are no longer needed but they don't provide any example of how to implement or structure repositories in their examples?
Some people have even started renaming repositories to services?
How do you structure your repositories and implement unit of work in MVC5 using EF6 perhaps using an IOC such as Unity? Or what is another solution?
I'm working along the following lines but not sure if it is best solution and how do i add unit of work?
public class ShopContext : DbContext
{
public ShopContext() : base("name=ShopContext")
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Customer> Customers { get; set; }
...
}
public interface IProductRepository
{
IEnumerable<Product> GetAll();
...
}
public interface ICustomerRepository
{
IEnumerable<Customer> GetAll();
...
}
public class ProductRepository : IDisposable, IProductRepository
{
private ShopContext _context;
public ProductRepository()
{
_context = new ShopContext();
}
public IEnumerable<Product> GetAll()
{
return _context.Products;
}
// Other methods not displayed
protected void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
public class CustomerRepository : IDisposable, ICustomerRepository
{
private ShopContext _context;
public CustomerRepository()
{
_context = new ShopContext();
}
public IEnumerable<Customer> GetAll()
{
return _context.Customers;
}
// Other methods not displayed
protected void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
public class ProductsController : BaseController
{
private IProductRepository _productRepository;
private ICustomerRepository _customerRepository;
public ProductsController()
: this(new ProductRepository(), new CustomerRepository())
{
}
public ProductsController(IProductRepository productRepository, ICustomerRepository customerRepository)
{
_productRepository = productRepository;
_customerRepository = customerRepository;
}
// Other controller methods not shown.
}
Example code would be helpful.
The best working example one can find is the series of Mr Mittal at codeproject
he is using Entity Framework, Generic Repository pattern and Unit of Work.
keep up with him you'll get to know how this all works
here is the link Mittal Series
As #Thomas has already stated in the comments, I think what you're after here is a service layer rather than a repository. The two terms are often used very interchangeably, but they are not the same thing.
The repository pattern is intended to provide an abstraction of the database so that the database can change without impacting on the rest of the code. The DBContext in EF6 is already doing that for you as you can have, for example, a table called one thing, but mapped to a class with a different name. The DBContext also already implements the Unit of Work pattern, as it will perform all actions inside a single transaction up until you call SaveChanges/SaveChangesAsync on the context.
The service layer then provides methods to the user interface layer. It calls the methods from the repository to do this.
With a simple model it seems like the service layer and the repository are the same thing, but your repository would typically map to one business object (e.g. a Contact) where as your service layer might encapsulate a number of objects (e.g. a Customer business entity, which when saved stores data to the Contact and CustomerProfile repositories), using a unit of work to ensure that both changes are committed or rolled back together.
This excellent existing stack overflow answer by #ken2k goes into this in much more detail.