Windsor容器:如何指定一个公共属性不应该被容器填充?

发布于 2024-07-07 22:59:03 字数 271 浏览 12 评论 0 原文

当实例化一个类时,Windsor 默认将该类的所有公共属性视为可选依赖项,并尝试满足它们。 就我而言,这会创建一个相当复杂的循环依赖关系,导致我的应用程序挂起。

我如何明确告诉温莎城堡它不应该试图满足公共财产的要求? 我认为一定有一个到这个程度的属性。 但是我找不到它,所以请让我知道适当的命名空间/程序集。

如果有任何方法可以在没有属性(例如 Xml 配置或通过代码配置)的情况下执行此操作,那将是更好的选择,因为发生这种情况的特定库迄今为止不需要对 castle 的依赖。

When Instantiating a class, Windsor by default treats all public properties of the class as optional dependencies and tries to satisfy them. In my case, this creates a rather complicated circular dependency which causes my application to hang.

How can I explicitly tell Castle Windsor that it should not be trying to satisfy a public property? I assume there must be an attribute to that extent. I can't find it however so please let me know the appropriate namespace/assembly.

If there is any way to do this without attributes (such as Xml Configuration or configuration via code) that would be preferable since the specific library where this is happening has to date not needed a dependency on castle.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(7

脸赞 2024-07-14 22:59:03

您可以使用 Castle.Core。 DoNotWireAttribute 属性用于阻止 IoC 容器连接属性(这是在 Castle.Core 程序集中,这意味着您的库只需要依赖于轻量级 Castle.Core 程序集 - 例如,如果您想要使用完全没有控制反转容器的代码,或者在不同的 IoC 容器中)。

我不相信有任何方法可以防止在 Xml 配置中发生连接,但是添加对此的支持相当容易 - 如果我必须这样做,我可能会:

  1. 在属性声明中引入某种属性xml:
  2. 继承自 PropertiesDependencyModelInspector,重写 InspectProperties 方法以应用一些附加逻辑来识别哪些属性应作为依赖项添加到组件模型(检查 model.Configuration 中的wire="false" 属性/值对)。
  3. 继承 DefaultComponentModelBuilder 和覆盖 InitializeContributors 以包含替换的 PropertiesDependencyModelInspector - 或者仅删除现有的属性贡献者并在运行时通过 AddContributor/ 添加您自己的属性>RemoveContributor 方法。
  4. 替换分配给容器内核的 ComponentModelBuilder 服务实例。

另一种适合您的方法是在请求任何服务实例之前手动从模型中删除依赖项。

kernel.GetHandler(typeof(MyComponent)).ComponentModel.Dependencies.RemoveAll(d => d.DependencyKey == "PropertyThatShouldNotBeWired");

YMMV 使用这种方法 - 特别是如果您有可启动的服务或其他设施,它们可能会在注册后急切地实例化您的组件。

You can use the Castle.Core.DoNotWireAttribute attribute to stop a property from being wired up by the IoC container (this is in the Castle.Core assembly, which means your library only needs to take a dependency on the lightweight Castle.Core assembly - if for example you want to use the code without an inversion of control container altogether, or in a different IoC container).

I don't believe there's any way to prevent wiring from occurring in the Xml configuration, but it would be reasonably easy to add support for this - if I had to do this I would probably:

  1. Introduce some kind of attribute on the property declaration in the xml: <myprop wire="false" />
  2. Inherit from PropertiesDependenciesModelInspector, overriding the InspectProperties method to apply some additional logic to identifying which properties should be added as dependencies to the components model (inspecting the model.Configuration for the wire="false" attribute/value pair).
  3. Inherit from DefaultComponentModelBuilder and override the InitializeContributors to include your replacement PropertiesDependenciesModelInspector - or just remove the existing properties contributor and add your own at run time via the AddContributor/RemoveContributor methods.
  4. Replace the ComponentModelBuilder service instance assigned to the kernel of your container.

Another approach which could work for you is to just manually remove the dependencies from the model before any instances of the service are requested ie.

kernel.GetHandler(typeof(MyComponent)).ComponentModel.Dependencies.RemoveAll(d => d.DependencyKey == "PropertyThatShouldNotBeWired");

YMMV with that approach though - especially if you have startable services or other facilities which may be eagerly instantiating your component after it's registered.

画离情绘悲伤 2024-07-14 22:59:03

我创建了一个工具来帮助解决此问题:

I created a facility to help with this:

樱娆 2024-07-14 22:59:03

我不知道你们当时使用的是哪个版本的 Castle,但是提到的解决方案都不起作用。 另外,还有很多死链接。

在 castle 3.1 中,我提出了解决方案(感谢一些 castle 源代码挖掘):

container.Register(Component.For(type)
                                        .LifestyleTransient()
                                        .Properties( propertyInfo => propertyInfo.PropertyType != typeof(MyOtherType)));

“Properties”函数添加了 castle 在构建 ComponentModel 时使用的属性过滤器。 就我而言,除了属性类型“MyOtherType”之外,所有属性依赖性都将得到满足。

I do not know which version of Castle you guys were using at that time, but none of the solution mentioned were working. Plus, there is a lot of dead links.

With castle 3.1, here the solution I came up with (thanks to some castle source code digging):

container.Register(Component.For(type)
                                        .LifestyleTransient()
                                        .Properties( propertyInfo => propertyInfo.PropertyType != typeof(MyOtherType)));

The 'Properties' function adds a property filter used by castle when constructing the ComponentModel. In my case, all properties dependency will be satisfied except the property type 'MyOtherType'.

安穩 2024-07-14 22:59:03

也许这会对某人有帮助。 在Windsor 4.1中,注册时有PropertiesIgnore方法。

Component.For<Role>().LifestyleTransient().PropertiesIgnore((model, propertyInfo) => true)

Maybe it will be helpful for someone. In Windsor 4.1 there is PropertiesIgnore method during registration.

Component.For<Role>().LifestyleTransient().PropertiesIgnore((model, propertyInfo) => true)
她比我温柔 2024-07-14 22:59:03

这可以通过以下代码来实现:

var container = new WindsorContainer();

// We don't want to inject properties, only ctors
var propInjector = container.Kernel.ComponentModelBuilder
                         .Contributors
                         .OfType<PropertiesDependenciesModelInspector>()
                         .Single();
container.Kernel.ComponentModelBuilder.RemoveContributor(propInjector);

Source 温莎城堡文档

This can be achieved by the following code:

var container = new WindsorContainer();

// We don't want to inject properties, only ctors
var propInjector = container.Kernel.ComponentModelBuilder
                         .Contributors
                         .OfType<PropertiesDependenciesModelInspector>()
                         .Single();
container.Kernel.ComponentModelBuilder.RemoveContributor(propInjector);

Source Castle Windsor Documentation

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