3

キーの有無にかかわらず登録できるインターフェイスINavigationServiceとシンプルなコンテナーがあります。

フレームワークが登録されたインスタンスをビューモデルのコンストラクターに挿入するので、これは私にとって便利です。

現在、複数のナビゲーション サービスがあります (UI のフレームのため)。これらはすべて同じ基本インターフェースを実装しています ( INavigationService)。

パラメータ (DI 登録キー) を渡さなくても、コンテナがこれらのインスタンスを正しいナビゲーション ツリー (フレーム + 後続のビュー/ビュー モデル) に挿入できるようにしたいと考えています。

これは通常どのように行われますか?

属性ベースのものを想像できます (したがって、すべての依存クラス定義に登録キーを配置します)。しかし、コンテナはこれをサポートしていません。面倒でもあるようです。

タグ付け専用のインターフェースを作成することもできます。したがってINavigationService<T>、各ナビゲーション サービスを異なる型引数で登録します。たとえば、フレームの最初のビューのタイプ。これにより、必要な解決策が得られますが、意味のないインターフェイスは渡されます。

一方、依存ビューを見つけるためのIDEサポートを取得します(たとえば、次のようなタイプを作成することにより)FileTreeNavigation : INavigationService<FileTreeView>

別のパターンはありますか?

4

1 に答える 1

1

これが Caliburn Micro にどのように当てはまるかはわかりませんが、質問はパターンに関するものなので、StrucureMapでこの問題を解決する方法をここで説明します:Ctor<>コンストラクターのパラメーター解決に具体的な型を指定できる方法を使用します。

また、特殊なインターフェース(あなたのFileTreeNavigation例)を使用することは素晴らしいと思いますが、何らかの理由でこれが適切でないと思う場合は、読み進めてください.

INavigationServiceインターフェイスと 2 つの異なる実装があるとします。

public interface INavigationService { }
public class NavigationServiceA : INavigationService { }
public class NavigationServiceB : INavigationService { }

次に、INavigationServiceインターフェイスに応じて、2 つの異なる Service クラスがあります。

public class ServiceA
{
    private readonly INavigationService _navigationService;

    public ServiceA(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }
}

public class ServiceB
{
    private readonly INavigationService _navigationService;

    public ServiceB(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }
}

最後に、IoC コンテナーを使用して解決するクラスがあります。ServiceAこのクラスは、 と の両方に依存し、ServiceB次のように定義されます。

public class SomeClassToResolve
{
    private readonly ServiceA _serviceA;
    private readonly ServiceB _serviceB;

    public SomeClassToResolve(ServiceA serviceA, ServiceB serviceB)
    {
        _serviceA = serviceA;
        _serviceB = serviceB;
    }
}

StructureMap は、コンストラクターのパラメーターを解決するために使用する型を指定する可能性を提供します。登録はこんな感じです。

ForConcreteType<ServiceA>().Configure.Ctor<INavigationService>().Is<NavigationServiceA>();
ForConcreteType<ServiceB>().Configure.Ctor<INavigationService>().Is<NavigationServiceB>();

ここで、呼び出すcontainer.GetInstance<SomeClassToResolve>();と、 のインスタンスが構築されます。これには、とのSomeClassToResolveインスタンスが正しく構築されています (それぞれとがあります)。ServiceAServiceBNavigationServiceANavigationServiceB

これはそれを行う1つの方法であり、より簡単であることがわかりました。Conditional Constructionを実行する可能性もありますが、かなり複雑になる可能性があると思います。

PS:「caliburn micro constructor」を検索すると、StructureMapで行っていることに似ているこのアプローチInjectionConstructorに出くわしました(ここでは と呼ばれているだけです)。

于 2012-10-14T11:48:10.177 に答える