2017-03-01 85 views
1

最近我通過一些舊代碼去,發現下面的代碼如何統一容器將解決註冊類型

public class ProfileModule : IModule 
{ 
    private readonly IRegionManager regionManager; 
    private readonly IUnityContainer container; 
    private IEventAggregator eventAggregator; 

    public ProfileModule(IUnityContainer c, IRegionManager r, IEventAggregator e) 
    { 
     container = c; 
     regionManager = r; 
     eventAggregator = e; 
    } 

    public void Initialize() 
    {  
     // Create and add profiles as new Tab items 
     container.RegisterType<IProfileViewModel, Profile1ViewModel>(new ContainerControlledLifetimeManager()); 
     regionManager.Regions[RegionNames.HomeRegion].Add(container.Resolve<ProfileView>());// HomeRegion is of type TabControl 

     container.RegisterType<IProfileViewModel, Profile2ViewModel>(new ContainerControlledLifetimeManager()); 
     regionManager.Regions[RegionNames.HomeRegion].Add(container.Resolve<ProfileView>()); 

     container.RegisterType<IProfileViewModel, Profile3ViewModel>(new ContainerControlledLifetimeManager()); 
     regionManager.Regions[RegionNames.HomeRegion].Add(container.Resolve<ProfileView>()); 
    } 
} 

下面是ProfileView.xaml.cs

public partial class ProfileView : INotifyPropertyChanged 
{ 
    [InjectionConstructor] 
    public ProfileView(IProfileViewModel vm) 
    { 
     DataContext = vm; 
     InitializeComponent(); 
    } 
} 

下面是viewModels

public abstract class ProfileViewModelBase : IProfileViewModel, IDataErrorInfo, INotifyPropertyChanged 
{ 
    public ProfileViewModelBase(IEventAggregator eventAggregator, IRegionManager regionManager) 
    { 

    } 
} 


public class Profile1ViewModel : ProfileViewModelBase 
{ 
    [InjectionConstructor] 
    public Profile1ViewModel(IEventAggregator eventAggregator, IRegionManager regionManager) 
     : base (eventAggregator, regionManager) 
    { 

    } 
} 

public class Profile2ViewModel : ProfileViewModelBase 
{ 
    [InjectionConstructor] 
    public Profile2ViewModel(IEventAggregator eventAggregator, IRegionManager regionManager) 
     : base (eventAggregator, regionManager) 
    { 

    } 
} 


public class Profile3ViewModel : ProfileViewModelBase 
{ 
    [InjectionConstructor] 
    public Profile3ViewModel(IEventAggregator eventAggregator, IRegionManager regionManager) 
     : base (eventAggregator, regionManager) 
    { 

    } 
} 

對我來說不清楚的部分代碼是ProfileModule.Initialise()。 區域管理器每次添加視圖時,都會創建一個新的ProfileView新實例,並且viewModel是最後一次註冊的視圖模型。

首次使用Profile1ViewModel創建ProfileView作爲Datacontext。 第二次使用Profile2ViewModel創建ProfileView作爲Datacontext。 第三次使用Profile3ViewModel創建ProfileView作爲Datacontext。

  1. 容器如何確切地知道在創建視圖時要創建哪個視圖模型。
  2. 另外我明白,container.Resolve將返回視圖,如果它已經有一個,第一次視圖被創建並返回,第二次我除了相同的視圖將被返回,但一個新的視圖被創建。與第三個相同。

任何人都可以解釋發生了什麼?

回答

0

這裏所說:

  1. 你能在Initialize方法裏面看到的是,在註冊後IProfileViewModel的代碼,然後立即調用Resolve<ProfileView>其中第一Resolve正在提供Profile1ViewModelProfileView構造。然後第二個Register取代第一次註冊Profile2ViewModel。因此,對Resolve的後續調用絕不會爲您提供Profile1ViewModel的實例(或單例實例)。

  2. 如果由於某種原因,你真的想解析ProfileView的同一個實例,那麼你需要將這個與Unity容器一起作爲如下所示的單例使用:Register

    container.RegisterType(new ContainerControlledLifetimeManager());

這顯然是假設你有一個interface定義了一個名爲IProfileView

+0

的代碼格式不顯示 – Bijington

+0

謝謝Bijington一些很奇怪的原因。這回答我。 – JSR

+0

如果我們再次註冊,我絕不會進行替換。在'Initilaise()'中,代碼只是'regionManager.Regions [RegionNames.HomeRegion] .Add(new profileView(new profile1ViewModel()); regionManager.Regions [RegionNames.HomeRegion] .Add(new profileView(new profile2ViewModel() ); regionManager.Regions [RegionNames.HomeRegion] .Add(new profileView(new profile3ViewModel());'作爲'container'將不會有任何對視圖的引用並失去對viewModels的引用。 – JSR

相關問題