Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 国际奥委会集装箱联合会把我搞糊涂了_C#_Events_Event Handling_Ioc Container_Resolve - Fatal编程技术网

C# 国际奥委会集装箱联合会把我搞糊涂了

C# 国际奥委会集装箱联合会把我搞糊涂了,c#,events,event-handling,ioc-container,resolve,C#,Events,Event Handling,Ioc Container,Resolve,有一种可能是我不理解它应该如何工作 在哪里启动我的应用程序,我会执行以下操作: IUnityContainer container = new UnityContainer(); container.RegisterInstance<IUnityContainer>(container); //MainWindow container.RegisterType<Window, MainWindow>(); //Services container.RegisterTy

有一种可能是我不理解它应该如何工作

在哪里启动我的应用程序,我会执行以下操作:

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();
IUnityContainer container=newunitycontainer();
容器。注册表状态(容器);
//主窗口
container.RegisterType();
//服务
container.RegisterType();
//工作区
集装箱登记类型(“公司”);
容器注册表类型(“部门”)
//更多的
container.RegisterType();
Window=container.Resolve();
window.DataContext=container.Resolve();
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)));
        }
    }
public MainWindowViewModel(IWorkspaceFactory工作空间工厂、IWindowManager窗口管理器)
{
_workspaceFactory=workspaceFactory;
_windowManager=windowManager;
_windowManager.Changed+=新事件处理程序(DialogChanged);
ControlPanel=new ListCommandsViewModel();
foreach(在_workspaceFactory.GetWorkspaceList()中的字符串s)
{
添加(新的CommandViewModel,新的RelayCommand(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();
    }

}
公共类工作空间工厂:IWorkspaceFactory
{
专用IUnityContainer\u容器;
公共工作空间工厂(IUnityContainer容器)
{
_容器=容器;
}
public ViewModel.WorkspaceViewModel GetWorkspace(字符串工作区)
{
返回_container.Resolve(工作区);
}
公共ICollection GetWorkspaceList()
{
返回_container.Registrations.Where(r=>r.RegisteredType==typeof(WorkspaceViewModel))。选择(r=>r.Name.ToList();
}
}
当我将原始容器注册为实例时,它应该是传递到工厂的内容。因此,我让同一个容器解析将IWindowsManager作为ctro参数的工作区。所以它应该像MainWindowViewModel那样获得sama实例,对吗

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

怎么可能呢


我完全错了,我的印象是,如果您不为容器中的类型定义生存期,您可能会得到相同的实例。

对不起,但我认为您错了-如果Unity像AutoFac,那么默认行为将是“每个请求新实例”

这当然是文档看起来的样子,“它每次都会创建一个注册、映射或请求类型的新实例”-参见


要更正此问题,请在注册类型时提供LifetimeManager-例如ContainerControlled LifetimeManager(请参阅)

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

是的,我现在可以看出我误读了手册。我阅读了RegisterInstance一章,因为它可以处理RegisterType。这可以解释我的问题,我以前听说过。这主要只是一个临时解决方案,因为我需要基于字符串解析WorkspaceModels。我对工厂还不太熟悉,所以我相信自己能做到这一点。大+1@斯图尔特的回答是正确的,但我完全同意@Lee的观点,注射容器不是最佳做法。Unity可以轻松地为工厂注入Func(T)委托。再见,谢谢,我稍后会查看你的链接。我不希望工厂不依赖于容器,而让一个代理参与可能就是答案。