在创建组件期间如何配置 Castle Windsor 错误处理?

发布于 2024-12-17 01:29:45 字数 2931 浏览 0 评论 0原文

我有一个在温莎城堡注册的组件,它依赖于组件列表,每个组件都由一个接口表示。 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 IFooComponents 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 IFooProcessors registered. The AwesomeMainService then verified that this matched the number of IFooProcessors 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疯狂的代价 2024-12-24 01:29:45

这是 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 of IFoos but no component for IFoo is registered in the container.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文