在创建组件期间如何配置 Castle Windsor 错误处理?
我有一个在温莎城堡注册的组件,它依赖于组件列表,每个组件都由一个接口表示。 Castle Windsor 的配置类似于下面的代码。
public class WindsorInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
//Allow the container to resolve all IFooComponent
//as IEnumerable<IFooComponent>
container.Kernel.Resolver
.AddSubResolver(new CollectionResolver(container.Kernel, false));
container.Register(
Component
.For<IMainService>()
.ImplementedBy<AwesomeMainService>());
container.Register(
Component.For<IFooComponent>()
.ImplementedBy<CoolFooComponent>()
.Named(typeof (CoolFooComponent).Name),
Component.For<IFooComponent>()
.ImplementedBy<FooComponentWithUnresolvedDependancy>()
.Named(typeof (FooComponentWithUnresolvedDependancy).Name)
//....
);
}
}
AwesomeMainService
依赖于 IEnumerable
如下所示
public class AwesomeMainService : IMainService
{
public AwesomeMainService(IEnumerable<IFooComponent> fooComponents)
{
//I could count the fooComponents here but this is a hack
}
}
现在,如果其中一个 IFooComponent
缺少依赖项,或者 Castle Windsor 遇到异常在实例化 IFooComponent
时,异常被 Castle Windsor 捕获并且不会重新抛出。当我解析 IMainService
的注册实例时,一切看起来都很好,因为至少有一个可以创建的 IFooComponent
实例。
//No exception here because there is at least 1 IFooComponent
var plugin = _container.Resolve<IMainService>();
我该如何处理这个错误并关闭一切?我本以为内核上会有一个事件,但没有看来不是。
我的修复:
我为 AwesomeMainService
创建了一个动态参数,用于计算注册的 IFooProcessor
数量。然后,AwesomeMainService
验证这是否与提供的 IFooProcessor
数量匹配。
public class AwesomeMainService : IMainService
{
public AwesomeMainService(IEnumerable<IFooComponent> fooComponents,
int expectedProcessorCount)
{
Verify.That(fooComponents.Count == expectedProcessorCount,
"requestProcessors does not match the expected number " +
"of processors provided");
}
}
然后我将其添加到 AwesomeMainService 注册中:
.DynamicParameters((kernel, parameters) =>
{
parameters["expectedProcessorCount"] =
container.Kernel.GetAssignableHandlers(typeof (object))
.Where(
h => h.ComponentModel.Service.UnderlyingSystemType ==
typeof (IRequestProcessor))
.Count();
}));
I have a component registered with Castle Windsor which depends on a list of components, each of which is represented by an interface. Castle Windsor is configured similar to the code below.
public class WindsorInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
//Allow the container to resolve all IFooComponent
//as IEnumerable<IFooComponent>
container.Kernel.Resolver
.AddSubResolver(new CollectionResolver(container.Kernel, false));
container.Register(
Component
.For<IMainService>()
.ImplementedBy<AwesomeMainService>());
container.Register(
Component.For<IFooComponent>()
.ImplementedBy<CoolFooComponent>()
.Named(typeof (CoolFooComponent).Name),
Component.For<IFooComponent>()
.ImplementedBy<FooComponentWithUnresolvedDependancy>()
.Named(typeof (FooComponentWithUnresolvedDependancy).Name)
//....
);
}
}
AwesomeMainService
depends on an IEnumerable<IFooComponent>
like below
public class AwesomeMainService : IMainService
{
public AwesomeMainService(IEnumerable<IFooComponent> fooComponents)
{
//I could count the fooComponents here but this is a hack
}
}
Now if one of the IFooComponent
s is missing a dependency, or Castle Windsor otherwise encounters an exception while instantiating an IFooComponent
, the exception is caught by Castle Windsor and not rethrown. When I resolve the registered instance of IMainService
everything appears fine because there is at least on instance of IFooComponent
which can be created.
//No exception here because there is at least 1 IFooComponent
var plugin = _container.Resolve<IMainService>();
How do I handle this error and shut everything down? I would've thought there would be an event on the Kernel, but there doesn't appear to be.
My Fix:
I created a dynamic parameter for AwesomeMainService
which counted the number of IFooProcessor
s registered. The AwesomeMainService
then verified that this matched the number of IFooProcessor
s provided.
public class AwesomeMainService : IMainService
{
public AwesomeMainService(IEnumerable<IFooComponent> fooComponents,
int expectedProcessorCount)
{
Verify.That(fooComponents.Count == expectedProcessorCount,
"requestProcessors does not match the expected number " +
"of processors provided");
}
}
Then I added this to the AwesomeMainService registration:
.DynamicParameters((kernel, parameters) =>
{
parameters["expectedProcessorCount"] =
container.Kernel.GetAssignableHandlers(typeof (object))
.Where(
h => h.ComponentModel.Service.UnderlyingSystemType ==
typeof (IRequestProcessor))
.Count();
}));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是 Windsor 2.5 及更早版本中的一个已知限制。这种情况在 Windsor 3 中会快速失败。
在 v3 中,还有一个新事件
EmptyCollectionResolving
,当组件依赖于IFoo
集合但没有IFoo
的组件时,会引发该事件。 code>IFoo 已在容器中注册。This is a known limitation in Windsor 2.5 and earlier. This scenario will fail-fast in Windsor 3.
In v3 there's also a new event
EmptyCollectionResolving
which is raised when a component depends on a collection ofIFoo
s but no component forIFoo
is registered in the container.