5

アプリケーションのレイヤーを表す複数のプロジェクトを持つソリューションがあります。例えば

ドメイン

データ

論理

WebUI

Castle Windsor コンテナーは Web レイヤーから参照され、これらの依存関係をレイヤーにカスケードします。例えば...

// In Domain
public interface IFooRepository
{
    void DoSomething();
} 

// In Data
public class FooRepository : IFooRepository
{
    public void DoSomething()
    {
        // Something is done
    }
}

// In Logic
public class MyThingManager
{
    private readonly IFooRepository fooRepository;

    public MyThingManager(IFooRepository fooRepository)
    {
        this.fooRepository = fooRepository;
    }

    public void AMethod()
    {
        this.fooRepository.DoSomething();
    }

}

// In Web
// in some controller....
var newManager = new MyThingManager(WindsorContainer.Resolve<IFooRepository>());
newManager.DoSomething();

これは、マネージャーが独自の依存関係を持つ多くのメンバーを持つまでうまく機能します。これが発生すると、マネージャーの依存関係とその依存関係の両方を解決し、Web レイヤーからそれらをカスケードすることになります。この結果は、いくつかのかなり大きなコンストラクタです。

たとえば、マネージャーの内部コンポーネントがコンテナーにアクセスせずに独自の依存関係を解決するなど、より洗練された方法はありますか?

Web レイヤーのみがコンテナーにアクセスできることに注意してください (循環プロジェクトの依存関係を防ぐため)。したがって、アクティブに WindsorContainer.Resolve() できるのは Web レイヤーのみであり、ロジック レイヤーはできないため、依存関係をカスケードする唯一の方法は、コンテナーの支援は、Web レイヤーでそれを解決し、そのインターフェイスを使用してチェーンに渡すことでした。

4

1 に答える 1

6

.Resolve<T>短い答えは、あなたがおそらく間違ったことをしているのを見るときはいつでも、ということです。@Stevenが述べたように、Windsorの組み込み機能を使用して、コンストラクター注入(および/またはプロパティ注入)を提供したいと考えています。これはWindsorContainer、オブジェクト グラフのルートにあるオブジェクトを知る必要があることを意味します。

あなたの場合、MyThingyManagerルート オブジェクトに到達するまで、(から) オブジェクトのツリーを上っていきます。たとえば、ASP.NET MVC アプリでは、呼び出されるアクションを含むコントローラーになります。MVC3 の場合、DependencyResolverを使用して、すべての依存関係の注入を開始します。

さらに、私が過去に Windsor で便利だと思ったのは、コンポーネント (アセンブリ) ごとに異なるインストーラーを持つことです。そして、これらのインストーラーを、アプリケーションをホストしているプロセスのベースに登録します。

したがって、各コンポーネントには、次のようなインストーラーがあります。

public class Installer : IWindsorInstaller
{
        public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
        {
            container.Register(
                Component.For<IMyThingManager>().ImplementedBy<MyThingManager>(),
                Component.For<IFooRepository>().ImplementedBy<FooRepository>()
                );
        }
}

そして、Global.asax.cs Application_Start には次のようなものがあります。

var container = new WindsorContainer();
container.Install(FromAssembly.This());
container.Install(FromAssembly.Containing(typeof(ComponentThatContains.MyThingManager.Installer)));

これにより、オブジェクト グラフ全体のすべての依存関係を管理し、コンストラクター インジェクションによって解決する方法が得られます。お役に立てれば。

于 2012-04-11T11:48:11.890 に答える