繁体   English   中英

Autofac。 命名解析和子依赖

[英]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 接受两个委托 - 第一个是选择器,它允许您确定引用的构造函数参数是否相关,如果相关,则执行第二个委托以提供值。

通过上下文查看键控服务select 以获取更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM