MVVM依赖注入跨平台

用户名

早些时候,我写了这个问题,关于让MainViewModel实现接口的方式取决于我的Universal App中正在运行的项目。

根据平台选择通用应用程序中的接口实现

在实现了MVVM指示灯之后,我就可以通过以下方式注册我的VM:

SimpleIoc.Default.Register<MainViewModel>();

它还提供了在CTOR中使用接口注册VM的机会,如下所示:

SimpleIoc.Default.Register<IDataService, DataService>();

设置如下:

我有2个项目,Windows和WindowsPhone。在我的VM(位于PCL中)中,我的MainViewModel带有ctor中的ICameraCaller。这些项目都有一个实现ICameraCaller的类,并且我想根据我运行的项目,将CameraCaller的“正确”实现传递给CTOR。

因此,有人告诉我DI是必经之路。对我来说,这是一个相当新的话题,我已经坚持了很长时间。

在我看来,这应该是一项相当普通的任务?根据正在运行的项目将接口的实现传递给VM。

这是MainViewModel的ctor:

private ICameraCaller _cameraCaller;

public MainViewModel(ICameraCaller cameraCaller)
{
    _cameraCaller = cameraCaller;
}

考虑到我不知道将使用哪种实现,我不了解如何在ViewModelLocator中向我的视图模型注册接口。即使我知道。我无法访问其他项目中的实现。我一定对这个问题全都错了。

Fex

首先:使用便携式版本的mvvm light MVVMLight.portable我还建议您使用一些更高级的IoC容器-我个人更喜欢Ninject(也有称为的便携式版本Ninject.Portable)-它可以满足我的所有需求。从获取它Nuget Package Manager

第二个-创建名为ViewModelLocator(对于Windows Phone和Windows Modern不同)的类,它将充当您所谓的ApplicationCore(依赖项注入容器所在的位置)。

例子:

public class ViewModelLocator
{
    private readonly IKernel _dependenciesContainer;

    public ViewModelLocator() 
    {
         _dependenciesContainer = new StandardKernel(new ApplicationKernelModule());
    }

    public MainViewModel Main { get { return _dependenciesContainer.Get<MainViewModel>() } }
}

public class ApplicationKernelModule : NinjectModule
{ 
    public override void Load()
    {
        Bind<ICameraCaller>().To<DesktopCameraCaller>();  
    }
} 

public class DesktopCameraCaller : ICameraCaller
{
     // here lies Windows Modern implementation of camera caller
}

在App.xaml中,将您添加ViewModelLocatorStaticResource

<Application
x:Class="YourApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:YouNamespace"
xmlns:viewModel="using:ViewModelLocatorNamespace">

<Application.Resources>
    <ResourceDictionary>

        <viewModel:ViewModelLocator x:Key="ViewModelLocator"/>
    </ResourceDictionary>
</Application.Resources>

并在您的MainView中添加绑定到适当的ViewModel:

DataContext={Binding Source={StaticResource ViewModelLocator}, Path=Main}

对Windows Phone项目重复完全相同的步骤,但在ApplicationModule中将绑定到Windows Phone实现,例如:Bind<ICameraController>().To<WindowsPhoneCameraController>()

那里发生了什么?您使用Inversion of Control称为Ninject“将”接口“绑定”到具体类的库。这意味着-当您调用IKernel.Get<Type>()并在创建对象时Ninject看到构造函数中的任何位置时,ICameraControl它将其中创建新ModernCameraControl对象。您创建ViewModelLocator了一个简单的位置来存储“ Dependency Injection Resolver”(称为IKernel)-因此,您不必在任何地方都使用丑陋的服务定位器模式和静态引用Kernel当然,我以简化版描述了它-Ninject您可以做其他很棒的事情,例如进行范围界定(例如,您可以将接口注册为单例的类-在绑定的任何位置都存在相同的对象插入),您可以在注入类时添加条件逻辑(检查Bind<T>().To<T>().WhenInjectedTo/WhenInjectedExactlyToBind<T>().ToMethod(..)等等)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章