我为服务注册了两个组件:
container.Register(
Component.For<IDataStorage>().Named("FirstChoice").ImplementedBy...
Component.For<IDataStorage>().Named("SecondChoice").ImplementedBy
然后我有一组派生自这个基类的组件,它取决于那些组件:
public abstract class BaseMessageHandler
{
public IDataStorage FirstStorage {get; set;}
public IDataStorage SecondStorage {get; set;}
}
如果我手动注册这些“处理程序”(从BaseMessageHandler派生),我会指定一个服务覆盖,指示我想要属性“FirstStorage”和“SecondStorage”的组件。类似的东西:
.Configure(x => x.DependsOn(
ServiceOverride.ForKey("FirstStorage").Eq("FirstChoice"),
ServiceOverride.ForKey("SecondStorage").Eq("SecondChoice"))
不幸的是,这个注册是由框架(NServiceBus)自动完成的。我知道如果我首先注册处理程序(在NServiceBus有机会之前),这些注册将会坚持下去。但是我不想尝试猜测并模仿NServiceBus的注册,而是想知道我是否可以在自定义IContributeComponentModelConstruction中指定服务覆盖。 这似乎是一个好地方,我能找到这些属性:
public class DataStorageOverrideContributor : IContributeComponentModelConstruction
{
public void ProcessModel(Castle.MicroKernel.IKernel kernel, Castle.Core.ComponentModel model)
{
var dataStorageDependencies = model.Properties.Where(
x => x.Dependency.TargetItemType == typeof(IDataStorage));
foreach (var propertyDependency in dataStorageDependencies)
{
// now what??
但我不确定正确的方法:
这可以在IContributeComponentModelConstruction.ProcessModel方法中检查和处理ComponentModel吗?
答案 0 :(得分:1)
我会在你的场景中使用一个子顺从解析器。您可以在下面看到有关如何使用它的代码。
古德勒克,
Marwijn。
公共接口IDataStorage { }
public class DataStore1 : IDataStorage
{
}
public class DataStore2 : IDataStorage
{
}
public class BaseMessageHandler
{
public IDataStorage FirstStorage { get; set; }
public IDataStorage SecondStorage { get; set; }
}
public class SubDependencyResolver : ISubDependencyResolver
{
private readonly IKernel _kernel;
public SubDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
return model.Implementation == typeof (BaseMessageHandler) && dependency.TargetType == typeof(IDataStorage);
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
var handlers = _kernel.GetHandlers(dependency.TargetType);
switch (dependency.DependencyKey)
{
case "FirstStorage":
return handlers.Single(h => h.ComponentModel.Implementation == typeof (DataStore1)).Resolve(context);
case "SecondStorage":
return handlers.Single(h => h.ComponentModel.Implementation == typeof(DataStore2)).Resolve(context);
}
return null;
}
}
[TestFixture]
public class Tests
{
[Test]
public void SomeTest()
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new SubDependencyResolver(container.Kernel));
container.Register(
Component.For<IDataStorage>().Named("FirstChoice").ImplementedBy<DataStore1>(),
Component.For<IDataStorage>().Named("SecondChoice").ImplementedBy<DataStore2>(),
Component.For<BaseMessageHandler>()
);
var messageHandler = container.Resolve<BaseMessageHandler>();
Assert.AreEqual(typeof(DataStore1), messageHandler.FirstStorage.GetType());
Assert.AreEqual(typeof(DataStore2), messageHandler.SecondStorage.GetType());
}
}
您可以使用的替代方案:
case "FirstStorage":
return handlers.Single(h => h.ComponentModel.Name == "FirstChoice").Resolve(context);
case "SecondStorage":
return handlers.Single(h => h.ComponentModel.Name == "SecondChoice").Resolve(context);
解决组件名称而不是实现类型。