Инъекция контейнера Unity в моих моделях взгляда - PullRequest
1 голос
/ 25 мая 2019

Я новичок в C # / .Net / Prism / WPF / DevExpress и начал работать над большим проектом в моей компании. Поскольку я начинаю немного поздно в проекте, много кода уже было создано, и я очень часто сталкиваюсь с таким кодом:

public class AboutWindowViewModel : BindableBase
{
  public AboutWindowViewModel(IUnityContainer container)
  {
    ...

Что я нахожу здесь "особенным", так это зависимость модели представления в контейнере. В кодовой базе, на которую я сейчас смотрю, это, кажется, «шаблон». Каждый класс получает в IUnityContainer зависимость, и затем зависимости разрешаются вручную, например,

container.ResolveEx<...>(...);

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

Теперь я обратился с этой проблемой к разработчикам моей компании, и они ответили мне следующее:

Prism recommendation is to resolve services using containers as they are needed.

Поэтому они все время разрешают их методом IUnityContainer.ResolveEx.

Мой вопрос: действительно ли это рекомендуемый способ создания программного обеспечения с помощью Prism ??? Если нет, то знаете ли вы, где я могу найти документацию, в которой четко приведены примеры с указанием?

1 Ответ

1 голос
/ 25 мая 2019

- это действительно рекомендуемый способ создания программного обеспечения с помощью Prism ???

Совсем нет, в этом анти-шаблон .

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

На самом деле не только Prism, но в более общем плане рекомендуется позволить контейнеру разрешить зависимости.Конечно, это можно сделать, вызвав Resolve вручную, но при этом вы потеряете все преимущества, ожидаемые от внедрения зависимостей.

Скорее, вы захотите перечислить зависимости как параметры конструктора и позволить контейнеру заполнитьсяих.Ваш код не должен зависеть от контейнера, за исключением самой точки входа ("корневого разрешения").Приложение должно содержать только один оператор Resolve, который разрешает первый экземпляр.

Здесь вступает в игру Prism: в ваших PrismApplication.RegisterTypes и IModule.RegisterTypes вы настраиваете свой контейнер.Вы говорите ему, какой тип должен реализовывать какой интерфейс.Позже, когда требуются модели представлений, Prism (точнее, ViewModelLocator) использует контейнер для разрешения моделей представлений, тем самым разрешая все зависимости.Нет никаких причин, чтобы какой-либо класс зависел от контейнера, фактически Prism вообще ничего не регистрирует для IContainerRegistry.

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

В дополнение к этому, я лично не буду работать для клиента с такой кодовой базой, какэто очевидное доказательство того, что их разработчики понятия не имеют, что они делают.

...