gpt4 book ai didi

c# - 在 CaSTLe Windsor 中通过属性注入(inject)实现循环依赖

转载 作者:行者123 更新时间:2023-11-30 20:48:14 27 4
gpt4 key购买 nike

我需要 Windsor 中的循环依赖。这是为了递归方法而设计的。模块 A 调用模块 B-F,模块 B 需要回调 A,因为节点树。

无论如何,我知道我不能因此而使用构造函数注入(inject)。因此,我使用属性注入(inject)设置模块 A 以获得 IEnumerable

我已经注册了所有类型,但是在解析模块 A 时,Windsor 将属性设置为 Null(我让它抛出异常)。我尝试使用 DependsOn,但这似乎只适用于构造函数参数。

如何让 Windsor 通过属性注入(inject)将我的模块 B-F 集合解析为模块 A,以便我可以获得所需的依赖周期?

这里是顶层模块(Module 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 方工具注册这些组件。

谢谢!

编辑

我的期望:

  1. Windsor 解析 CompositeModule 并使用默认构造函数创建一个实例。给它命名。

  2. Windsor 去满足属性,这是一个可枚举的 IModules

  3. 它看到 6 个 IModule,不包括 CompositeModule,并尝试将它们实例化到一个集合中

  4. 它看到 6 个模块之一 CheckChildrenModule 需要 CompositeModule 的命名实例。

  5. 它使用在步骤 1 中创建的 CompositeModule 的命名实例来满足对 CheckChildrenModule 的 ctor 依赖

  6. 现在它可以完成 IModules 的收集并将它们传递到 CompositeModule 的 InnerModules 属性中,从第 2 步开始。

只是不知道如何让它发生。

最佳答案

我相信您可以使用延迟解析和构造函数注入(inject)来实现循环依赖。

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

关于c# - 在 CaSTLe Windsor 中通过属性注入(inject)实现循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24914165/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com