4

我只是在学习 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

4

2 回答 2

5

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

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”或“c)的 NamedParameter 实例中提取值") 并将该值传递给 ClassA 的构造函数。NamedParameter 对象将作为 Resolve 调用的一部分传递,例如Resolve<ClassA>(new NamedParameter("a", "AAAA")).

最后的 register 调用告诉 Autofac 它必须解析 ClassA、ClassB 和 ClassC 的实例,并将这些实例传递给 Classes 的构造函数。为了解决这些依赖关系,Autofac 必须从传入的一些 NamedParameter 实例中提取值,并将这些值传递到新 NamedParameter 实例中的 Resolve 中。

有两点需要注意。

  1. 可以在类的 Register 调用中重用 NamedParameter 实例,而不是创建新实例。匿名函数的 p 参数是一个 IEnumerable,所以它可能是可能的。
  2. 此代码使用最新版本的 Autofac (2.6.1) 进行了测试。
于 2012-05-02T17:06:55.320 回答
3

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

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

而不是像这样创建一个生命周期范围:

var scope = container.BeginLifetimeScope();

scope现在您可以像从容器中解析实例一样,但是每个范围都有一个单独的ClassA,ClassB和实例ClassC

于 2012-05-02T14:41:56.693 回答