Регистрация в контейнере IoC после начальной настройки - PullRequest
1 голос
/ 17 декабря 2010

У меня есть сценарий, в котором я хотел бы зарегистрировать один экземпляр компонента в контейнере, но, к сожалению, его нельзя создать при запуске приложения.Этот компонент может быть создан только с передачей некоторых объектов, которые доступны только чуть позже в жизненном цикле приложения (однако они не являются другими зарегистрированными службами IoC) [см. Примечание ниже] .

  • Является ли регистрация компонента в контейнере IoC после начальной конфигурации (запуск при запуске приложения) плохой практикой?
  • Как это сделать, не ссылаясь непосредственно на контейнер?Стоит ли абстрагировать службу регистрации?
  • Есть лучший подход для поддержки сценария?

ПРИМЕЧАНИЕ о фактическом сценарии
компонент, который я хотел бы поместить в контейнер, инициализируется с конкретным экземпляром элемента управления пользовательского интерфейса (в основном это адаптер), поэтому мне нужно вручную создать экземпляр компонента и зарегистрировать его в контейнере.
Я бы сделалэто при запуске приложения, но, к сожалению, у меня пока нет доступного экземпляра элемента управления пользовательским интерфейсом (и при этом я не могу создать его самостоятельно).
Даже в более позднее время я не могу получить доступ к экземпляру элемента управления пользовательского интерфейса с поверхности других компонентов беззная их конкретный класс.
По этой причине я подумал, что могу возложить ответственность за регистрацию адаптера на класс, которому принадлежит элемент управления UI.

Мой начальный сценарий:

public interface IDockManager { ... }
public class AcmeDockManagerAdapter : IDockManager  {
    public AcmeDockManager(DockControl control) { ... }
    ...
}

public class ShellViewModel { ... }
public class ShellView : Window { 
    internal DockControl theDockControl;
} 

public class AnotherViewModel {
     AnotherViewModel(IDockManager dockManager) { ... }
}

Решение, которое меня не устраивает:

public class ShellView : Window { 
    internal DockControl theDockControl;
    public ShellView () {
        InitializeComponents();
        var dockManager = new AcmeDockManagerAdapter(theDockControl);
        //registration in the container
    }
} 

Ответы [ 2 ]

1 голос
/ 19 декабря 2010

Решение, насколько я понимаю вопрос, относительно простое - предоставить theDockControl извне.Я знаю, что это портит автоматически сгенерированную чушь WinForms / WPF / что угодно, но я боюсь, что здесь нет красивых решений.

1 голос
/ 18 декабря 2010

Вместо этого вы можете зарегистрировать «ленивую оболочку». Такая обертка реализует тот же интерфейс и может быть немедленно реализована, но внутренне откладывает создание фактического компонента, который выполняет работу. Взгляните на пример Плоэ LazyOrderShipper или LazyOrderShipper2 .

edit: Если я правильно понимаю, вы просто пытаетесь соединить ваши представления с вашими моделями представления в стиле MVVM. Я предпочитаю позволить контейнеру обрабатывать конструкцию viewmodel, но делать конструкцию view и проводку viewmodel самостоятельно. Мой стартовый код выглядит так:

var mainViewModel = container.Get<MainViewModel>();
var mainView = new MainView(mainViewModel);
Application.Run(mainView);

А внутри конструктора MainView я бы позаботился о дочерних элементах управления, для которых требуется собственная модель представления:

   public MainView(MainViewModel viewModel)
   {
       // link "subviews" to "subviewmodels"
       this.SomeChildControl.ViewModel = viewModel.SomeChildViewModel;

       // normal MVVM property wiring
       viewModel.TitleChanged += delegate { this.Text = viewModel.Title; };
       ...
   }

Если вы строго следуете подходу MVVM, вам не нужно регистрировать любое представление в контейнере. Все, что «нуждается в взаимодействии с представлением», на самом деле должно взаимодействовать с базовой моделью представления. (Ситуация становится более интересной, если вы хотите включить сменные представления в интерфейсе с вкладками или в графическом интерфейсе пристыкованного окна, но это уже другая история.)

...