1

SimpleInjectorをIoCコンテナとして使用しています。パブリッシュ/サブスクライブフレームワークを作成しました。サブスクライバーが実行の優先順位を指定できるようにすることで、このフレームワークを改良できるようにする必要があります。たとえば、トランザクションの残りの部分に必要なすべてのデータをプリロードするためのサブスクライバーを作成できます。

私が考えることができる1つの方法は[SubscriberPriority]、登録プロセス中に要件を示す属性を作成することですRegisterManyForOpenGenericが、まだ深く掘り下げていません。

GetAllInstances登録を返す注文を管理する方法はありますか?

アップデート:

私が今考えたもう1つのオプションは、CoC(設定より規約)を使用して、によって返されるインスタンスを注文することGetAllInstancesです。

4

1 に答える 1

1

を使用していることを示しているため、次のように、コールバック デリゲートを受け取るオーバーロードをGetAllInstances使用していると思われます。RegisterManyForOpenGeneric

container.RegisterManyForOpenGeneric(
    typeof(ISubstriber<>),
    (type, impls) => container.RegisterAll(type, impls),
    typeof(ISubstriber<>).Assembly);

その場合、実装のリストがデリゲートに提供される順序は、それらが .NET メタデータから返される順序によって異なります。提供されたアセンブリをRegisterManyForOpenGeneric呼び出すだけです。GetExportedTypes()これらの型が返される順序は非常に信頼性が低く、C# の将来のバージョンではコードを再コンパイルすることで変更される可能性があり、CLR の将来のバージョンではアプリケーションを再起動するだけで変更される可能性があります。

したがって、実装を特定の順序でリストに配置する必要がある場合は、実装のリストを並べ替えるだけです。

(serviceType, impls) => container.RegisterAll(serviceType,
    impls.OrderBy(type => [some condition]));

ただし、一般的には、順序は重要ではないと思います。問題がある場合は、デザインをよく見てください。ここにいくつかの問題があるかもしれません。たとえば、一部のクラスを属性でマークしたいという事実は[SubscriberPriority]、抽象化が欠落している可能性があることを示しています。おそらく、それらに独自のインターフェースを与えて、別々に登録する必要があります。

私が常にアドバイスするもう 1 つのことは、登録リストをコンポジットの背後に配置して、アプリケーションから非表示にすることです。

public class CompositeSubscriber<T> : ISubscriber<T>
{
    private IEnumerable<ISubscriber<T>> subscribers;

    public CompositeSubscriber(
        IEnumerable<ISubstriber<T>> subscribers)
    {
        this.subscribers = subscribers;
    }

    public void Handle(T value)
    {
        foreach (var subscriber in this.subscribers)
        {
            subscriber.Handle(value);
        }
    }
}

このコンポジットは、次のように登録できます。

container.RegisterSingleOpenGeneric(typeof(ISubscriber<>),
    typeof(CompositeSubscriber<>);

ISubscriber<T>この場合、アプリケーションは単純にの代わりに依存できますIEnumerable<ISubscriber<T>>。メソッドのコールバックを使用して順序を制御する代わりにRegisterManyForOpenGeneric、コンポジットを使用して順序を制御できるようになりました。

于 2013-02-01T09:08:48.013 に答える