2011-02-07 82 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