ウィンザーで循環依存関係が必要です。これは、再帰的なアプローチのために意図的に行われます。モジュール A はモジュール BF を呼び出し、モジュール B はノードのツリーのためにモジュール A にコールバックする必要があります。
とにかく、このためコンストラクター注入を使用できないことはわかっています。そこで、IEnumerable<IModule> を取得するために、プロパティ インジェクションを使用してモジュール A をセットアップしました。
すべてのタイプを登録しましたが、モジュール A を解決するときに、Windsor がプロパティを 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 を使用してインスタンスを作成します。名前を付けます。
Windsor は、列挙可能な IModules であるプロパティを満たします。
CompositeModule を数えずに 6 つの IModule を認識し、それらをコレクションにインスタンス化しようとします。
6 つのモジュールの 1 つである CheckChildrenModule には、CompositeModule の名前付きインスタンスが必要であることがわかります。
手順 1 で作成された CompositeModule の名前付きインスタンスを使用して、CheckChildrenModule の ctor 依存関係を満たします。
これで IModules のコレクションを終了し、手順 2 から CompositeModule の InnerModules プロパティに渡すことができます。
それを実現する方法がわからないだけです。