[英]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.