如何确保Autofac在EF6 DbContext上调用Dispose()

Sea*_*G80 6 c# dispose autofac entity-framework-6

UPDATE

发现这个小宝石帮助我使用DbContext Josh Kodroff - 让实体框架更加单元可测试

原版的

经过大量的研究后,我终于决定在我的MVC5 EF6项目中使用Autofac实现IOC.Autofac的文档很有用,但我仍然不确定是否需要在Controller或Service Class中调用Dispose()?

我没有使用抽象的UOW和Generic Repository,只是依赖于EF6中提供的DbContext和DbSet <>.这是我课程的片段.

我的DbContext

public class ProductContext : DbContext
{
    public ProductContext() : base("ProductContext")
    {
    }

    public DbSet<Availability> Availability { get; set; }       
    public DbSet<Category> Categories { get; set; } 
    ....
 }
Run Code Online (Sandbox Code Playgroud)

我的服务类

    public class ProductService : IProductService
{
    private ProductContext _db;
    public ProductService(ProductContext db)
    {
        _db = db;
    }

    public List<Product> GetProductsByCategory(string cleanCategory)
    {
        return _db.Products
             .Include(p => p.Options.Select(o => o.OptionGroup))
                 .Include(p => p.Associations.Select(a => a.AssociatedGroup))
                 .Include(p => p.Variations).Include(p => p.Manufacturer)
                 .Where(p => p.Active && p.Category.Name.ToUpper().Equals(cleanCategory)).ToList();
    }
    .....
}
Run Code Online (Sandbox Code Playgroud)

我的服务界面

    public interface IProductService
{
    List<Product> GetProductsByCategory(string cleanCategory);
    ....
}
Run Code Online (Sandbox Code Playgroud)

我的控制器

    public class ProductsController : Controller
{
    private IProductService _productService;
    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }

    //GET: Products/
    public ActionResult Index(string category)
    {
        if (String.IsNullOrEmpty(category))
        {
            return HttpNotFound();
        }

        string cleanCategory = urlScrubber(category);
        var viewModel = new ProductsVM();
        viewModel.ProductList = _productService.GetProductsByCategory(cleanCategory);
}
Run Code Online (Sandbox Code Playgroud)

我的Autofac容器

var builder = new ContainerBuilder();

        // Register your MVC controllers.
        builder.RegisterControllers(typeof(MvcApplication).Assembly);

        // REGISTER COMPONENTS HERE:
        builder.RegisterType<ProductContext>().AsSelf().InstancePerRequest();
        builder.RegisterType<ProductService>().As<IProductService>().InstancePerRequest();

        // Set the dependency resolver to be Autofac.
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
Run Code Online (Sandbox Code Playgroud)

我已经从控制器中删除了Dispose(),理解为Autofac将处理从IDisposable继承的上下文的处理.由于ProductContext继承自包含Dispose()方法的DbContext,因此这应该有效.

我是否需要包含类似的内容

builder.RegisterType<ProductContext>().As<DbContext>().InstancePerRequest();
Run Code Online (Sandbox Code Playgroud)

或者我当前的容器是否按预期调用Dispose?

builder.RegisterType<ProductContext>().AsSelf().InstancePerRequest();
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助,我很难在没有通用存储库的情况下使用Autofac查找文档,而在DbContext上使用类似于我当前模式的UOW.

ven*_*mit 5

按照配方,

Autofac 集成库标准的工作单位生命周期范围将自动创建并为您处理。Autofac的ASP.NET MVC集成,将在Web请求开始时为您创建一个生存期范围,并且通常会从那里解析所有组件。在Web请求结束时,范围将自动被处理-您无需另外创建范围。

所以,我认为,如果你的类implments IDisposable然后Dispose()会自动调用这些对象。就是这么简单

builder.RegisterType<ProductContext>().As<DbContext>().InstancePerRequest();
Run Code Online (Sandbox Code Playgroud)

将通过对象寿命范围管理进行处置。

  • 就这么简单.. DbContext 是实现 IDisposable 的抽象类,意味着它派生不需要显式实现 IDisposable。Dispose 实际上会在 Dervied 对象上被调用。这是继承的基本原则:)无论如何..祝你的生产工作好运。干杯!! (2认同)