开发者

Calling ServiceLocator.SetLocatorProvider for a new Castle Windsor container causes IServiceProvider conflict in a VSIX package

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 th开发者_Go百科e 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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜