[英]Autofac. Naming resolving and child dependencies
命名/键控解析是否也使用名称解析子依赖项? 或者命名解析仅将名称/密钥应用于没有其子依赖项的已解析类型?
发生错误:
在“ConsoleApplication1.Program+MainClassOne”类型上用“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”找到的构造函数都不能用可用的服务和参数调用:无法解析构造函数“Void.ctor(我命名)'。
class Program
{
static void Main(string[] args)
{
var container = new ContainerBuilder();
container.RegisterType<NamedB>().Named<INamed>("B");
container.RegisterType<NamedA>().Named<INamed>("A");
container.RegisterType<MainClassOne>().Named<MainClassOne>("A");
container.RegisterType<MainClassTwo>().Named<MainClassTwo>("B");
var di = container.Build();
var a = di.ResolveNamed<MainClassTwo>("B");
var a2 = di.ResolveNamed<MainClassOne>("A");
}
public class MainClassOne
{
public MainClassOne(INamed named)
{
Console.WriteLine("MainClassOne= " + named.Name);
}
}
public class MainClassTwo
{
public MainClassTwo(INamed named)
{
Console.WriteLine("MainClassTwo= " + named.Name);
}
}
public interface INamed
{
string Name { get; set; }
}
public class NamedA : INamed
{
public string Name
{
get { return "A"; }
set { }
}
}
public class NamedB : INamed
{
public string Name
{
get { return "B"; }
set { }
}
}
}
密钥仅在解析请求的服务时使用。 如果将密钥传递给后续的解析操作,则需要依赖图中的所有服务也使用相同的密钥进行注册。
您尝试实现的目标可以使用基于 lambda 的注册来完成,这些注册使您的主类的依赖关系显式。
container.RegisterType<NamedA>().Named<INamed>("A");
container.RegisterType<NamedB>().Named<INamed>("B");
container.Register(c => new MainClassOne(c.ResolveNamed<INamed>("A"))).Named<MainClassOne>("A");
container.Register(c => new MainClassTwo(c.ResolveNamed<INamed>("B"))).Named<MainClassTwo>("B");
这将允许您使用它们的名称解析主类,同时确保它们也接收到正确的命名依赖项。
将您的注册更新为如下所示:
container.RegisterType<NamedB>().Named<INamed>("B");
container.RegisterType<NamedA>().Named<INamed>("A");
container.RegisterType<MainClassOne>()
.Named<MainClassOne>("A")
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.Name == "named",
(pi, ctx) => ctx.ResolveNamed<INamed>("A")));
container.RegisterType<MainClassTwo>()
.Named<MainClassTwo>("B")
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.Name == "named",
(pi, ctx) => ctx.ResolveNamed<INamed>("B")));
可能有一些方法可以使它看起来更整洁(扩展方法等)。 此外,请考虑使用 Keyed 而不是 Named 参数。
“ResolvedParameter” class 接受两个委托 - 第一个是选择器,它允许您确定引用的构造函数参数是否相关,如果相关,则执行第二个委托以提供值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.