防止重复注册 - Castle Windsor

4

抱歉如果这个问题以前已经被问过,我试着做了一些谷歌搜索但没有找到任何匹配的结果,所以现在来问一下....

我有一个Castle Windsor容器,我使用以下方法将我的组件添加到其中(其中container是IWindsorContainer的实例)...

container.Register(AllTypes.FromAssemblyNamed("App.Infrastructure")
    .Where(x => !x.IsAbstract && !x.IsInterface)
    .WithService.DefaultInterface()

这很有用,但我想以同样的方式注册另一个DLL来解决那个DLL的依赖关系问题...

container.Register(AllTypes.FromAssemblyNamed("App.Client.Infrastructure")
    .Where(x => !x.IsAbstract && !x.IsInterface)
    .WithService.DefaultInterface()

现在有没有办法让Windsor通知我是否正在添加相同的接口分辨率,即:每个接口只有一个实现者(如果存在多个,则取第一个)。
希望我已经解释清楚了。我正在使用Castle Windsor版本:2.5.1.0,升级/更改版本并不是一个真正的选项。
更新:
我通过在注册后删除重复的注册来解决了这个问题。 注册完成后,我有一个循环...
var registeredServices = new Dictionary<Type, string>();
foreach (var node in container.Kernel.GraphNodes)
{
    var cmp = ((Castle.Core.ComponentModel)node);
    Type t = cmp.Service;
    if (registeredServices.ContainsKey(t))
        container.Kernel.RemoveComponent(cmp.Name);
    else
        registeredServices.Add(t, cmp.Implementation.FullName);
}

应该是默认行为,首次注册应该被解决。 - maxlego
嗨@maxlego。我不明白你的意思,你能否详细说明一下? - Sam Lad
1
如果您使用相同接口注册多个组件,则当您通过此接口解析时,将获取第一个注册的组件。我理解这就是您想要的。难道不是吗? - maxlego
谢谢@maxlego,我希望它能抛出异常或类似的东西,因为我们只想要一个已注册的组件每个接口,如果我在我的问题中没有表达清楚,对不起。 - Sam Lad
2个回答

6

我不知道是否可以调整注册器来抛出异常,但这个简单的代码片段可能会对你有帮助。

var registeredServices = new List<Type>();

foreach (var node in container.Kernel.GraphNodes)
{
    foreach (var t in ((Castle.Core.ComponentModel)node).Services)
    {
        if (registeredServices.Contains(t))
            throw new Exception(string.Format("service {0} already registered", t));
        registeredServices.Add(t);
    }
}

4
在2.5版本中,您可以在注册所有内容后调用以下命令。
var allHandlers = container.Kernel.GetAssingableHandlers(typeof(object));

然后,您可以查看每个处理程序的.Service并查找是否存在任何重复项,并且可以抛出有用的异常或类似的东西。

我想这是您想在测试中执行的操作,而不是在运行时执行。


谢谢Krzysztof,这正是我想要进行检查的位置。我们有一个单元测试寻找重复注册,但它失败了,我希望能够检测到正在重复的内容。谢谢大家,我会尝试你们两个的解决方案并报告我的发现! - Sam Lad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接