为新的 Castle Windsor 容器调用 ServiceLocator.SetLocatorProvider 会导致 VSIX 包中的 IServiceProvider 冲突

发布于 2024-11-10 17:31:05 字数 965 浏览 3 评论 0原文

我在 VS 2010 中有一个基本的 vsix 包项目,并且有一个从 Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase 派生的简单 ServiceLocator,我正在从 Package 派生的类的初始化覆盖中注册:

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 类型。

因此,我认为在同一个应用程序域中运行的两个独立组件完全有可能都使用 ServiceLocator 注册一个容器,从而导致彼此冲突。我不知道 VSCommands 是否正在使用 ServiceLocator,但从 VS 中删除此扩展可以解决该问题。

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

问候,

马克

I have a basic vsix package project in VS 2010 and have a simple ServiceLocator deriving from Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase that I am registering in the Initialize override of the class deriving from Package:

private WindsorContainer container;

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

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

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

The problem is that for some reason the container is being asked to resolve types I know nothing about. I've not even implemented any code to ServiceLocator.Current yet but still the calls to resolve are executing.

The first resolving type is the System.IServiceProvider which made me think there is some clash of container's going on somewhere. I temporarily added some code to the locator's resolve override to return null if the IServiceProvider was asked for. The external code, what ever it is, seemed not to mind me not returning a valid instance but then the resolve was asked to resolve some VSCommands type.

So, I'm thinking that it is entirely possible that 2 separate components running in the same appdomain could both register a container using the ServiceLocator and thereby cause conflicts with one another. I don't know if VSCommands is using the ServiceLocator but removing this extension from VS removed the issue.

As I don't have control over any other 3rd party extension implementors and their possible use of ServiceLocator, is it possible to isolate it in someway so that other extensions don't call my container?

Regards,

Mark

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凡间太子 2024-11-17 17:31:05

多么棒的发现啊!
正如您猜测 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。

What a great find!
Just as you guessed VSCommands uses ServiceLocator and as you discovered doing so may cause some problems for you and me since other packages might use it just as well.

There is one simple workaround I can think of and I'll probably use it in the next version of VSCommands to avoid such conflicts. Since ServiceLocator class has a very simple implementation:

public static class ServiceLocator
{
    private static ServiceLocatorProvider currentProvider;

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

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

I'm thinking about creating 'MyServiceLocator' with exactly same implementation and using it in code instead of ServiceLocator from Microsoft.Practices.ServiceLocation.dll.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文