Когда люди создают представления, передавая их через контейнер IOC, я всегда чувствую себя грязно. Ваши поверхности дизайна (Visual Studio и Expression Blend) не будут этого делать - они настаивают на использовании конструктора по умолчанию. Так зачем бороться с ними?
Гораздо более чистым решением является использование шаблона локатора модели вида. Вот основной:
public abstract class ViewModelLocator<TViewModel>
{
public TViewModel ViewModel
{
get { return StaticGateway.ServiceLocator.GetInstance<TRuntimeViewModel>(); }
}
}
Где StaticGateway - это статический класс, который предоставляет доступ к вашему контейнеру Unity и предоставляет его ServiceLocator. Тогда вы просто объявляете одно:
public class MasterPageViewModelLocator : ViewModelLocator<IMasterPageViewModel> { }
И используйте его в XAML:
<UserControl x:Class="YourCompany.MasterPageView" etc.>
<UserControl.Resources>
<local:MasterPageViewModelLocator x:Key="Locator" />
</UserControl.Resources>
<UserControl.DataContext>
<Binding Source="{StaticResource Locator}" Path="ViewModel" />
</UserControl.DataContext>
...etc...
</UserControl>
Ваши привязки, как правило, будут намного счастливее, потому что вы устанавливаете контекст данных в своем XAML. Установка контекста данных в коде позади может привести к некоторым странным поведениям, особенно когда вы переходите к интересным представлениям, таким как присоединенное поведение. И вы по-прежнему полностью используете свой контейнер IOC для выполнения внедрения зависимостей с дополнительным преимуществом всех ваших поверхностей проектирования, которые продолжают функционировать.
Что касается того, где зарегистрироваться, я не уверен, куда именно вы поместите это в приложение для навигации. Обычно вы используете Unity с чем-то вроде Prism и выполняете регистрацию в модуле инициализаторов. Я полагаю, вы могли бы сделать это в своем классе App или придумать эквивалент инициализатора модуля (но тогда вы должны просто использовать Prism, а не изобретать велосипед).