[英]Cyclic dependency via property injection in Castle Windsor
我在温莎需要一个周期性的依赖。 这是为了递归方法。 模块A调用由于节点树,模块BF和模块B需要回调回A。
无论如何,因此我知道我不能使用构造函数注入。 因此,我使用属性注入设置了模块A,以获得IEnumerable <IModule>。
我已经注册了所有类型,但是在解析模块A时,温莎将属性设置为Null(我抛出了异常)。 我尝试使用DependsOn,但这似乎仅适用于构造函数参数。
如何通过属性注入使Windsor将我的模块BF集合解析为模块A,以便获得所需的依赖周期?
这是顶层模块(模块A)和IModule;
public interface IModule
{
bool IsAccessibleToUser(INode node);
}
public class CompositeModule:IModule
{
private IEnumerable<IModule> innerModules;
public IEnumerable<IModule> InnerModules
{
get { return innerModules; }
set {
if (null == innerModules) throw new ArgumentNullException("innerModules");
innerModules = value;
}
}
public CompositeModule()
{
InnerModules = new List<IModule>();
}
public bool IsAccessibleToUser(INode node)
{
return innerModules.All(module => module.IsAccessibleToUser(node));
}
}
和递归子模块:
public class CheckChildrenModule : IModule
{
private IModule compositeModule;
public CheckChildrenModule(IModule compositeModule)
{
if (null == compositeModule) throw new ArgumentNullException("compositeModule");
this.compositeModule = compositeModule;
}
public bool IsAccessibleToUser(INode node)
{
var attributes = node.Attributes;
if (!attributes.ContainsKey("checkchildren")) return true;
string checkchildren = attributes["checkchildren"].ToString();
if (checkchildren.ToLower() == bool.TrueString.ToLower())
{
//look for any child with result of TRUE and stop immediately if found in order to be efficient.
return node.ChildNodes.Any(childNode => compositeModule.IsAccessibleToUser(childNode));
}
return true; //check false or some other value. return true!
}
}
而我的注册:
// Configure Windsor to resolve arrays in constructors
container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel, true));
//collections too
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
//other stuff here
container.Register(Component.For<IModule>()
.ImplementedBy<CompositeModule>()
.Named("CompositeModule1"));
container.Register(Component.For<IModule>().ImplementedBy<CheckChildrenModule>()
.DependsOn(ServiceOverride.ForKey<IModule>().Eq("CompositeModule1")));
//A few other IModules here, all of which should be passed to the Composite Module "innerModules" property.
正如我所说,我尝试了DependsOn(似乎不适用于属性)以及PropertyRequire(没有效果),但仍然传递了null。
请注意,由于我正在为第三方工具注册这些组件,因此我无权访问Container.Resolve代码。
谢谢!
编辑
我的期望:
Windsor解析CompositeModule并使用默认ctor创建实例。 命名。
温莎去满足该属性,这是IModules的一个枚举
它看到6个IModule,不计算CompositeModule,并尝试将它们实例化为一个集合
它可以看到6个模块之一CheckChildrenModule需要CompositeModule的命名实例。
它使用在步骤1中创建的CompositeModule的命名实例来满足CheckChildrenModule的ctor依赖性
现在,它可以完成IModules的收集并将它们传递到步骤2中的CompositeModule的InnerModules属性中。
只是不知道如何使它发生。
我相信您可以在构造函数注入中使用惰性解析来实现循环依赖。
container.Register(Component.For<ILazyComponentLoader>()
.ImplementedBy<LazyOfTComponentLoader>());
public class CompositeModule : ICompositeModule
{
private IEnumerable<IModule> _childModules;
public CompositeModule(IEnumerable<IModule> childModules)
{
_childModules = childModules;
}
}
public class CheckChildrenModule : IModule
{
private Lazy<ICompositeModule> _compositeModule;
public CheckChildrenModule(Lazy<ICompositeModule> compositeModule)
{
_compositeModule = compositeModule;
}
public void DoStuff()
{
_compositeModule.Value.DoStuff();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.