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 中删除此扩展程序可以解决问题。

由于我无法控制任何其他第 3 方扩展实施者及其可能使用的 ServiceLocator,是否可以以某种方式将其隔离,以便其他扩展不会调用我的容器?

问候,

标记

4

1 回答 1

0

多么棒的发现!正如您猜到的 VSCommands 使用 ServiceLocator 并且您发现这样做可能会给您和我带来一些问题,因为其他软件包也可能使用它。

我能想到一个简单的解决方法,我可能会在下一版本的 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 回答