说我有:
ProductA
ProductB
ProductScreen
ProductAScreen1 : ProductScreen
ProductAScreen2 : ProductScreen
ProductBScreen1 : ProductScreen
ProductBScreen2 : ProductScreen
如何设置它以便我在本地注册产品?因此,当我在ProductA中并传递IEnumerable时,它无法解析ProductB的屏幕?
我认为这可以通过使用寿命范围之类的东西来实现,但似乎我没有理解它。
答案 0 :(得分: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);
}