2011-02-23 27 views
5

我注意到我經常需要實現複合圖案。例如:Autofac複合圖案

interface IService { ... } 
class Service1 : IService { ... } 
class Service2 : IService { ... } 
class CompositeService : IService 
{ 
    public CompositeService(IEnumerable<IService> services) { ... } 
    ... 
} 

我想在容器中註冊CompositeService作爲IService,並且注入了依賴關係。

(看起來有點類似裝飾裝潢卻一組服務,而不是隻有一個)

什麼是做在autofac的最佳方式?

理想解決方案如何(C#)?

更新:

我目前的註冊是:

builder.RegisterType<Service1>().Named<IService>("impl"); 
builder.RegisterType<Service2>().Named<IService>("impl"); 

builder.Register(c => new CompositeService(c.Resolve<IEnumerable<IService>>("impl"))) 
    .As<IService>(); 

它類似於裝飾手工http://nblumhardt.com/2011/01/decorator-support-in-autofac-2-4

是否可以改進?

回答

3

我還沒有實現這個,甚至認爲它通過充分,但我能做到的最好的語法是:

builder 
.RegisterComposite<IService>((c, elements) => new CompositeService(elements)) 
.WithElementsNamed("impl"); 

elements參數註冊函數將IEnumerable<IService>類型和封裝c.Resolve<IEnumerable<IService>>("impl")

現在該怎麼寫...

+0

我也會提出一個簡單的例子: 'builder.RegisterCompositeType (「impl」)'。我只是不喜歡手動調用構造函數,因爲依賴關係可以被注入。 – 2011-03-01 06:12:10

+1

@Konstantin Spirin:我曾考慮過這種超載,但想明確我的答案是怎麼回事。我唯一會改變的是我仍然會使用'WithElementsNamed'(以及'WithElementsKeyed')方法,所以我們不必爲各種註冊類型創建'RegisterComposite'的重載(這不是任何註冊類型其他註冊方法對於命名/鍵控類型)。 – 2011-03-01 15:41:20

1

您可以嘗試命名或鍵控註冊。命名註冊只是獲取一個字符串名稱,以區別於同一接口的其他註冊。同樣,一個鍵使用某種值類型(例如枚舉)來區分多個註冊。您的CompositeService可能是默認引用,按類型註冊,不需要其他特殊信息。您將需要一些方法來解決其他IService依賴關係並將它們傳遞給構造函數; CompositeService的工廠方法可能有效。

+0

謝謝!我目前正在做你剛纔描述的內容。我希望有一個更聰明,更短的代碼。 – 2011-02-24 03:40:06