2

VS 2010 に基本的な vsix パッケージ プロジェクトがあり、Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase から派生した単純な ServiceLocator があり、Package から派生したクラスの Initialize オーバーライドに登録しています。

private WindsorContainer container;

protected override void Initialize()
{
    container = new WindsorContainer();

    ServiceLocator.SetLocatorProvider
    (
        () => new WindsorServiceLocator(container)
    );

    ....the package menu setup....
}

問題は、何らかの理由で、コンテナーが私が何も知らない型を解決するように求められていることです。まだ ServiceLocator.Current にコードを実装していませんが、まだ解決するための呼び出しが実行されています。

最初の解決タイプは System.IServiceProvider で、どこかでコンテナの衝突が起こっていると思いました。IServiceProvider が要求された場合に null を返すように、ロケーターの解決オーバーライドにコードを一時的に追加しました。外部コードは、それが何であれ、有効なインスタンスを返さないことを気にしないように見えましたが、解決はいくつかの VSCommands タイプを解決するように求められました。

したがって、同じ appdomain で実行されている 2 つの別個のコンポーネントが両方とも ServiceLocator を使用してコンテナーを登録し、それによって互いに競合が発生する可能性は十分にあると考えています。VSCommands が ServiceLocator を使用しているかどうかはわかりませんが、VS からこの拡張機能を削除すると問題が解決しました。

他のサードパーティの拡張機能の実装者と ServiceLocator の使用の可能性を制御できないため、他の拡張機能が私のコンテナーを呼び出さないように何らかの方法で分離することは可能ですか?

よろしく、

マーク

4

1 に答える 1

0

なんて素晴らしい発見でしょう!VSCommands が ServiceLocator を使用していると推測したのと同じように、他のパッケージも同様に ServiceLocator を使用する可能性があるため、そうすることで問題が発生する可能性があります。

考えられる簡単な回避策が 1 つあります。このような競合を回避するために、VSCommands の次のバージョンでおそらくそれを使用します。ServiceLocator クラスの実装は非常に単純であるため、次のようになります。

public static class ServiceLocator
{
    private static ServiceLocatorProvider currentProvider;

    public static void SetLocatorProvider(ServiceLocatorProvider newProvider)
    {
        currentProvider = newProvider;
    }

    public static IServiceLocator Current
    {
        get
        {
            return currentProvider();
        }
    }
}

まったく同じ実装で「MyServiceLocator」を作成し、Microsoft.Practices.ServiceLocation.dll の ServiceLocator の代わりにコードで使用することを考えています。

于 2011-06-01T13:26:21.627 に答える