How to do Hollywood Principle + DI + WPF + Unity
I'm currently starting with the development of a new WPF application where I use Unity as a DI container. As of now, I'm doing DI like this in the App.xaml.cs
protected overri开发者_开发百科de void OnStartup(StartupEventArgs e)
{
var container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
container = (UnityContainer)section.Configure(container);
WPFUnityContainer.Instance = container;
var mainwindow = new MainWindow();
var mainmodel = container.Resolve<ViewModel.MainWindowViewModel>();
mainwindow.DataContext = mainmodel;
mainwindow.Show();
base.OnStartup(e);
}
The MainWindowViewModel's ctr looks like this:
public MainWindowViewModel(IUserRepository userRepository, IGroupRepository groupRepository)
{
this._ManagementWorkSpaces = new ObservableCollection<WorkspaceViewModel>();
this._ManagementWorkSpaces.Add(new ManageApplicationsViewModel());
this._ManagementWorkSpaces.Add(new ManageUserViewModel(userRepository, groupRepository));
}
Now let's have a look at the ManageUserViewModel:
public ManageUserViewModel(IUserRepository userRepository, IGroupRepository groupRepository)
{...
this._ManageGroupsCommand = new DelegateCommand(() =>
{
LookupGroupDialogViewModel vm=new LookupGroupDialogViewModel(groupRepository);
View.LookupGroupDialogWindow vw=new View.LookupGroupDialogWindow();
ModalDialogService.Service.ShowDialog(vw, vm, returnedVM =>
{
if (returnedVM.SelectedGroup!=null)
this.SelectedUser.Groups.Add(returnedVM.SelectedGroup);
});
});
}
As you can see I'm injecting the groupRepository only to pass it on to the LookUpGroupDialogViewModel. I could leave the IGroupRepository out of the ManageUserViewModel's ctr and resolve it directly through the container but I think that violates the hollywood principle. How can I, in WPF, resolve all my dependencies so that the container calls me ? :)
It looks to me as if the View Models you are adding to the _ManagementWorkSpaces
must have some sort of common abstraction (unless the collection is completely untyped and simply accepts any object
) - I'm assuming that this is the WorkspaceViewModel
type.
This means that you can neatly solve your problem by changing the constructor to look like this:
public MainWindowViewModel(ObservableCollection<WorkspaceViewModel> workSpaces)
{
this._ManagementWorkSpaces = workSpaces;
}
Let your Composition Root worry about how the ObservableCollection<WorkspaceViewModel>
instance is resolved.
精彩评论