簡體   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