【发布时间】:2014-07-23 15:06:04
【问题描述】:
我需要 Windsor 中的循环依赖。这是为了递归方法而设计的。模块 A 调用模块 B-F 并且模块 B 需要回调到 A 因为节点树。
无论如何,我知道我不能因此使用构造函数注入。所以我设置了带有属性注入的模块 A 以获得 IEnumerable
我已经注册了所有类型,但是在解析模块 A 时,Windsor 将属性设置为 Null(我让它抛出异常)。我尝试使用 DependsOn,但这似乎只适用于构造函数参数。
如何让 Windsor 通过属性注入将我的模块 B-F 集合解析为模块 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 代码,因为我正在为第 3 方工具注册这些组件。
谢谢!
编辑
我的期望:
Windsor 解析 CompositeModule 并使用默认 ctor 创建一个实例。给它命名。
Windsor 去满足属性,这是 IModules 的可枚举
它看到 6 个 IModule,不包括 CompositeModule,并尝试将它们实例化为一个集合
它看到 6 个模块之一 CheckChildrenModule 需要 CompositeModule 的命名实例。
它使用步骤 1 中创建的 CompositeModule 的命名实例来满足对 CheckChildrenModule 的 ctor 依赖
现在它可以完成 IModule 的收集,并将它们从第 2 步传递到 CompositeModule 的 InnerModules 属性中。
只是不知道如何让它发生。
【问题讨论】:
-
IModule有InnerModules属性吗? -
没有。 InnerModules 特定于复合模块实现。并非所有模块都具有此层次结构。我将进行编辑以明确这一点。
-
There 你去。
-
对不起。 “你去吧”是什么意思?
-
哦。我没注意到这是一个链接!
标签: c# recursion dependency-injection castle-windsor property-injection