我是否以正确的方式使用Unity和UnitOfWork?

时间:2013-02-12 16:36:06

标签: c# asp.net-mvc dependency-injection unity-container unit-of-work

我是否正确这样做?内存使用或性能是否会出现问题?

UPD:修复已处理上下文的错误。

我正在使用Unity与工作单元模式。当我第一次运行我的应用程序时,一切都按预期工作,但一旦我刷新页面,应用程序崩溃时出现以下异常:

  
    

由于已经处理了DbContext,因此无法完成操作。

  

我的DI配置如下:

private static IUnityContainer BuildUnityContainer()
{
    var container = new UnityContainer();

    container.RegisterType<DataContext>();

    container.RegisterType<IUnitOfWorkFactory, UnitOfWorkFactory>();

    container.RegisterType<IUnitOfWork, UnitOfWork>();

    container.RegisterType<IProductRepository, ProductRepository>();

    return container;
}

我的UnitOfWorkUnitOfWorkFactory如下所示:

public class UnitOfWork : IUnitOfWork
{
    private readonly IUnityContainer _container;
    private bool _disposed;

    public UnitOfWork(IUnityContainer container)
    {
        _container = container;
        Context = _container.Resolve<DataContext>();
    }

    internal DataContext Context { get; set; }

    public TRepository GetRepository<TRepository>() 
        where TRepository : class
    {
        return _container.Resolve<TRepository>();
    }

    public void Commit()
    {
        Context.SaveChanges();
    }

    public void Dispose()
    {
        if (!_disposed)
        {
            _disposed = true;
            Context.Dispose();
        }
    }
}

public class UnitOfWorkFactory : IUnitOfWorkFactory
{
    private readonly IUnityContainer _container;

    public UnitOfWorkFactory(IUnityContainer container)
    {
        _container = container;
    }

    public IUnitOfWork CreateUnitOfWork()
    {
        return _container.Resolve<UnitOfWork>();
    }
}

UnitOfWork包含允许返回任何存储库的GetRepository方法。以下是此类存储库的示例:

public class ProductRepository : BaseRepository<Product>,
    IProductRepository
{
    public ProductRepository(UnitOfWork unitOfWork)
        :base(unitOfWork)
    {
    }

    public Product Create(Product entity)
    {
        return DataBase.Add(entity);
    }

    public Product Remove(Product entity)
    {
        return DataBase.Remove(entity);
    }

    public Product Get(Int32 entityId)
    {
        return DataBase.FirstOrDefault(x => x.Id == entityId);
    }
}

public class BaseRepository<TEntity> 
    where TEntity : class
{
    internal BaseRepository(UnitOfWork unitOfWork)
    {
        UnitOfWork = unitOfWork;

    }

    internal UnitOfWork UnitOfWork { get; private set; }

    internal virtual IDbSet<TEntity> DataBase
    {
        get { return UnitOfWork.Context.Set<TEntity>(); }
    }
}

我的MVC控制器依赖于IUnitOfWorkFactory。以下是AccountController例如:

public class AccountController : Controller
{
    private readonly IUnitOfWorkFactory _unitOfWorkFactory;

    public AccountController(IUnitOfWorkFactory unitOfWorkFactory)
    {
        _unitOfWorkFactory = unitOfWorkFactory;
    }

    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;

        using (var uow = _unitOfWorkFactory.CreateUnitOfWork())
        {
            var rep = uow.GetRepository<IProductRepository>();

            var prod = rep.GetById(1);
        }

        return View();
    }
}

2 个答案:

答案 0 :(得分:2)

你告诉Unity创建一次UnitOfWork(单身):

    container.RegisterType<IUnitOfWork, UnitOfWork>(
    new ContainerControlledLifetimeManager());

我不认为你想要那个。删除ContainerControlledLifetimeManager()....

答案 1 :(得分:0)

我认为这是因为你正在使用的LifetimeManager。 (LifetimeManager保留给它的实例。)您的实例被释放,但由于ContainerControlledLifetimeManager,它不会创建新的实例。在this文章中,您可以了解如何解决此问题。

基本上最好使用Unity.MVC3包,并为您的IDisposable依赖项定义HierarchicalLifetimeManager。