我只是在学习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
取决于ClassA
,ClassB
和ClassC
的特定实例。我该怎么做?
答案 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 :(得分:3)
最简单的方法是使用生命周期范围。像这样注册你的课程:
builder.RegisterType<ClassA>().InstancePerLifetimeScope();
builder.RegisterType<ClassB>().InstancePerLifetimeScope();
builder.RegisterType<ClassC>().InstancePerLifetimeScope();
而不是像这样创建一个终身范围:
var scope = container.BeginLifetimeScope();
现在您可以从容器中解析scope
中的实例,但每个范围都有一个单独的ClassA
,ClassB
和ClassC
实例。