我开始使用DI / IoC,我在理解所有概念方面遇到了一些麻烦。
我选择了Autofac,因为它似乎是支持.Net 4.6+和.Net Core的少数几个之一。它似乎也被广泛使用。
1)构造函数注入 - 例如在控制器或我的WCF服务中 我理解不可能对我在代码中实例化的对象进行构造函数注入,这意味着它不会自动实例化。
2)物业注入 我想做一些类似于你在Ninject中做的事情:
[Inject]
public IWeapon Weapon { get; set; }
正如我在自动翻译中所做的那样。它是公平的:
builder.RegisterType<Weapon>().As<IWeapon>().PropertiesAutowired();
1。现在,为什么构造函数注入是首选方式?
例如,我有:
那些工厂,只是单行,应该做(从另一个IoC):
public class DataRepositoryFactory : IDataRepositoryFactory
{
T IDataRepositoryFactory.GetDataRepository<T>()
{
return ObjectBase.Container.GetExportedValue<T>();
}
}
有些方法需要两者,有些则不需要。做类似的事情:
public SampleControllerOrManager(IUnitOfWork unitOfWork, IRepositoryFactory repositoryFactory, IBusinessEngineFactory engineFactory)
似乎浪费资源。
我知道这有助于测试(?)。
但这看起来更干净:
public SampleControllerOrManager(IUnitOfWork unitOfWork)
[Inject]
public IRepositoryFactory RepositoryFactory { get; set; }
[Inject]
public IBusinessEngineFactory EngineFactory { get; set; }
2。将实体框架DbContext注入存储库
我想用Container注册上下文,并将其注入UnitOfWork和Repository的对象构造函数中。我想确保将相同的实例注入到所有对象中。我如何在Autofac中做到这一点?
public class Repository : IRepository {
//context injected here
public Repository (DbContext context){ ... }
}
public class Manager {
public void SomeMethod(){
IRepository = RepositoryFactoryGetDataRepository<ISomeTypeRepository>
}
}
答案 0 :(得分:1)
构造函数注入是首选方法,因为它使它们变得明显。如果不提供所需的依赖项,则无法实例化该类。
使用属性注入依赖项是隐藏的,您可以使用一些丢失的注入实例化该类,这可能会让您相信该类已完全初始化并准备好使用。最终,如果您尝试使用需要缺少依赖项的功能,则可能会出错。
为确保注入相同的实例,您可以将 DbContext 注册为Singleton。 例如:
var builder = new ContainerBuilder();
builder.RegisterType<DbContext>().SingleInstance();
或者,根据您的需要,您可以使用每个请求的实例范围注册它:
var builder = new ContainerBuilder();
builder.RegisterType<DbContext>().InstancePerRequest();
注意:您可能会发现 Martin Fowler 撰写的this article有用。