Prism, Unity и регистрация типов по умолчанию в модулях - PullRequest
3 голосов
/ 12 мая 2011
*

Технологии * 1001 C # 4.0 Prism 4 с Unity для DI WPF MVVM Введение

В моем решении есть два проекта: MyApp.Shell и MyApp.ModuleFoo

MyApp.Shell's Unity Bootstrapper

protected override IModuleCatalog CreateModuleCatalog()
{
    // Module assemblies are read from a directory.
    DirectoryModuleCatalog moduleCatalog = new DirectoryModuleCatalog();
    moduleCatalog.ModulePath = @".\Modules";
    return moduleCatalog;
}

Проект MyApp.ModuleFoo содержит представление и модель представления.

ViewModel

// Somehow, Unity sees this class and registers the type.
public class FooViewModel : ViewModelBaseClass
{
    public string FooText
    {
        get { return "Foo!"; }
    }
}

Вид

<Label Content={Binding FooText} />

Код представления позади

// Unity automatically sees this as Constructor Injection, 
// which is exactly what I desire.
public FooView(FooViewModel viewModel)
{
    DataContext = viewModel;
    ...
}

Инициализация MyApp.FooModule

Возможно, регистрация FooView у менеджера региона непреднамеренно регистрирует FooViewModel в Unity?

public void Initialize()
{
    var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
    regionManager.RegisterViewWithRegion("FooRegion", typeof(FooView));
}

Вид правильно отображает «Foo!».

Проблемы

  • Как мне сказать Unity, чтобы он регистрировал только один экземпляр FooViewModel?
  • Кроме того, (и я думаю об этом здесь), как бы я сказал единице , а не , чтобы зарегистрировать FooViewModel?

Спасибо за помощь.

Edit:

Добавлен код инициализации MyApp.FooModule

Редактировать (Решение):

Оказывается, RegisterViewWithRegion имеет две перегрузки. Из документации Prism, когда используется перегрузка, которую я использую, создается новый экземпляр представления. Я предполагаю, что это также создает новый экземпляр FooViewModel.

Другая перегрузка использует делегат для разрешения FooView. В документации говорится, что эта перегрузка используется в подходе «ViewModel-first». Я собираюсь задать этот вопрос в качестве ответа, но если у кого-то есть какие-то дополнительные идеи, я бы хотел услышать.

1 Ответ

4 голосов
/ 12 мая 2011

// Somehow, Unity sees this class and registers the type. public class FooViewModel : ViewModelBaseClass ...

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

Когда у вас есть конкретные классы (не интерфейсы), они автоматически создаются Unity независимо от того, зарегистрированы они или нет.Если не по умолчанию, каждый раз создается новый экземпляр.Управление временем жизни также не применяется.

Что касается ваших вопросов:

Чтобы зарегистрировать только один тип при инициализации вашего модуля, просто имейте.

Container.RegisterType<FooViewModel>(new ContainerControlledLifetimeManager());

Время жизниМенеджер даст команду Unity создать только один экземпляр модели представления.

...