質問
、これは基本的に各エンティティの特定の順序で呼び出されるクラスの連鎖です。
例えば、我々が持っているのでます:
providers = new List<IMetadataProvider>();
providers.Add(new ImageFromMediaLocationProvider());
providers.Add(new ImageByNameProvider());
providers.Add(new MovieProviderFromXml());
providers.Add(new MovieDbProvider());
providers.Add(new TVProviderFromXmlFiles());
providers.Add(new TvDbProvider());
providers.Add(new VirtualFolderProvider());
providers.Add(new FrameGrabProvider());
providers.Add(new MediaInfoProvider());
は、リスト内のプロバイダの順序はあるの重要の上位プロバイダは、下位のものよりも優先されます。
最近、私はこの部分の拡張性を作ることを試みました。だから、サードパーティのDLLは、私たちのチェーンに注入されます、独自のプロバイダを定義することができます。
問題は、サードパーティが、あなたがこの順序を定義するための中心的な場所を失うチェーンで自分自身を注入するためにあなたができるように一度ということです。
私はと少し不快に思います私の現在のソリューションは、各プロバイダ、次に優先順位によって順位を持つオプションの優先順位属性を定義することです。
だから、例えば私が今持ってます:
[ProviderPriority(20)]
class ImageByNameProvider{}
これはサードパーティがチェーン内での位置を定義することができます。
私が考えたもう一つの解決策は、属性例:前と後にした。
[Before(typeof(ImageByNameProvider))]
class ImageFromMediaLocationProvider {}
しかし、私はこれが反対プログラミングが容易または困難であるかどうかわからないです。
この問題の他の解決策はありますか?あなたはどちらのソリューションをして行くのでしょうか?
おそらく、私はちょうどコアプロバイダのリストを保持し、前に/追加する必要があり、サードパーティプロバイダにとってはattribs後...
解決
それはそうです。基本的な問題は、任意のオブジェクトがそのリストの途中のある時点で、既存のリストに挿入されることを可能にする機構を思い付くしようとしている。
あなたはIMetadataProviderインターフェイスが実際にどのように見えるかを説明していませんが、それは(最良のオプションは、GUIDを使用することです)一意プロバイダを識別するためにいくつかの方法を持っている必要があります。クラス名を使用してオーバー利点は、リファクタリング、などの際に必要に応じてあなたがいる限り、あなたが同じGUIDを保つようにカスタム(サードパーティ)のプロバイダに影響を与えることなく、クラスの名前を変更することを可能にするということです。
あなたはおそらくあなた自身のリストを導き出す必要がある。むしろ、単純なリストを使用するよります:
class ProviderList : List<IMetadataProvider { }
/インストールし、そのリストから自分自身を削除するには、カスタム(サードパーティ)のプロバイダのための方法を公開しています。これらのメカニズムは、チェーンの途中にで新しいプロバイダーを挿入する方法を知っているのに十分にスマートにも挿入されている複数のカスタムプロバイダを処理する方法を知っているのに十分にスマートにする必要があります。同様に、除去プロセスは同様の懸念に対処し、また、誰かがあなたの「コア」プロバイダのいずれかを削除しようとしないことを保証するだけでなく、スマートにする必要があります。
ここで良いアプローチは、おそらくあなたがインストールする()メソッドへのパラメータとして後に挿入したいプロバイダのGUIDを渡すことであろう。 remove()メソッドは、同様に除去するプロバイダのGUIDを取るだろう。
たとえば、私はMovieProviderFromXml後に新しいプロバイダを挿入言います。その後、別のサードパーティもMovieProviderFromXml後に新しいプロバイダをインストールします。新しいチェーンの順序は何をすべきですか?第二プロバイダは常にMovieProviderFromXml直後に挿入しないか、それが起動しないし、任意のカスタムプロバイダーをスキップし、最後のカスタムプロバイダをインストールした後に挿入します(これだけ次の「コア」プロバイダの前に?
その質問に関連して、あなたの「コア」プロバイダとカスタムプロバイダを区別するためにいくつかの方法を持っている必要があります考えです。
最後に、カスタムプロバイダが間違った場所に挿入されている場合は特に、チェーンの障害を処理する方法があることを確認する必要があります。
あなたはいつも、デフォルトのチェーンのベース(「マスター」)のリストを維持したいです。新しいプロバイダは、そのチェーンの途中に設置されている場合は、新しいチェーンを作成する必要がありますが、あなたは基本チェーンを失いたくはありません。これはあなたにデフォルトの状態に戻すチェーンをリセットする機能を提供します。
は、優先順位に基づいて連鎖をあなたがして、優先度の衝突の処理方法を決定する必要があるという点で問題があります。限り前/属性セットしたら、同じプロバイダの両方が可能でしょうか?おそらくない、それはChainInsertはとして列挙型の値の前後に定義ChainInsert列挙型プロパティがありProviderChainAttributeを作成するために、より多くの意味をなすかもしれませんので。これは、あなたはそれが指定されたプロバイダの後のまたはの前にインストールするかどうかを判断をするために、カスタムプロバイダを強制することができます。私はまだタイプではなくGUIDを使用することになります。
うまくいけば、これはあなたにこの問題にアプローチする方法についていくつかの他のアイデアを与えます。