IoC Container Unity is messing with me
There is a possibility I'm not understanding how it's supposed to work.
Where I start my app I do this:
IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);
//MainWindow
container.RegisterType<Window, MainWindow>();
/开发者_C百科/Services
container.RegisterType<IWindowManager, WindowManager>();
//Workspaces
container.RegisterType<WorkspaceViewModel, CompanyWorkspace>("Company");
container.RegisterType<WorkspaceViewModel, DivisionWorkspace>("Division")
//More of this
container.RegisterType<IWorkspaceFactory, WorkspaceFactory>();
Window window = container.Resolve<Window>();
window.DataContext = container.Resolve<ViewModel.MainWindowViewModel>();
window.Show();
My MainWindowViewModel gets resolved and here is it's constructor
public MainWindowViewModel(IWorkspaceFactory workspaceFactory, IWindowManager windowManager)
{
_workspaceFactory = workspaceFactory;
_windowManager = windowManager;
_windowManager.Changed += new EventHandler(DialogChanged);
ControlPanel = new ListCommandsViewModel();
foreach (string s in _workspaceFactory.GetWorkspaceList())
{
ControlPanel.List.Add(new CommandViewModel(s, new RelayCommand<string>(OpenWorkspace)));
}
}
Notice that I subscribe to a event in the windowManager. WorkspaceFactory and WindowManager should are resolved here by Unity so instances of them are created.
Here is a implmentation of IWorkspaceFactory:
public class WorkspaceFactory : IWorkspaceFactory
{
private IUnityContainer _container;
public WorkspaceFactory(IUnityContainer container)
{
_container = container;
}
public ViewModel.WorkspaceViewModel GetWorkspace(string workspace)
{
return _container.Resolve<WorkspaceViewModel>(workspace);
}
public ICollection<string> GetWorkspaceList()
{
return _container.Registrations.Where(r => r.RegisteredType == typeof(WorkspaceViewModel)).Select(r => r.Name).ToList();
}
}
As I registered the original container as a instance it should be what is passed into the factory. So I'm letting the same Container resolve the workspace that grabs IWindowsManager as a ctro parameter. So it should be getting the sama instance as the MainWindowViewModel got right?
But if I fire off the event from inside the workspace the MainView never gets notified, in actuality the Changed event is empty like this is a seperate instance of IWindowManager.
How may that be?
Am I totally off, I was under the impression that if you don't define a LifeTime for types in containers you alwasy get the same instance.
Sorry, but I think you are off - if Unity is like AutoFac then the default behaviour will be "new instance per request".
This is certainly what the docs look like "It will create a new instance of the registered, mapped, or requested type each time" - see http://msdn.microsoft.com/en-us/library/cc440953.aspx
To correct this, provide a LifetimeManager when you Register the type - e.g. ContainerControlledLifetimeManager (see http://msdn.microsoft.com/en-us/library/cc440953.aspx)
By default, Unity will resolve a new instance for registered types, so you need to register WorkspaceViewModel
with a different scope. In addition, it's a bad idea to inject the container instead of the real dependencies since it makes it difficult for the client to know what those are.
精彩评论