2011-02-27 4 views
2

어떻게 작동하는지 이해할 수 없을 수도 있습니다. 내 응용 프로그램을 시작IoC Container Unity가 나를 괴롭 히고 있습니다.

내가 이렇게 여기

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

공지 사항입니다이다. WorkspaceFactory와 WindowManager는 유니티에 의해 여기에서 해석되어 인스턴스가 생성됩니다. 여기

는 IWorkspaceFactory의 implmentation입니다 :

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을 정의하지 않으면 알 수없는 것처럼 느껴질 것입니다.

답변

2

미안하지만, 나는 당신이 꺼져 있다고 생각합니다. Unity가 AutoFac과 같은 경우, 기본 동작은 "요청 당 새로운 인스턴스"가 될 것입니다.

이 확실히 문서는 "그것은 때마다, 등록 매핑, 또는 요구 된 타입의 새 인스턴스를 만들 것"처럼 무엇

- http://msdn.microsoft.com/en-us/library/cc440953.aspx

는이 문제를 해결하려면 볼을 당신이 유형을 등록 할 때 LifetimeManager을 제공 - 예. ContainerControlledLifetimeManager (http://msdn.microsoft.com/en-us/library/cc440953.aspx 참조)

+0

그래, 나는 설명서를 잘못 읽었 음을 알았다. RegisterType에서 작동하는 것처럼 RegisterInstance 장을 읽었습니다. 그건 내 문제를 설명해 줄거야. –

2

기본적으로 Unity는 등록 된 유형의 새 인스턴스를 확인하므로 WorkspaceViewModel을 다른 범위로 등록해야합니다. 또한 실제 의존성 대신 컨테이너를 주입하는 것은 클라이언트가 그 내용을 알기 어렵 기 때문에 바람직하지 않습니다.

+0

전에 들었습니다. 이것은 문자열을 기반으로 WorkspaceModels를 해결해야 할 때 주로 임시 솔루션입니다. 나는 아직 자신이 그렇게하기를 신뢰하는 공장에 익숙하지 않다. –

+1

큰 +1. @ 스튜어트의 대답은 정확하지만 컨테이너에 주사하는 것이 최선의 방법은 아니라는 것을 전적으로 동의합니다. Unity는 Func (T) 대리자가있는 공장을 쉽게 주입 할 수있게 해줍니다. [link] (http://blogs.msdn.com/b/ukadc/archive/2010/05/11/unity-2-0-automatic-builders.aspx)를 참조하십시오. – TrueWill

+0

감사합니다. 당신의 링크를 살펴 보겠습니다. 나중에. 나는 컨테이너에 의존하지 않는 공장을 가지지 않고 대의원을 보면서 답을 구할 수도있다. –

관련 문제