Windsor Container:如何指定公共财产不应该被容器填充?

问题描述 投票:12回答:7

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

我怎样才能明确告诉温莎城堡它不应该试图满足公共财产?我假设必须有一个属性到那个程度。我无法找到它,请告诉我相应的命名空间/程序集。

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

inversion-of-control castle-windsor property-injection
7个回答
11
投票

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

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

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

可能对您有用的另一种方法是在请求任何服务实例之前手动删除模型中的依赖项,即。

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

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


3
投票

我创建了一个设施来帮助解决这个问题:


2
投票

我不知道你们当时使用的是哪个版本的城堡,但所提到的解决方案都没有奏效。此外,还有很多死链接。

使用城堡3.1,这里是我提出的解决方案(感谢一些城堡源代码挖掘):

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

'Properties'函数在构造ComponentModel时添加了castle使用的属性过滤器。在我的例子中,除了属性类型'MyOtherType'之外,将满足所有属性依赖性。



1
投票

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

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

1
投票

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

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);

来源Castle Windsor Documentation


© www.soinside.com 2019 - 2024. All rights reserved.