2

ウィンザーで循環依存関係が必要です。これは、再帰的なアプローチのために意図的に行われます。モジュール 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 コードにアクセスできないことに注意してください。

ありがとう!

編集

私が期待するもの:

  1. Windsor は CompositeModule を解決し、デフォルトの ctor を使用してインスタンスを作成します。名前を付けます。

  2. Windsor は、列挙可能な IModules であるプロパティを満たします。

  3. CompositeModule を数えずに 6 つの IModule を認識し、それらをコレクションにインスタンス化しようとします。

  4. 6 つのモジュールの 1 つである CheckChildrenModule には、CompositeModule の名前付きインスタンスが必要であることがわかります。

  5. 手順 1 で作成された CompositeModule の名前付きインスタンスを使用して、CheckChildrenModule の ctor 依存関係を満たします。

  6. これで IModules のコレクションを終了し、手順 2 から CompositeModule の InnerModules プロパティに渡すことができます。

それを実現する方法がわからないだけです。

4

1 に答える 1

4

コンストラクター注入で遅延解決を使用して、循環依存関係を実現できると思います。

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();
    }
}
于 2014-07-24T02:28:16.787 に答える