0

Media Browserにはプロバイダーモデルがあります。これは基本的に、エンティティごとに特定の順序で呼び出されるクラスのチェーンです。

たとえば、次のようになります。

        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 {} 

しかし、これに対してプログラミングするのが簡単なのか難しいのかはわかりません。

この問題に対する他の解決策はありますか?どのソリューションを使用しますか?

おそらく、コアプロバイダーのリストを保持し、サードパーティプロバイダーのBefore/After属性を追加する必要があります...

4

1 に答える 1

1

ここには、対処すべきいくつかの異なる問題があるようです。基本的な問題は、任意のオブジェクトをそのリストの途中のある時点で既存のリストに挿入できるようにするメカニズムを考え出すことです。

IMetadataProviderインターフェイスが実際にどのように見えるかは説明しませんが、プロバイダーを一意に識別する方法が必要です(Guidを使用するのが最善のオプションです)。クラス名を使用する利点は、GUIDを同じに保つ限り、カスタム(サードパーティ)プロバイダーに影響を与えることなく、リファクタリングなどで必要に応じてクラスの名前を変更できることです。

単純なリストを使用するのではなく、おそらく独自のリストを導出する必要があります。

class ProviderList : List<IMetadataProvider { }

これは、カスタム(サードパーティ)プロバイダーがそのリストから自分自身をインストール/アンインストールする方法を公開します。これらのメカニズムは、新しいプロバイダーをチェーンの途中に挿入する方法を知るのに十分スマートである必要がありますが、挿入された複数のカスタムプロバイダーを処理する方法を知るのに十分スマートである必要もあります。同様に、削除プロセスも同様の懸念に対処し、誰かがあなたの「コア」プロバイダーの1つを削除しようとしないようにするために賢明である必要があります。

ここでの良いアプローチは、Install()メソッドのパラメーターとして後に挿入するプロバイダーのGUIDを渡すことです。Remove()メソッドも同様に、プロバイダーのGUIDを削除します。

たとえば、MovieProviderFromXmlの後に新しいプロバイダーを挿入するとします。次に、別のサードパーティもMovieProviderFromXmlの後に新しいプロバイダーをインストールします。新しいチェーンの順序はどうあるべきですか?2番目のプロバイダーは常にMovieProviderFromXmlの直後に挿入しますか、それともそこから開始してカスタムプロバイダーをスキップし、最後にインストールしたカスタムプロバイダーの後で(つまり、次の「コア」プロバイダーの直前に)挿入しますか?

その質問に関連しているのは、「コア」プロバイダーとカスタムプロバイダーを区別するための何らかの方法が必要であるという考えです。

最後に、特にカスタムプロバイダーが間違った場所に挿入された場合に、チェーンの障害を処理する方法があることを確認する必要があります。

デフォルトチェーンのベース(「マスター」)リストを常に維持する必要があります。そのチェーンの途中に新しいプロバイダーをインストールする場合は、新しいチェーンを作成する必要がありますが、ベースチェーンを緩めたくありません。これにより、チェーンをデフォルトの状態にリセットすることができます。

優先度に基づく連鎖は、優先度の衝突を処理する方法を決定する必要があるという点で問題があります。Before / After属性セットに関しては、同じプロバイダーで両方を許可しますか?おそらくそうではないので、ChainInsert列挙型プロパティを持つProviderChainAttributeを作成する方が理にかなっているかもしれません。ここで、ChainInsertはBeforeとAfterを列挙値として定義します。これにより、カスタムプロバイダーに、指定したプロバイダーの前にインストールする後にインストールするかを決定させることができます。タイプではなく、GUIDを使用します。

うまくいけば、これはあなたにこの問題に取り組む方法に関するいくつかの他のアイデアを与えるでしょう。

于 2009-04-07T02:07:34.323 に答える