更新
找到了这个帮助我使用DbContext的小宝石 Josh Kodroff - Making Entity Framework More Unit-Testable
原始
经过大量研究后,我终于决定在我的MVC5 EF6项目中使用Autofac实现IOC。 Autofac的文档很有帮助,但我还不确定是否需要在Controller或Service Class中调用Dispose()?
我没有使用抽象的UOW和Generic Repository,只是依赖于DbContext和DbSet<>在EF6中提供。这是我课程的片段。
我的DbContext
public class ProductContext : DbContext
{
public ProductContext() : base("ProductContext")
{
}
public DbSet<Availability> Availability { get; set; }
public DbSet<Category> Categories { get; set; }
....
}
我的服务类
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();
}
.....
}
我的服务界面
public interface IProductService
{
List<Product> GetProductsByCategory(string cleanCategory);
....
}
我的控制器
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);
}
我的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));
我已从控制器中删除了Dispose(),并了解Autofac将处理从IDisposable继承的上下文的处理。由于ProductContext继承自包含Dispose()方法的DbContext,因此这应该有效。
我是否需要包含类似
的内容builder.RegisterType<ProductContext>().As<DbContext>().InstancePerRequest();
或我当前的容器是否按预期调用Dispose?
builder.RegisterType<ProductContext>().AsSelf().InstancePerRequest();
感谢您的帮助,我很难在没有通用存储库的情况下使用Autofac查找文档,而在DbContext上使用类似于我当前模式的UOW。
答案 0 :(得分:4)
根据doucmentation,
将自动为您创建和处置Autofac MySQL documentation标准工作单元生命周期范围。 Autofac的integration libraries,将在Web请求开始时为您创建生命周期范围,并且通常会从那里解析所有组件。在Web请求结束时,范围将自动处理 - 您无需创建额外的范围。
所以我认为如果你的班级为J <= J
,那么IDisposable
会自动调用这些对象。简单地说,
Dispose()
将通过对象生命范围管理进行处置。
答案 1 :(得分:2)
Autofac还支持在构造函数注入中使用Func<>
。例如,您可以像平常一样注册数据上下文:
builder.RegisterType<ProductContext>().As<IProductContext>();
并在ProductService
:
public class ProductService : IProductService
{
private IProductContext _dbCreator;
public ProductService(Func<IProductContext> dbCreator)
{
_db = db;
}
public List<Product> GetProductsByCategory(string cleanCategory)
{
using (var dbCtx = _dbCreator())
{
return dbCtx.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();
}
}
.....
}
基本上,您的ProductService
现在可以访问Func<>
(_dbCreator
),每次调用时,都会根据您的autofac注册创建ProductContext
的新实例,允许您在认为合适时处置实例。
我在写完之后意识到你没有IProductContext
,我通常建议使用这种模式,但就你的问题而言,它并不太重要。您可以继续使用ProductContext
的当前注册方法,然后传入Func<ProductContext>
而不是IProductContext
,即
builder.RegisterType<ProductContext>().AsSelf();
和
private ProductContext _dbCreator;
public ProductService(Func<ProductContext> dbCreator)
很抱歉,如果代码没有编译,我没有使用IDE ...希望它足够让你明白我的观点!