虽然我更喜欢构造函数注入,但我希望我的团队中的开发人员能够使用属性注入,只要他们使用属性显式地将属性标记为可注入即可。根据 CastleWindsor 文档here,这应该可以通过创建一个贡献者然后通过内核调用 AddContributor 来实现。我似乎无法让它发挥作用。所有公共属性(甚至那些没有该属性的属性)都会被注入。
当我在贡献者 ProcessModel 方法中设置断点时,它将所有具有该属性的属性设置为强制(IsOptional = false),并跳过任何不具有该属性的属性。但尽管如此,没有该属性的属性仍然会被注入。我做错了什么?
下面是我的代码:
贡献者
public class PropertyInjectionContributor : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
model.Properties
.Where(p => p.Property.IsDefined(typeof(InjectedAttribute)))
.All(p => p.Dependency.IsOptional = false);
}
}
属性
[AttributeUsage(AttributeTargets.Property)]
public class InjectedAttribute : Attribute { }
将贡献者添加到 Kernel.ComponentModelBuilder 并注册组件
public class Program
{
public static void Main(string[] args)
{
var container = new WindsorContainer();
container.Kernel.ComponentModelBuilder.AddContributor(new PropertyInjectionContributor());
container.Register(Component.For<IClass1>()
.ImplementedBy<Class1>()
.LifestyleTransient());
container.Register(Component.For<IClass2>()
.ImplementedBy<Class2>()
.LifestyleTransient());
var class1 = container.Resolve<IClass1>();
class1.DoSomething();
}
}
1班
public class Class1 : IClass1
{
//[Injected]
public IClass2 Class2 { get; set; }
public void DoSomething()
{
Class2.DoSomething();
}
}
即使未使用 Injected 属性修饰,Class1 中的 Class2 属性也会被注入。
我当前的解决方法是删除 CastleWindsor 的 PropertiesDependencyModelInspector 并将其替换为强制 IsOptional 为 false 的实现。它可以工作,但它重复了很多 CW 的代码。如果我只能让它发挥作用,我更愿意使用上面的简单方法!
仅当属性具有该属性时才设置 IsOptional。如果没有该属性,您就不会为属性执行任何操作。对于所有您不想注入的属性,您需要将它们标记为“不可注入”。有一个属性已经做到了这一点:[DoNotWire]。