2011-02-07 121 views
0

說我有:嵌套分辨率

ProductA 
ProductB 

ProductScreen 

ProductAScreen1 : ProductScreen 
ProductAScreen2 : ProductScreen 

ProductBScreen1 : ProductScreen 
ProductBScreen2 : ProductScreen 

我如何可以設置它使我在本地註冊的屏幕的產品?所以當我在ProductA中並傳遞IEnumerable時,它不能解析ProductB的屏幕?

我認爲這是可以實現的使用像生命週期的範圍,但它不會出現我正確理解它。

回答

4

生命週期範圍用於控制實例生命週期。你在談論控制選擇。爲此,您應該在Autofac中查看the metadata features

使用元數據,可以在「標籤」的每個產品的屏幕,表示它所屬的產品:

builder.Register(c => new ProductAScreen1()).As<ProductScreen>() 
    .WithMetadata<IProductScreenMetadata>(m => 
     m.For(am => am.ProductType, typeof(ProductA))); 
builder.Register(c => new ProductAScreen2()).As<ProductScreen>() 
    .WithMetadata<IProductScreenMetadata>(m => 
     m.For(am => am.ProductType, typeof(ProductA))); 

builder.Register(c => new ProductBScreen1()).As<ProductScreen>() 
    .WithMetadata<IProductScreenMetadata>(m => 
     m.For(am => am.ProductType, typeof(ProductB))); 
builder.Register(c => new ProductBScreen2()).As<ProductScreen>() 
    .WithMetadata<IProductScreenMetadata>(m => 
     m.For(am => am.ProductType, typeof(ProductB))); 

接下來,可以採取一個IEnumerable<Lazy<ProductScreen, IProductScreenMetadata>>的依賴性和解決屏幕根據產品類型:

var productScreens = _screens.WHere(a => a.Metadata.ProductType == typeof(ProductA)); 

更新:爲了完整性,這裏是一個簡單的解決方案,使用the Keyed approach。首先,註冊簡單得多:

builder.RegisterType<ProductAScreen1>().Keyed<ProductScreen>(typeof(ProductA)); 
builder.RegisterType<ProductAScreen2>().Keyed<ProductScreen>(typeof(ProductA)); 
builder.RegisterType<ProductBScreen1>().Keyed<ProductScreen>(typeof(ProductB)); 
builder.RegisterType<ProductBScreen2>().Keyed<ProductScreen>(typeof(ProductB)); 

要解決的鍵控服務的集合,我們將不得不採取對IIndex<,>類型的依賴:

public class SomeService  
{ 
    private IEnumerable<ProductScreen>> _screens; 
    public SomeService(IIndex<Type, IEnumerable<ProductScreen>> screens) 
    { 
     _screens = screens; 
    } 

    public void DoSomething() 
    { 
     var screensForProductA = _screens[typeof(ProductA)]; 
    } 
} 

注:爲好奇:代替硬編碼的類型註冊,這裏是如何做一個「按慣例」註冊:

var assembly = ...; 
var productTypes = ...; // a collection of all the product types 

foreach(var productType in productTypes) 
{ 
    builder.RegisterAssemblyTypes(assembly) 
     .Where(t => typeof(ProductScreen).IsAssignableFrom(t)) 
     .Where(t => t.Name.StartsWith(productType.Name)) 
     .Keyed<ProductScreen>(productType); 
} 
+0

謝謝彼得。這似乎是一個不錯的選擇。我嘗試過,並使用.Keyed()註冊它。他們都看起來很體面。 – Mark 2011-02-08 14:40:56