C# Autofac构造函数/属性注入(DbContex
我开始与DI/IoC合作,我在理解所有概念时遇到了一些困难 我之所以选择Autofac,是因为它似乎是为数不多的同时支持.NET4.6+和.NETCore的软件之一。它似乎也是应用最广泛的软件 1) 构造函数注入-例如,在控制器或我的WCF服务中 我知道不可能对我在代码中实例化的对象进行构造函数注入,这意味着它不会自动实例化 2) 属性注入 我想做一些类似于您在Ninject中所做的事情:C# Autofac构造函数/属性注入(DbContex,c#,entity-framework,inversion-of-control,autofac,ioc-container,C#,Entity Framework,Inversion Of Control,Autofac,Ioc Container,我开始与DI/IoC合作,我在理解所有概念时遇到了一些困难 我之所以选择Autofac,是因为它似乎是为数不多的同时支持.NET4.6+和.NETCore的软件之一。它似乎也是应用最广泛的软件 1) 构造函数注入-例如,在控制器或我的WCF服务中 我知道不可能对我在代码中实例化的对象进行构造函数注入,这意味着它不会自动实例化 2) 属性注入 我想做一些类似于您在Ninject中所做的事情: [Inject] public IWeapon Weapon { get; set; } 正如我所了解的
[Inject]
public IWeapon Weapon { get; set; }
正如我所了解的,在Autofac。这相当于:
builder.RegisterType<Weapon>().As<IWeapon>().PropertiesAutowired();
看起来像是浪费资源
我知道这有助于测试(?)
但这看起来更干净:
public SampleControllerOrManager(IUnitOfWork unitOfWork)
[Inject]
public IRepositoryFactory RepositoryFactory { get; set; }
[Inject]
public IBusinessEngineFactory EngineFactory { get; set; }
2。将实体框架DbContext注入到存储库中
我想用容器注册上下文,并将其注入UnitOfWork和存储库的对象构造函数中。我想确保将相同的实例注入到所有对象中。如何在Autofac中执行此操作
public class Repository : IRepository {
//context injected here
public Repository (DbContext context){ ... }
}
public class Manager {
public void SomeMethod(){
IRepository = RepositoryFactoryGetDataRepository<ISomeTypeRepository>
}
}
公共类存储库:IRepository{
//这里注入了上下文
公共存储库(DbContext上下文){…}
}
公共班级经理{
公共方法(){
IRepository=RepositoryFactoryGetDataRepository
}
}
构造函数注入
构造函数注入是首选方法,因为它使它们变得显而易见。如果不提供所需的依赖项,则无法实例化该类
属性注入依赖项是隐藏的,您可以用一些缺少的注入来实例化类,这可能会使您相信该类已经完全初始化并准备好使用。最终,如果您尝试使用需要缺少依赖项的功能,可能会出现错误
实例范围
为了确保注入相同的实例,可以将DbContext注册为。
例如:
var builder = new ContainerBuilder();
builder.RegisterType<DbContext>().SingleInstance();
var builder=newcontainerbuilder();
builder.RegisterType().SingleInstance();
或者,根据您的需要,您可以使用每个请求的实例范围进行注册:
var builder=newcontainerbuilder();
builder.RegisterType().InstancePerRequest();
注意:您可能会发现Martin Fowler的文章很有用。正如我在第1页的例子中所说,如果不是所有的深度都是必需的,那该怎么办?因为它们不是在一个类的每个方法中都使用的,这并不意味着它们是可选的。DbContext不能是一个单例,它反对一切。管理器/控制器是按请求创建的,这意味着每次请求操作时都会创建新实例。在该操作的范围内,应该将一个DbContext注入到内部请求的每个存储库中。我认为我应该使用类似“每个生命周期范围”的东西。例如,当您使用一个框架为您实例化类,但不允许您提供自定义工厂来完成这项工作时,它有时是有用的。如果没有属性注入,则无法注入所需的依赖项。在我看来,这更像是一种变通办法。如果可能,您应该使用构造函数注入。如果不是,则使用属性注入。不,工厂模式不是一种坏做法。依赖项并不隐藏,任何希望实例化工厂的人都可以看到它们。我要说的是,将责任委托给特定的班级是一个相当好的实践,也是坚实的第一原则。
public class Repository : IRepository {
//context injected here
public Repository (DbContext context){ ... }
}
public class Manager {
public void SomeMethod(){
IRepository = RepositoryFactoryGetDataRepository<ISomeTypeRepository>
}
}
var builder = new ContainerBuilder();
builder.RegisterType<DbContext>().SingleInstance();
var builder = new ContainerBuilder();
builder.RegisterType<DbContext>().InstancePerRequest();