【问题标题】:IoC Container Unity is messing with meIoC Container Unity 惹恼了我
【发布时间】:2011-02-27 18:47:19
【问题描述】:

我可能不明白它应该如何工作。

我从哪里开始我的应用程序:

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 中订阅了一个事件。 WorkspaceFactory 和 WindowManager 应该在这里由 Unity 解析,以便创建它们的实例。

这是 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 参数的工作区。所以它应该得到 sama 实例,因为 MainWindowViewModel 是正确的?

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

怎么可能?

我是不是完全走神了,我的印象是,如果你不为容器中的类型定义 LifeTime,你总是会得到相同的实例。

【问题讨论】:

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


    【解决方案1】:

    对不起,但我认为你已经离开了 - 如果 Unity 类似于 AutoFac,那么默认行为将是“每个请求的新实例”。

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

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

    【讨论】:

    • 是的,我现在可以看到我误读了手册。我阅读了 RegisterInstance 章节,因为它适用于 RegisterType。这可以解释我的问题。
    【解决方案2】:

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

    【讨论】:

    • 我以前听说过。这主要只是一个临时解决方案,因为我需要基于字符串解析 WorkspaceModels。我对工厂还不够熟悉,所以我相信自己能够做到这一点。
    • 大+1。 @Stuart 的回答是正确的,但我完全同意@Lee 的观点,即注入容器不是最佳实践。 Unity 可以轻松地使用 Func(T) 代表注入工厂。见link
    • 很好,谢谢,稍后我会查看您的链接。我不希望工厂不依赖于容器并且传递一个委托可能就是答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 2011-12-15
    相关资源
    最近更新 更多