using UnitOfWork and Repository Pattern with Entity Framework

后端 未结 3 1110
情书的邮戳
情书的邮戳 2021-02-04 21:22

I\'m gonna to use repository and UnitOfwork in my data access layer to do this take a look at one contact aggregateroot

 public interface IAggregateRoot
    {
          


        
3条回答
  •  面向向阳花
    2021-02-04 22:06

    It's not a direct answer to your question, but it might simplify things a little bit and reduce duplication.

    When you use e.g. EntityFramework Power Tools to reverse-engineer Code First (or just use Code First in general), you end up with the DbContext class that serves as a UoW and repository in one, e.g.:

    public partial class YourDbContext : DbContext
    {
        public DbSet Contacts {get; set;}
    }
    

    Now, if you want things to be testable, there's an easy way: introduce a very thin interface:

    public interface IDbContext
    {
        IDbSet EntitySet() where T : class;
        int SaveChanges();
        //you can reveal more methods from the original DbContext, like `GetValidationErrors` method or whatever you really need.
    }
    

    then make another file with second part of the partial class:

    public partial class YourDbContext : IDbContext
    {
         public IDbSet EntitySet() where T : class
         {
             return Set();
         }
    }
    

    Ta-da! Now you can inject IDbContext with YourDbContext backing it up:

    //context is an injected IDbContext:
    var contact = context.EntitySet().Single(x => x.Id == 2);    
    contact.Name = "Updated name";
    context.EntitySet().Add(new Contact { Name = "Brand new" });
    context.SaveChanges();
    

    Now if you want to have control over the disposal of the context, then you'd have to write your own (gasp) IDbContextFactory (generic or not, depending what you need) and inject that factory instead.

    No need to write your own Find, Add or Update methods now, DbContext will handle that appropriately, it's easier to introduce explicit transactions and everything is nicely hidden behind interfaces (IDbContext, IDbSet).

    By the way, the IDbContextFactory would be an equivalent to NHibernate's ISessionFactory and IDbContext - ISession. I wish EF had this out of the box, too.

提交回复
热议问题