Autofac构造函数/属性注入(DbContex

时间:2018-04-23 10:46:07

标签: c# entity-framework inversion-of-control autofac ioc-container

我开始使用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>
        }
    }

1 个答案:

答案 0 :(得分:1)

构造函数注入

构造函数注入是首选方法,因为它使它们变得明显。如果不提供所需的依赖项,则无法实例化该类。

使用属性注入依赖项是隐藏的,您可以使用一些丢失的注入实例化该类,这可能会让您相信该类已完全初始化并准备好使用。最终,如果您尝试使用需要缺少依赖项的功能,则可能会出错。

实例范围

为确保注入相同的实例,您可以将 DbContext 注册为Singleton。 例如:

var builder = new ContainerBuilder();
builder.RegisterType<DbContext>().SingleInstance();

或者,根据您的需要,您可以使用每个请求的实例范围注册它:

var builder = new ContainerBuilder();
builder.RegisterType<DbContext>().InstancePerRequest();

注意:您可能会发现 Martin Fowler 撰写的this article有用。