ReactiveUI, View / ViewModel injection и DI в целом
в последнее время я пытаюсь попасть в новую эру разработки пользовательского интерфейса и обнаружил ReactiveUI. Мне нравится его декларативный характер.
Я хотел сделать полный переключатель, поэтому я попытался понять, как делаются вещи в этом новом мире ReactiveUI. Я выбираю ReactiveUI, потому что я видел, что поддерживается очень умным парнем (Paul C. Betts).
Я очень новичок в этом, и я, вероятно, буду наводнять StackOverflow вопросами об этом, потому что у меня есть огромная сила и Я думаю, он заслуживает того, чтобы его выучили и освоили.
давайте перейдем к деталям:
Я всегда использовал View-First. Я ветеран-пользователь Cinch Framework (http://cinch.codeplex.com/)
Он использует MEF для ввода ViewModels в каждый вид. Вам просто нужно украсить свою ViewModel [ViewModel ("SampleView")] и добавить прикрепленное свойство к вашему представлению (ViewModelLocator.ViewModel= "SampleView"), и всякий раз, когда вид Загруженный, соответствующий ViewModel создается и вводится как его DataContext с выбранным жизненным циклом.
этот механизм, хотя он и действителен, имеет некоторые неудобства. Хуже всего то, что он использует локатор.
Как Марк Seemann предложить в своей книге, ServiceLocator является анти-шаблон, который следует избегать.
- Итак, мой первый вопрос: ReactiveUI построен поверх Инфраструктура на основе локаторов?
- вид-Первый или Модель Представления-Первых? Что лучше с точки зрения хорошей практики, развязки, твердого тела и подобных вещей, которые являются проблемами сумасшедшего, про-Microsoft чистого любовника кода, как я? Что заставит меня спать лучше и обеспечит мое приложение всеми этими *ibility goodness?
2 ответов
пол, вероятно, вступит в разговор с официальным ответом, но я внесу свои $0.02 как человек, который использовал фреймворк для нескольких проектов, но ни в коем случае не является экспертом.
1) я большой поклонник Марка Seemann, и я согласен с его выводом о ServiceLocator anti-pattern. Хотя ReactiveUI использует локатор "Splat", я бы не считал его построенным поверх инфраструктуры на основе локатора. Есть несколько глобальных элементов, которые используются как планировщики потоков и несколько основные настройки, но они в основном устанавливаются при запуске приложения (как и любой контейнер DI), и вы не имеете дело с ними непосредственно в своих классах по большей части. Единственное реальное местоположение -ViewModelHost
управление, которое использует определенный интерфейс (IViewFor
) о представлениях для регистрации в ViewModels. Это лучше, чем метод атрибута, так как он держит ViewModels блаженно не знают о представлениях. Но это происходит в самом контроле и является частью структуры, поэтому я не чувствую, что это злоупотребление из ServiceLocator анти-шаблон. Я не чувствую, что это отличается от регистрации ничего в настройка контейнер.
2) только в моем опыте с момента использования ReactiveUI мои взгляды стали супер-простыми. В основном хлопнуть некоторые основные XAML, чтобы получить внешний вид и макет правильно, реализовать IViewFor
в коде позади, и сделать все мои привязки в конструкторе, что я нахожу проще теперь с ReactiveUI, чем делать в XAML (хотя вы все еще можете, если хотите). Затем все, что логично, делается в ViewModels. Я думаю, что обычно я делаю первый подход ViewModel исключительно для того, чтобы он (или, по крайней мере, его интерфейс) был определен для реализации IViewFor<>
для него на вид. Мне нравится проверка типов и прочее (еще одна причина, по которой мне нравится связываться в конструкторе не в XAML). Но я не думаю, что есть веская причина делать это так или иначе, из моего опыта.
ServiceLocator-это анти-шаблон, которого следует избегать.
Я вообще думаю, что много советов вокруг IoC / DI довольно плохо в области "кросс-платформенных мобильных приложений", потому что вы должны помнить, что многие их идеи были написаны для веб-приложений, а не мобильных или настольных приложений.
например, подавляющее большинство популярных контейнеров МОК касаются исключительно ускорить разрешение на теплый кэша, а в основном, полностью игнорируя использование памяти и время запуска - это 100% хорошо для серверных приложений, потому что эти вещи не имеют значения, но для мобильного приложения? Время запуска огромный.
расположение службы Splat решает ряд проблем для RxUI:
- расположение услуги быстро, и почти не имеет накладных расходов для настройки.
- он инкапсулирует несколько различных моделей общего срока службы объекта (т. е. " создать новый каждый время", "синглтон", "ленивый"), просто написав Func по-разному
- это моно Линкер дружественный (как правило)
- расположение службы позволяет нам регистрировать типы в специфичном для платформы коде, но использовать их в коде PCL.
лучший способ использовать Service Locator
на самом деле, я вообще согласен с Марком Seemann, в том, что инъекция конструктора является предпочтительным способом - это шаблон, который я действительно например:
public SuspensionHost(ISuspensionDriver driver = null)
{
driver = driver ?? Locator.Current.GetService<ISuspensionDriver>();
}
Это использует интерфейс службы, расположенный для интерфейса по умолчанию, но только если вызывающий не дал явного в конструкторе. Гораздо проще тестировать в модульном тестовом раннере, чем пытаться построить поддельный контейнер IoC, но все равно возвращается к реализации по умолчанию во время выполнения.
View-First или ViewModel-First?
можно ли использовать маршрутизацию на основе VM (т. е. RoutedViewHost, IScreen, RoutingState и friends) в ReactiveUI зависит от платформы, на которой вы находитесь:
- WPF, Xamarin формы: абсолютно
- WP8, WinRT: вы можете заставить его работать, вы теряете некоторые переходы и тонкости
- Android, iOS родной: очень трудно сделать работу