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

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; } 正如我所了解的

我开始与DI/IoC合作,我在理解所有概念时遇到了一些困难

我之所以选择Autofac,是因为它似乎是为数不多的同时支持.NET4.6+和.NETCore的软件之一。它似乎也是应用最广泛的软件

1) 构造函数注入-例如,在控制器或我的WCF服务中 我知道不可能对我在代码中实例化的对象进行构造函数注入,这意味着它不会自动实例化

2) 属性注入 我想做一些类似于您在Ninject中所做的事情:

[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();