跨平台MVVM依赖注入

跨平台MVVM依赖注入,mvvm,Mvvm,早些时候,我写了这个问题,是关于让我的MainViewModel根据我的通用应用程序中运行的项目实现接口的方法 在此之后,我实现了MVVM light,它允许我像这样注册我的VM: SimpleIoc.Default.Register<MainViewModel>(); SimpleIoc.Default.Register<IDataService, DataService>(); 考虑到我不知道将使用什么实现,我不理解如何在ViewModelLocator中注册v

早些时候,我写了这个问题,是关于让我的MainViewModel根据我的通用应用程序中运行的项目实现接口的方法

在此之后,我实现了MVVM light,它允许我像这样注册我的VM:

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

考虑到我不知道将使用什么实现,我不理解如何在ViewModelLocator中注册viewmodel的接口。即使我知道。我无法访问其他项目中的实现。我一定是把这个问题搞错了。

首先:使用可移植版本的mvvm light
MVVMLight.portable
。我还建议您使用一些更高级的
IoC
容器-我个人更喜欢
Ninject
(也有名为
Ninject.portable
)的便携式版本-它适合我的所有需要。从Nuget软件包管理器获取它

第二,创建名为
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
}

并在主视图中向适当的ViewModel添加绑定:

private ICameraCaller _cameraCaller;

public MainViewModel(ICameraCaller cameraCaller)
{
    _cameraCaller = cameraCaller;
}
DataContext={Binding Source={StaticResource ViewModelLocator}, Path=Main}
对Windows Phone项目重复完全相同的步骤,但在ApplicationModule中绑定到Windows Phone实现,例如:
bind().to()


那里发生了什么?您可以使用名为
Ninject
inversionofcontrol
库将接口“绑定”到具体的类中。这意味着-当您调用
IKernel.Get()
并在创建对象
Ninject
时,它将在构造函数
ICameraControl
中的任意位置创建新的
modernacmeracontrol
对象。您创建了
viewmodelocator
来简化存储“依赖项注入解析器”(称为IKernel)的位置,这样您就不必到处使用丑陋的服务定位器模式和对
内核的静态引用。当然,我在简化版中描述了它-使用
Ninject
您可以做其他很棒的事情,比如范围界定(例如,您可以将接口注册到类,这将是单例的-在绑定的任何地方都有相同的对象安装),您可以在注入类时添加条件逻辑(检查
Bind().to()).WhenInjectedTo/WhenInjectedExactlyTo
Bind().ToMethod(..)
等)

首先:使用便携式mvvm light
MVVMLight.portable
。我还建议您使用一些更高级的
IoC
容器-我个人更喜欢
Ninject
(也有名为
Ninject.portable
)的便携式版本-它适合我的所有需要。从Nuget软件包管理器获取它

第二,创建名为
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
}

并在主视图中向适当的ViewModel添加绑定:

private ICameraCaller _cameraCaller;

public MainViewModel(ICameraCaller cameraCaller)
{
    _cameraCaller = cameraCaller;
}
DataContext={Binding Source={StaticResource ViewModelLocator}, Path=Main}
对Windows Phone项目重复完全相同的步骤,但在ApplicationModule中绑定到Windows Phone实现,例如:
bind().to()


那里发生了什么?您可以使用名为
Ninject
inversionofcontrol
库将接口“绑定”到具体的类中。这意味着-当您调用
IKernel.Get()
并在创建对象
Ninject
时,它将在构造函数
ICameraControl
中的任意位置创建新的
modernacmeracontrol
对象。您创建了
viewmodelocator
来简化存储“依赖项注入解析器”(称为IKernel)的位置,这样您就不必到处使用丑陋的服务定位器模式和对
内核的静态引用。当然,我在简化版中描述了它-使用
Ninject
您可以做其他很棒的事情,比如范围界定(例如,您可以将接口注册到类,这将是单例的-在绑定的任何地方都有相同的对象安装),您可以在注入类时添加条件逻辑(检查
Bind().to()).WhenInjectedTo/WhenInjectedExactlyTo
Bind().ToMethod(..)
等)

哇!谢谢你给出了一个很好的答案和例子!我要试试这个@用户2915962可以随意询问是否有不清楚的地方work@user2915962我回答这个问题时没有尝试编写代码和查看文档,已修复;)这两个项目都很成功!非常感谢你!哇!谢谢你给出了一个很好的答案和例子!我要试试这个@用户2915962可以随意询问是否有不清楚的地方work@user2915962我回答这个问题时没有尝试编写代码和查看文档,已修复;)这两个项目都很成功!非常感谢你!