简体   繁体   English

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

[英]Am i using Unity and UnitOfWork in right way?

Am I correct doing this? 我这样做是对的吗? Can there be problems with memory usage or performance? 内存使用或性能是否存在问题?

UPD:Bug with disposed context is fixed. UPD:修复已处理上下文的错误。

I'm using Unity with the Unit of Work pattern. 我正在使用Unity与工作单元模式。 When I run my application for the first time, everything works as expected, but once I refresh the page, the app crashes with the following exception: 当我第一次运行我的应用程序时,一切都按预期工作,但一旦我刷新页面,应用程序崩溃时出现以下异常:

The operation cannot be completed because the DbContext has been disposed. 由于已经处理了DbContext,因此无法完成操作。

My DI configuration looks like this: 我的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;
}

My UnitOfWork and UnitOfWorkFactory look like this: 我的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>();
    }
}

The UnitOfWork contains a GetRepository method that allows returning any repository. UnitOfWork包含一个允许返回任何存储库的GetRepository方法。 Here is an example of such a repository: 以下是此类存储库的示例:

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>(); }
    }
}

My MVC controllers depend on IUnitOfWorkFactory . 我的MVC控制器依赖于IUnitOfWorkFactory Here is the AccountController for example: 以下是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();
    }
}

You are telling Unity to create UnitOfWork once (singleton): 您告诉Unity创建一次UnitOfWork(单例):

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

I dont think you want that. 我不认为你想要那个。 Remove the ContainerControlledLifetimeManager().... 删除ContainerControlledLifetimeManager()....

I think this is because of the LifetimeManager you are using. 我认为这是因为你正在使用的LifetimeManager。 (A LifetimeManager holds onto an instance given to it.) Your instance is disposed, but becouse of the ContainerControlledLifetimeManager, it doesn't create a new one. (LifetimeManager保留给它的实例。)您的实例被释放,但由于ContainerControlledLifetimeManager,它不会创建新的实例。 In this article you can read how you can resolve this issue. 文章中,你可以看到你是如何解决这个问题。

Basically it is a good idea to use Unity.MVC3 package, and define a HierarchicalLifetimeManager for your IDisposable dependencies. 基本上,最好使用Unity.MVC3包,并为您的IDisposable依赖项定义HierarchicalLifetimeManager。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我是否以正确的方式统一使用依赖注入? - am i using dependency incection with unity the right way? 我是否以正确的方式使用静电? - Am I using static in the right way? 这是使用Dapper的正确方法还是我做错了? - Is this the right way of using Dapper or am I doing it all wrong? 我是否正确使用mongodb驱动程序执行此删除代码? - Am I doing this deletion code using mongodb driver on right way? 我是否以正确的方式测试我的存储库? - Am I testing My repository the right way? 这是使用基于约定的方法在Unity中注册类型的正确方法吗? - Is this the right way to register types in Unity using a convention-based approach? 使用Unity进行属性依赖注入的正确方法 - The right way to do property dependency injection using Unity 使用GridSplitter作为扩展器,我这样做对吗? - Using GridSplitter as an expander, am I doing this right? Unity Admob-正确的AdRequest方法 - Unity Admob - AdRequest the right way 存储库,UnitOfWork和服务提供商一起,将所有这些依赖项注入我的控制器的正确方法是什么? - Repository, UnitOfWork along with service provider, what is he right way to inject all these dependencies into my controller?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM