MvvmLight与WindsorCastle:冲突的Microsoft.Practices.ServiceLocation

时间:2019-05-06 13:44:28

标签: .net inversion-of-control mvvm-light castle-windsor common-service-locator

我已在.NET项目中安装:

  • MvvmLight v5.4.1.1
  • Castle.Windsor v5.0.0
  • CommonServiceLocator v2.0.2
  • CommonServiceLocator.WindsorAdapter.Unofficial v3.3.0

然后我像这样初始化我的容器

public ViewModelLocator()
{
    var container = new WindsorContainer();
    ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
    container.Register(Component.For<MainViewModel>().ImplementedBy<MainViewModel>());
}

哪个出现此错误:

  

类型'ServiceLocatorImplBase'在以下程序集中定义   未引用。您必须添加对程序集的引用   'Microsoft.Practices.ServiceLocation,版本== 1.3.0.0,   文化=中性,PublicKeyToken = 31bf3856ad364e35'。

基本上,MvvmLight v5.4.1.1期望CommonServiceLocator v2.0.2,CommonServiceLocator.WindsorAdapter.Unofficial期望CommonServiceLocator v1.3.0和CommonServiceLocator.WindsorAdapter期望CommonServiceLocator v1.0.0

一种解决方案是将CommonServiceLocator降级到v1.3.0,并且可以运行,但是随后MvvmLight也降级到v5.3.0

什么是正确的方法?如何使MvvmLight和Windsor Castle一起工作?

1 个答案:

答案 0 :(得分:0)

抱歉回答晚了 - 就在今天遇到了同样的问题。并有一个可行的解决方案。 是的,降级会起作用。并且会阻止稍后的 MvvmLight 更新或其他内容。 当您的项目肯定需要 CommonServiceLocator 版本 ^2.0.2 时,您可以将未“死”的 WindsorServiceLocator 适配器(对于 CommonServiceLocator v1)替换为 CommonServiceLocator v2 所需的另一个适配器。所以...CommonServiceLocator.ServiceLocator.SetLocatorProvider 期望 delegate IServiceLocator。然后,我们将需要一个适配器,它将现有的 WindsorContainer container 包装到 IServiceLocator 类型并将其作为委托返回。

感谢@zshewmaker (https://github.com/zshewmaker) 有他的代码。请检查 https://gist.github.com/zshewmaker/1074903 以获取包装源。

那么您的代码可能如下所示:

//existing *.cs
public ViewModelLocator()
{
    var container = new WindsorContainer();
    container.Register(Component.For<MainViewModel>().ImplementedBy<MainViewModel>());
    ServiceLocator.SetLocatorProvider(() => new CastleServiceProvider(container));
}

其中 CastleServiceProvider 以这种方式实现:

//new CastleServiceProvider.cs
public class CastleServiceProvider : IServiceLocator
{
    private readonly IWindsorContainer container;

    public CastleServiceProvider(IWindsorContainer container)
    {
        this.container = container;
    }

    public object GetService(Type serviceType)
    {
        return container.Resolve(serviceType);
    }

    public object GetInstance(Type serviceType)
    {
        return container.Resolve(serviceType);
    }

    public object GetInstance(Type serviceType, string key)
    {
        return container.Resolve(key, serviceType);
    }

    public IEnumerable<object> GetAllInstances(Type serviceType)
    {
        return (object[])container.ResolveAll(serviceType);
    }

    public TService GetInstance<TService>()
    {
        return container.Resolve<TService>();
    }

    public TService GetInstance<TService>(string key)
    {
        return container.Resolve<TService>(key);
    }

    public IEnumerable<TService> GetAllInstances<TService>()
    {
        return container.ResolveAll<TService>();
    }
}