Where does Unit Of Work belong w/ EF4, IoC (Unity), and Repository?

前端 未结 2 1443
滥情空心
滥情空心 2020-12-11 04:51

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 (a

相关标签:
2条回答
  • 2020-12-11 05:18

    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();
    }
    
    0 讨论(0)
  • 2020-12-11 05:22

    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).

    0 讨论(0)
提交回复
热议问题