WPF с Unity Container - Как зарегистрировать и разрешить ViewModels для Views

Привет я пытаюсь использовать контейнер Unity в приложении WPF MVVM. Я не использовал Prism, как кажется, тяжелым. Вот структура приложения. Я пытаюсь выяснить, как разрешить представления в ViewModels и зависимости моделей представлений (сервисов).

Заявка:

Просмотры

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

ViewModels

MainViewModel

CustomerListViewModel

BoolListViewModel

BookDetailViewModel

CustomerDetailViewModel

Библиотека

ICustomerService (AddCustomer, SaveCustomer, GetCustomers, GetCustomer)

CustomerService:ICustomerService

IBookService (GetBooks, GetBook)

BookService:IBookService

IBookReserveService(Reserve, Return)

BookReserveService:IBookReserveService

MainViewModel нужна ссылка на ICustomerService и IBookService

CustomerListViewModel нужна ссылка на ICustomerService

BoolListViewModel нужна ссылка на IBookService

BookDetailViewModel нуждается в ссылке на ICustomerService и IBookReserveService

CustomerDetailViewModel нуждается в ссылке на ICustomerService и IBookReserveService

У меня есть свойство getter setter для служб в каждой модели просмотра.

Я сталкиваюсь с вопросами о том, как использовать Dependency Injection с WPF, особенно для Views и ViewModel. Я пытался с Unity зарегистрироваться и решить в консольном приложении, которое работает нормально. Но я хотел бы поделиться некоторыми идеями о том, как это можно сделать для приложения WPF. Я пытался зарегистрироваться

 container.RegisterType()
 container.RegisterType()
 container.RegisterType()

и разрешите его с помощью container.Resolve ();

Но я не был уверен, как определить, какое представление должно использовать какую модель представления, и разрешить их при необходимости, а не при запуске приложения. Кроме того, я не разрешаю все сопоставления при запуске приложения. Это должно быть сделано, когда выбрано меню (Выбор клиента для просмотра деталей, выбор книги для просмотра деталей, сохранение клиента, резервная книга и т. Д.).

В основном то, что я прочитал, хотел использовать IView и IViewModel. Но не уверен, что понял в этом преимущество.

Любая помощь очень ценится.

 Adi Lester20 нояб. 2012 г., 20:23
Использование Prism действительно упростит вам весь этот процесс, так какотвечает за создание ваших представлений с вашим контейнером IoC (Unity в вашем случае). Может быть, этот вопрос может помочь:stackoverflow.com/q/8617277/389966

Ответы на вопрос(1)

Решение Вопроса

Один способ, которым вы можете сделать это. Сначала зарегистрируйте ваши View-модели и сервисы в Unity следующим образом:

// Unity is the container
_container.RegisterType<imainviewmodel, mainviewmodel="">();
_container.RegisterType<ibookservice, bookservice="">();
</ibookservice,></imainviewmodel,>

Во-вторых, установите свой взгляд "s DataContext для модели представления в представлении 'S конструктор, как это:

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

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

В-третьих, тыВам нужно будет внедрить ваши услуги в ваши View-модели:

public MainViewModel(ICustomerService custService, IBookService bookService ){}

Есть и другие способы сделать это с помощью файлов .config и т. Д., Но этого должно быть достаточно для начала, дайте мне знать, если вам нужно больше. Вы спросили, в чем преимущества DI, и я чувствую, что их много. Просто назову пару: способствует слабой связи между вашими компонентами и улучшает тестируемость. Я чувствую это's один из ключевых моментов для хорошего дизайна / реализации.

ОБНОВИТЬ:

С единством>= 3, вы можете пропустить регистрацию контейнера, если вы следуете следующим правилам именования:

// This will register all types with a ISample/Sample naming convention 
            container.RegisterTypes(
                AllClasses.FromLoadedAssemblies(),
                WithMappings.FromMatchingInterface,
                WithName.Default);
 Legends18 авг. 2016 г., 00:41
UnitContainer не является синглтоном.public UnityContainer() : this(null) { this.AddExtension(new UnityDefaultStrategiesExtension()); }
 Big Daddy20 нояб. 2012 г., 21:14
Unity разрешится сам, поэтому нет необходимости регистрировать контейнер для себя. Я'Мы обновили мой ответ, чтобы ответить на ваш вопрос.
 Big Daddy19 авг. 2016 г., 02:26
@Legends ... Раньше я использовал сервисный локатор, но теперь я использую инжектор конструктора почти исключительно. Я мог бы обновить это, но неЯ чувствую, что это добавляет что-то полезное в это время. Благодарю.
 Legends18 авг. 2016 г., 00:27
Почему ты_container.Resolve();  ConstructorInjection / PropertyInjection?
 isakavis20 нояб. 2012 г., 23:19
Отлично. Это сработало. Я также начал создавать отдельный класс для регистрации и разрешения типов, когда это необходимо, и сделал его статическим, а не передавал контейнер вокруг. Как вы думаете, это хороший подход?
 isakavis20 нояб. 2012 г., 20:44
_контейнер, где он создан? Я предполагаю, что это в App.xaml.cs. Как у меня будет доступ к этому в моделях представления, чтобы решить это?
 Hristo Yankov30 дек. 2016 г., 21:00
Это просто ужасный ответ! Передача контейнера Unity в основной вид вместоIMainViewModel?! Теперь у вас естьService Locator анти-паттерн продолжается.
 Big Daddy21 нояб. 2012 г., 00:55
Отлично ... Пусть Unity справится с Решением <T) и я считаю, что контейнер Unity является одноэлементным по умолчанию. Я бы несоздать отдельный статический класс, чтобы действовать в качестве оболочки, потому что я неЯ не вижу в этом никакого преимущества и думаю, что это добавляет ненужное раздувание (только мое мнение). Если у вас есть время, изучите Prism, поскольку он облегчает работу с моделью MVVM.

Ваш ответ на вопрос