2015-12-01 2 views
1

Я проверяю инфраструктуру ReactiveUI MVVM. Мне очень нравится концепция Rx и вы хотите начать использовать ее и изучить ее для моего следующего проекта.Подключить стороннюю инфраструктуру внедрения зависимостей с ReactiveUI

Я обнаружил недостаток документации при попытке использовать ее с Ninject или сторонним контейнером DI.

Что я обычно делаю, это установить Ninject в прикладном уровне платформы и зарегистрировать там зависимости. Затем используйте его для ввода зависимостей через конструктор или при необходимости разрешите их через место службы.

Я нашел этот шаблон необязательных зависимостей конструктора очень хорошим, сделав зависимость в конструкторе необязательным и, если null разрешить с использованием местоположения службы, работает при инъекции макетных зависимостей при модульном тестировании.

Итак, скажем, у вас есть этот конструктор.

public OrdersListViewModel(IWebOrdersRepository<Order> webOrdersRepository = null) 
     { 
      _webOrdersRepository = webOrdersRepository ?? Locator.Current.GetService<IWebOrdersRepository<Order>>(); 
     } 

Это используется локатор службы Splat, но я хочу использовать инжектор и место установки конструктора Ninject.

Что я делаю в проекте платформы iOS, является следующим.

public class NinjectConfiguration : NinjectModule 
    { 
     public override void Load() 
     { 
      BindImplementations(); 
     } 

     private void BindImplementations() 
     { 
      Bind<IWebOrdersRepository<Order>>().To<WebOrdersRepository>().InSingletonScope(); 
      Bind<OrdersListViewModel>().ToSelf(); 
     } 
    } 

В AppDelegate.cs.

NinjectKernel.Initialize(new NinjectConfiguration()); 

создать OrdersListViewModel в методе UIViewController ViewDidLoad.

public override async void ViewDidLoad() 
     { 
      base.ViewDidLoad(); 

      ViewModel = await BlobCache.LocalMachine.GetOrCreateObject(OrdersListViewModel.Key,() => { 
       return NinjectKernel.Get<OrdersListViewModel>(); 
      }); 
     } 

Вышеупомянутый должен создать экземпляр OrdersListViewModel, вводящий зависимости.

Запуск приложения iOS не впрыскивает зависимость в конструкторе, поэтому он всегда попадает в разрешение определения местоположения.

Я могу определенно жить без DI, реализующего дополнительный шаблон конструктора, так как модульное тестирование все еще легко, но мне интересно, почему он не работает.

Я нашел в этой ссылке https://reactiveui.readthedocs.org/en/latest/dependency-injection/splat/, в последнем абзаце говорится.

В расширенном разделе руководства описывается, как подключить сторонние модули ввода-вывода . Однако читателю настоятельно рекомендуется отказаться от этой идеи и использовать распознаватель по умолчанию.

Но, не можете найти расширенный раздел, а также почему ему рекомендуется отказаться от идеи? Я все еще могу быть лучшим из всех миров, не так ли?

На данный момент не так уверен, что это проблема с Ninject, или я не знаю, как это сделать с ReactiveUI, хотя раньше у меня не было проблем с Ninject DI.

ответ

2

Мне сложно точно сказать, что не так с вашим решением, но я думаю, что я могу предложить вам некоторые указания относительно подключения каркаса DI к RxUI.

Вы можете найти good example using Autofac on Github.Все это сводится к обертыванию DI по вашему выбору в классе, реализующем IMutableDependencyResolver (см. example), а затем присвоить его Locator.Current.

Для чего вам лучше использовать Splat, there is a great answer on SO by the creator of RxUI and Splat himself по этой теме. В основном,

Я вообще думаю, что много советов вокруг IoC/DI довольно плохо в области «кросс-платформенных мобильных приложений», потому что вы должны помнить, что многие их идеи были написаны для Интернета приложений, а не мобильных или настольных приложений.

Например, подавляющее большинство популярных контейнеров IoC относятся исключительно к скорости разрешения в теплом кеше, в то время как в основном полностью игнорируют использование памяти или время запуска - это на 100% отлично подходит для серверных приложений, поскольку эти вещи не дело; но для мобильного приложения? Время запуска огромно.

SPLAT в Service Location решает ряд вопросов для RxUI:

  1. Service Location быстро, и почти не имеет накладных расходов для настройки.
  2. Он инкапсулирует несколько различных моделей общего объекта прижизненных (т.е. «создать новый каждый раз, когда», «одиночки», «ленивыми»), просто написав Func иначе
  3. Это Mono Linker дружественного (обычно)
  4. Service Location позволяет нам регистрировать типы в коде, специфичном для платформы, но использовать их в коде PCL.
+0

Да, я видел ответ Павла о месте службы, но это действительно бьет с помощью DI контейнера, как Autofac или Ninject, когда речь идет о зависимости цепи? Я имею в виду, я мог бы просто использовать конструктор Splat-to-constructor во всех своих виртуальных машинах и службах, но опять же ... Спасибо за информацию, заменяющую локатор сервисов. Не уверен, что мне это действительно нужно, я просто хочу использовать Ninject для встраивания зависимостей в свой конструктор VM, и это странно, что это не работает. Думаю, мне придется просто придерживаться Splat. –

+0

Отмечено как разрешено, он отвечает на вопросы о том, как подключить сторонний контейнер DI в качестве решателя по умолчанию ReactiveUI. Я буду исследовать Ninject дальше, чтобы узнать, связано ли это с ReactiveUI и открыть новый вопрос. –