通过温莎城堡解决父母/孩子的问题
我不确定调用这个父/子,但是在这里,我有一个类似的情况,如下所示:
namespace ConsoleApplication1
{
using System.Diagnostics;
using System.Linq;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.Resolvers.SpecializedResolvers;
using Castle.Windsor;
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(
Component.For<Parent>().LifeStyle.Singleton,
Component.For<IChild>().ImplementedBy<Child1>().LifeStyle.Singleton);
var p = container.Resolve<Parent>();
// Fails...
Debug.Assert(p.Children.First().Parent == p, "Parent should be resolved");
}
}
class Parent
{
public IChild[] Children { get; set; }
}
interface IChild
{
Parent Parent { get; set; }
}
class Child1 : IChild
{
public Parent Parent { get; set; }
}
}
我已将 CollectionResolver 添加到容器中。 Parent 和 Child1(使用 IChild 服务)都在容器中注册为单例。每当我尝试解析 Parent 实例时,我都会填充 Children 数组,但该数组中的 Child1 实例的 Parent 为 null。我期望将 Child1 的 Parent 属性设置为我当时试图解析的 Parent 实例。我可以理解 Parent 尚未完全激活,但由于其 ctor 已运行,Windsor 还不能注入此属性吗?有什么方法可以完成这项工作,或者我应该手动运行一些代码来设置子对象的父对象(这远非理想)?
提前致谢!
I am not sure calling this parent/child but here you go, I have a similar case like this:
namespace ConsoleApplication1
{
using System.Diagnostics;
using System.Linq;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.Resolvers.SpecializedResolvers;
using Castle.Windsor;
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(
Component.For<Parent>().LifeStyle.Singleton,
Component.For<IChild>().ImplementedBy<Child1>().LifeStyle.Singleton);
var p = container.Resolve<Parent>();
// Fails...
Debug.Assert(p.Children.First().Parent == p, "Parent should be resolved");
}
}
class Parent
{
public IChild[] Children { get; set; }
}
interface IChild
{
Parent Parent { get; set; }
}
class Child1 : IChild
{
public Parent Parent { get; set; }
}
}
I have CollectionResolver added to the container. Both Parent and Child1 (with IChild service) are registered as singletons in the container. Whenever I try to resolve the Parent instance, I got my Children array populated but the Child1 instance in that array has a Parent of null. What I am expecting is the Parent property of the Child1 to be set to the Parent instance I am trying to resolve at that moment. I can understand that Parent is not fully activated yet, but since its ctor is run, can't Windsor inject this property yet? Are there any way to make this work or should I manually run some code to set Parents of child objects (which is far from ideal)?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Windsor 不会让你创建循环依赖链。如果您更改子级和父级定义,以便它们使用构造函数注入而不是属性注入,如下所示:
当您现在运行测试时,您将看到 Windsor 抱怨依赖循环:
当您有必需的依赖项时,使用构造函数注入总是更好。使用属性注入告诉 Windsor 该依赖项是可选的:如果可以,请提供组件,否则只需将属性保留为 null。在这种情况下,子级首先被解析,因此当创建父级依赖项时,Windsor 发现会产生循环并将其保留为空。
这里的解决方案是在解析子级时填充父级,方法是将一些代码放入父级构造函数中。
Windsor won't let you create a cyclic dependency chain. If you change your child and parent definitions so that they use constructor injection rather than property injection as follows:
When you run your test now, you'll see that Windsor complains about a dependency cycle:
It's always better to use constructor injection when you have a required dependency. Using property injection tells Windsor that the dependency is optional: Supply the component if you can, otherwise just leave the property null. In this case the children were resolved first, so when it came to create the Parent dependency Windsor saw that a cycle would result and left it null.
The solution here is to populate the Parent when the children are resolved, by putting some code in the Parent constructor.
实际上,可以在不调用其构造函数的情况下创建对象。它的所有字段都将为空,但您将拥有对对象的引用。此功能在 Windsor 中未实现,需要此功能的东西可能是设计味道。
Actually it is possible to create an object without invoking its constructor. All of its fields will be null, but you'll have a reference to object. This feature is not implemented in Windsor, and something that requires this is likely to be a design smell.
这是一个更好一点的变体:)
This is a variation that's a bit nicer :)