带有 Unity Container 的 WPF - 如何注册 ViewModel 并将其解析为 View

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13480387/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:34:46  来源:igfitidea点击:

WPF with Unity Container - How to register and resolve ViewModels to Views

wpfunity-container

提问by isakavis

Hi I am trying to use Unity container in WPF MVVM application. I have not used Prism as it seems to heavy. Here is the application structure. I am trying to figure out how to resolve Views to ViewModels and dependencies of the view models (services).

嗨,我正在尝试在 WPF MVVM 应用程序中使用 Unity 容器。我没有使用过棱镜,因为它似乎很重。这是应用程序结构。我试图弄清楚如何将视图解析为视图模型和视图模型(服务)的依赖关系。

Application:

应用:

Views

观看次数

MainWindow.xaml
CustomerList.xaml
CustomerDetail.xaml
BookList.xaml
BookDetail.xaml

ViewModels

视图模型

MainViewModel

CustomerListViewModel

BoolListViewModel

BookDetailViewModel

CustomerDetailViewModel

Library

图书馆

ICustomerService (AddCustomer, SaveCustomer, GetCustomers, GetCustomer)

CustomerService:ICustomerService

IBookService (GetBooks, GetBook)

BookService:IBookService

IBookReserveService(Reserve, Return)

BookReserveService:IBookReserveService
  1. MainViewModel needs reference to ICustomerService, and IBookService

  2. CustomerListViewModel needs reference to ICustomerService

  3. BoolListViewModel needs reference to IBookService

  4. BookDetailViewModel needs reference to ICustomerService, and IBookReserveService

  5. CustomerDetailViewModel needs reference to ICustomerService, and IBookReserveService

  1. MainViewModel 需要引用 ICustomerService 和 IBookService

  2. CustomerListViewModel 需要引用 ICustomerService

  3. BoolListViewModel 需要引用 IBookService

  4. BookDetailViewModel 需要引用 ICustomerService 和 IBookReserveService

  5. CustomerDetailViewModel 需要引用 ICustomerService 和 IBookReserveService

I have getter setter property for services in each viewmodels.

我在每个视图模型中都有服务的 getter setter 属性。

I am running into issues on how do I use Dependency Injection with WPF especially for Views and ViewModel. I tried with Unity to register and resolve in a console application which is working fine. But I would like some ideas on how this could be done for WPF app. I tried registering

我遇到了关于如何将依赖注入与 WPF 一起使用的问题,尤其是对于视图和视图模型。我尝试使用 Unity 在一个运行良好的控制台应用程序中进行注册和解析。但我想要一些关于如何为 WPF 应用程序完成此操作的想法。我试过注册

 container.RegisterType<ICustomerService, CustomerService>()
 container.RegisterType<IBookReserveService, BookReserveService>()
 container.RegisterType<IBookService, BookService>()

and resolve it using container.Resolve();

并使用 container.Resolve() 解决它;

But I was not sure how I could tell which view must use which view model and resolve them when required and not when the app starts. Also, I dont to resolve all mapping in the app start. It should be done when the menu (Selecting a customer to view detail, selecting a book to view detail, save customer, reserve book etc.) is selected.

但是我不确定如何判断哪个视图必须使用哪个视图模型并在需要时而不是在应用程序启动时解决它们。另外,我不解决应用程序启动中的所有映射。选择菜单(选择客户查看详细信息、选择书籍查看详细信息、保存客户、预订书籍等)时应执行此操作。

Mostly what I read wanted to use IView and IViewModel. But not sure I understood the advantage in it.

我读到的主要是想使用 IView 和 IViewModel。但不确定我是否理解其中的优势。

Any help is greatly appreciated.

任何帮助是极大的赞赏。

回答by Big Daddy

Here's one way you can do this. First, register your view-models and services with Unity like this:

这是您可以执行此操作的一种方法。首先,像这样使用 Unity 注册您的视图模型和服务:

// Unity is the container
_container.RegisterType<IMainViewModel, MainViewModel>();
_container.RegisterType<IBookService, BookService>();

Second, set your view's DataContext to a view-model in the view's constructor like this:

其次,在视图的构造函数中将视图的 DataContext 设置为视图模型,如下所示:

public partial class MainView:UserControl
{
   private readonly IUnityContainer _container;

   public MainView(IUnityContainer container)
        {
            InitializeComponent();
            _container = container;   
            this.DataContext = _container.Resolve<IMainViewModel>();            
        }      
}

Third, you'll need to inject your services into your view-models:

第三,您需要将您的服务注入到您的视图模型中:

public MainViewModel(ICustomerService custService, IBookService bookService ){}

There are other ways to do this using .config files, etc. but this should give you enough to get started, let me know if you need more. You asked what the advantages of DI are and there are many, I feel. Just to name a couple: promotes loose-coupling between your components and improved testability. I feel it's one of the lynch-pins to a good design/implementation.

还有其他方法可以使用 .config 文件等来做到这一点,但这应该足以让您开始使用,如果您需要更多,请告诉我。你问DI的优点是什么,我觉得有很多。仅举几个例子:促进组件之间的松散耦合并提高可测试性。我觉得这是良好设计/实施的关键之一。

UPDATE:

更新:

With Unity >=3, you can skip the container registration if you follow the naming convention like this:

在 Unity >=3 的情况下,如果您遵循这样的命名约定,则可以跳过容器注册:

// This will register all types with a ISample/Sample naming convention 
            container.RegisterTypes(
                AllClasses.FromLoadedAssemblies(),
                WithMappings.FromMatchingInterface,
                WithName.Default);