2

それがどのように機能するのか理解していない可能性があります。

アプリを起動する場所でこれを行います。

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

}

元のコンテナをインスタンスとして登録したので、それは工場に渡されるものでなければなりません。そのため、IWindowsManagerをctroパラメーターとして取得するワークスペースを同じコンテナーに解決させます。それで、MainWindowViewModelが正しくなったので、samaインスタンスを取得する必要がありますか?

しかし、ワークスペース内からイベントを発生させた場合、MainViewは通知されません。実際には、これはIWindowManagerの個別のインスタンスであるため、Changedイベントは空です。

どうでしょうか?

私は完全にオフですが、コンテナ内の型のLifeTimeを定義しないと、常に同じインスタンスを取得するという印象を受けました。

4

2 に答える 2

2

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)

于 2011-02-27T19:00:27.370 に答える
2

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.

于 2011-02-27T19:00:59.537 に答える