9

更新: Windsor 以外の IoC フレームワークで私がやろうとしていることを達成する方法はありますか? Windsor はコントローラーを適切に処理しますが、それ以外は解決しません。私はそれが私のせいだと確信していますが、私はチュートリアルを逐語的に従っており、オブジェクトは ctor インジェクションで解決されていません。登録と解決を行っているにもかかわらず、オブジェクトはまだ null です。プロジェクトは時間に敏感であるため、DIコードを破棄し、今のところ手動で挿入しています。締め切りまでにDIを完成させたい。


すべてが同じインターフェイスを実装する複数のクラスを持つソリューションがあります

簡単な例として、Interface

public interface IMyInterface {
    string GetString();
    int GetInt();
   ...
}

具体的なクラス

public class MyClassOne : IMyInterface {
    public string GetString() {
        ....
    }
    public int GetInt() {
        ....
    }
}

public class MyClassTwo : IMyInterface {
    public string GetString() {
        ....
    }
    public int GetInt() {
        ....
    }
}

これらのクラスは、次のように、必要に応じてその上のレイヤーに挿入されます。

public class HomeController {

    private readonly IMyInterface myInterface;

    public HomeController() {}

    public HomeController(IMyInterface _myInterface) {
        myInterface = _myInterface
    }
    ...
}

public class OtherController {

    private readonly IMyInterface myInterface;

    public OtherController() {}

    public OtherController(IMyInterface _myInterface) {
        myInterface = _myInterface
    }
    ...
}

両方のコントローラーに同じインターフェースが挿入されています。

これらのインターフェイスを IoC の適切な具象クラスで解決する場合、 のインスタンスが必要な場合とHomeControllerのインスタンスが必要な場合をどのように区別すればよいでしょうか?MyClassOneOtherControllerMyClassTwo

IoC で 2 つの異なる具象クラスを同じインターフェイスにバインドするにはどうすればよいですか? DRYルールに違反し、とにかく意味がないため、2つの異なるインターフェイスを作成したくありません。

Castle Windsor では、次のような 2 つの行があります。

container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>());
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>());

MyClassTwoインターフェイスに登録された最後のコピーであるため、コピーしか取得できないため、これは機能しません。

私が言ったように、具象ごとに特定のインターフェイスを作成せずにそれを行う方法がわかりません。それを行うと、DRY ルールだけでなく基本的な OOP も破られます。どうすればこれを達成できますか?


Mark Polsen の回答に基づく更新


これが私の現在の IoC.Resolveです。ステートメントはどこに行きますか? ウィンザーのドキュメントには何も表示されません

public class Dependency : IDependency {

    private readonly WindsorContainer container = new WindsorContainer();

    private IDependency() {
    }

    public IDependency AddWeb() {
        ...

        container.Register(Component.For<IListItemRepository>().ImplementedBy<ProgramTypeRepository>().Named("ProgramTypeList"));
        container.Register(Component.For<IListItemRepository>().ImplementedBy<IndexTypeRepository>().Named("IndexTypeList"));

        return this;
    }

    public static IDependency Start() {
        return new IDependency();
    }
}
4

3 に答える 3

7

サービスのオーバーライドを使用できることを願っています。

元。

container.Register(
    Component.For<IMyService>()
        .ImplementedBy<MyServiceImpl>()
        .Named("myservice.default"),
    Component.For<IMyService>()
        .ImplementedBy<OtherServiceImpl>()
        .Named("myservice.alternative"),

    Component.For<ProductController>()
        .ServiceOverrides(ServiceOverride.ForKey("myService").Eq("myservice.alternative"))
);

public class ProductController
{
    // Will get a OtherServiceImpl for myService.
    // MyServiceImpl would be given without the service override.
    public ProductController(IMyService myService)
    {
    }
}
于 2012-06-11T16:00:49.710 に答える
5

名前付きコンポーネントの登録でそれを達成できるはずです。

container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>().Named("One"));
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>().Named("Two"));

そして、それらを解決します

kernel.Resolve<IMyInterface>("One");

また

kernel.Resolve<IMyInterface>("Two");

参照: コンポーネントの名前を指定するには

于 2012-06-11T16:01:38.000 に答える