Autofac:注册依赖于其他类的特定实例的类

时间:2012-05-02 14:22:56

标签: c# dependency-injection autofac

我只是在学习Autofac并试图了解如何解决服务之间的依赖关系。

说我有以下课程:

class ClassA {}
class ClassB {}
class ClassC {}

class Classes
{
    public Classes(ClassA classA, ClassB classB, ClassC classC)
    {
        ...
    }
}

并且我想注册这些类,以便模仿以下行为。

var classA1 = new ClassA("A1");
var classB1 = new ClassB("B1");
var classC1 = new ClassC("C1");
var classes1 = new Classes(classA1, classB1, classC1);

var classA2 = new ClassA("A2");
var classB2 = new ClassB("B2");
var classC2 = new ClassC("C2");
var classes2 = new Classes(classA2, classB2, classC2);

简而言之,Classes取决于ClassAClassBClassC的特定实例。我该怎么做?

2 个答案:

答案 0 :(得分:5)

如果您希望能够创建Classes类的多个唯一实例,我将使用Autofac的parameter passing功能构建我的注册。我的代码看起来像

var builder = new ContainerBuilder();
builder.Register((c,p) => new ClassA(p.Named<string>("a")));
builder.Register((c,p) => new ClassB(p.Named<string>("b")));
builder.Register((c,p) => new ClassC(p.Named<string>("c")));
builder.Register((c,p) => new Classes(
    c.Resolve<ClassA>(new NamedParameter("a", p.Named<string>("ClassA"))),
    c.Resolve<ClassB>(new NamedParameter("b", p.Named<string>("ClassB"))),
    c.Resolve<ClassC>(new NamedParameter("c", p.Named<string>("ClassC")))));

var container = builder.Build();
var classes = container.Resolve<Classes>(
    new NamedParameter("ClassA", "AAAA"),
    new NamedParameter("ClassB", "BBBB"),
    new NamedParameter("ClassC", "CCCCC"));

前三个注册调用告诉​​Autofac,当它想要构建ClassA(或B或C)的实例时,必须使用名为“a”(或“b”)的NamedParameter实例中的值提取或“c”)并将该值传递给ClassA的构造函数。 NamedParameter对象将作为Resolve调用的一部分传递,如Resolve<ClassA>(new NamedParameter("a", "AAAA"))

最终的寄存器调用告诉Autofac它必须解析ClassA,ClassB和ClassC的实例,并将这些实例传递给Classes的构造函数。要解决这些依赖关系,Autofac必须从传入的NamedParameter的某些实例中提取值,并将它们传递到新的NamedParameter实例中的Resolve。

有两点需要注意。

  1. 可以在Register for Classes中重用NamedParameter实例,而不是创建新的实例。匿名函数的p参数是IEnumerable,所以它可能是。
  2. 此代码使用最新版本的Autofac(2.6.1)进行测试。

答案 1 :(得分:3)

最简单的方法是使用生命周期范围。像这样注册你的课程:

builder.RegisterType<ClassA>().InstancePerLifetimeScope();
builder.RegisterType<ClassB>().InstancePerLifetimeScope();
builder.RegisterType<ClassC>().InstancePerLifetimeScope();

而不是像这样创建一个终身范围:

var scope = container.BeginLifetimeScope();

现在您可以从容器中解析scope中的实例,但每个范围都有一个单独的ClassAClassBClassC实例。