IoC Container Unity正在搞乱我

时间:2011-02-27 18:47:20

标签: c# events event-handling ioc-container resolve

我有可能无法理解它应该如何运作。

在我开始使用我的应用程序时,我这样做:

IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);

//MainWindow
container.RegisterType<Window, MainWindow>();

//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();

我的MainWindowViewModel得到解决,这是它的构造函数

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)));
        }
    }

请注意,我在windowManager中订阅了一个事件。 Unity应该在这里解析WorkspaceFactory和WindowManager,以便创建它们的实例。

以下是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();
    }

}

当我将原始容器注册为实例时,它应该是传递给工厂的内容。所以我让同一个Container解析抓取IWindowsManager作为ctro参数的工作空间。所以应该在MainWindowViewModel正确的情况下获取sama实例?

但是如果我从工作区内部触发事件,MainView永远不会得到通知,实际上Changed事件是空的,就像这是IWindowManager的单独实例一样。

怎么可能?

我是完全离开的,我的印象是如果你没有为容器中的类型定义LifeTime,你可以得到相同的实例。

2 个答案:

答案 0 :(得分:2)

很抱歉,但我认为你不在 - 如果Unity就像AutoFac那么默认行为将是“每个请求的新实例”。

这肯定是文档的样子“它每次都会创建一个已注册,映射或请求类型的新实例” - 见http://msdn.microsoft.com/en-us/library/cc440953.aspx

要更正此问题,请在注册类型时提供LifetimeManager - 例如ContainerControlledLifetimeManager(参见http://msdn.microsoft.com/en-us/library/cc440953.aspx

答案 1 :(得分:2)

默认情况下,Unity将为已注册的类型解析新实例,因此您需要使用不同的范围注册WorkspaceViewModel。另外,注入容器而不是真正的依赖项是一个坏主意,因为它使客户端很难知道它们是什么。