2016-09-19 99 views
0

我有三個類的聲明像上面有沒有辦法介入autofac的實例化過程?

[Plug("hello")] 
public class Plug1 : IPlug{} 
[Plug("hello")] 
public class Plug2 : IPlug{} 
[Plug("world")] 
public class Plug3 : IPlug{} 

當我使用container.Resolve<IEnumerable<IPlug>>()來解決,我得到的所有實例,實現IPlug接口,不過,我想獲得第一和第二(或世界,這該實例被標記爲屬性Plug("hello"))。

有沒有辦法實現它?

我想避免使用

container.Resolve<IEnumerable<IPlug>>() 
     .Where(t => t.FirstAttribute<Plug>() != null 
        && t.FirstAttribute<Plug>().Id == "Hello") 

我總覺得它並不像表現的結果的最佳實踐。

回答

1

有很多方法可以做到你想要的。

最簡單的方法是將註冊類型命名註冊

builder.RegisterType<Plug1>().As<IPlug>().WithMetadata("plug", "hello"); 
builder.RegisterType<Plug2>().As<IPlug>().WithMetadata("plug", "hello"); 
builder.RegisterType<Plug3>().As<IPlug>().WithMetadata("plug", "world"); 

您還可以使用屬性來註冊這些類型:

builder.RegisterType<Plug1>() 
     .As<IPlug>() 
     .WithMetadata("plug", typeof(Plug1).FirstAttribute<Plug>().?Id ?? "Default"); 

然後,你將能夠得到所有命名IPlug註冊使用IEnumerable<Meta<IPlug>>

container.Resolve<IEnumerable<Meta<IPlug>>>() 
     .Where(m => m.Metadata["plug"] as String == "hello") 
     .Select(m => m.Value); 

如果你不想在運行,但國際奧委會根組成中過濾和IEnumerable<IPlug>總會解決的濾波IEnumerable<IPlug>那麼你可以重寫IEnumerable<IPlug>登記:

builder.Register(c => c.Resolve<IEnumerable<Meta<IPlug>>>() 
         .Where(m => m.Metadata["plug"] as String == "hello") 
         .Select(m => m.Value)) 
     .As<IEnumerable<IPlug>>(); 
+0

謝謝。這是一個不錯的選擇。 – linus

相關問題