2012-08-12 164 views
0

我有很多存儲庫這樣的:實例化IUnitOfWork在WPF各的ViewModels /棱鏡應用

public class PersonRepository : IPersonRepository 
{ 
    private readonly IUnitOfWork _unitOfWork; 

    public PersonRepository(IUnitOfWork instance) 
    { 
     _unitOfWork = instance; 
    } 

    //Remove, Get methods... 
    public void Add(Person p) 
    { 
     _unitOfWork.Context.People.Add(p); 
    } 
} 

和工作類的單位是這樣的:

public class UnitOfWork : IUnitOfWork, IDisposable 
{ 
    public UnitOfWork(){ } 

    private readonly HezarehContext _context = new HezarehContext(); 
    public HezarehContext Context 
    { 
     get 
     { 
      return _context; 
     } 
    } 

    public int Save() 
    { 
     return _context.SaveChanges(); 
    } 

    public void Initialize() 
    { 
     Context.Database.Initialize(false); 
    } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     _context.Dispose(); 
    } 

    #endregion 
} 

現在我想每一次我的ViewModels得到解決,新的IUnitOfWork實例化。我的大部分的ViewModels的是這樣的:

Container.RegisterType<IPersonRepository, PersonRepository>(); 
// resolve in InjectionProperty... 
Container.RegisterType<Object, PeopleMainView>("PeopleMainView", new InjectionProperty(PeopleMainView.DataContextProperty.Name, Container.Resolve<PeopleMainViewModel>(); 

我的問題是,如何註冊我ViewModel S和:

public class PeopleMainViewModel : NotificationObject 
{ 
    // both of repositories must have same instance of IUnitOfWork 
    private readonly IPersonRepository _personRepository = ServiceLocator.Current.GetService<IPersonRepository>(); 
    private readonly ICategoryRepository _categoryRepository = ServiceLocator.Current.GetService<ICategoryRepository>(); 

    public PeopleMainViewModel() 
    { 
     InitializeView(); 
    } 

    // add, edit, remove commands ... 
} 

的ViewModels總是被使用Unity集裝箱這樣的解決IUnitOfWork每個人都有IUnitOfWork實例嗎?

回答

0

更新: 還有另一種解決方案here in unity.codeplex discussions

我終於找到了解決辦法。 Unity容器有一個功能,可以在解析Type時傳遞參數。通過將ViewModels的構造函數更改爲:

public class PeopleMainViewModel : NotificationObject 
{ 
    private readonly IPersonRepository _personRepository = null; 
    private readonly ICategoryRepository _categoryRepository = null; 

    public PeopleMainViewModel(IUnityContainer container, IUnitOfWork unitOfWork) 
    { 
     // now both of repositories have same instance of IUnitOfWork 
     _personRepository = container.Resolve<IPersonRepository>(new ParameterOverride("unitOfWork", unitOfWork)); 
     _categoryRepository = container.Resolve<ICategoryRepository>(new ParameterOverride("unitOfWork", unitOfWork)); 
     InitializeView(); 
    } 

    // add, edit, remove commands ... 
} 

問題已解決。現在_personReposiotry_categoryRepository參照unitOfWork的同一個實例。

+0

您正在像服務定位器一樣傳遞容器。這是不正確的使用DI和容器。 – antinutrino 2017-01-26 10:52:45

0

如果我理解你的問題,只需在上面的例子中註冊你的註冊倉庫的IUnitOfWork相同的方式(和相同的地方)。由於您沒有使用接口,因此您無需根據當前設計註冊ViewModel。

Container.RegisterType<IUnitOfWork, UnitOfWork>(); 

,然後繼續讓你的倉庫接受在構造函數中IUnitOfWork。這將允許Unity在每次解析存儲庫時使用構造函數注入來提供一個新的IUnitOfWork實例。默認情況下,您每次都會得到一個新的IUnitOfWork實例。如果你想有一個單身IUnitOfWork,你不得不說,所以,當你註冊IUnitOfWork這樣的:

Container.RegisterType<IUnitOfWork, UnitOfWork>(new ContainerControlledLifetimeManager()); 

如果你想在一生經理讀了,你可以這樣做here

我也建議改變你的ViewModels採取的構造函數傳遞參數庫,這樣,如果你要解決這些問題(因此統一將做的工作沒有你引用直接ServiceLocator

public PeopleMainViewModel(IPersonRepository personRepo, ICategoryRepository categoryRepo) 
{ 
... 
} 
+0

謝謝你的回答,但正如我所問,我希望每次ViewModel實例化,新的IUnitOfWork實例化,而不是每個REPOSITORY!我的意思是,ViewModel中的所有存儲庫必須具有相同的IUnitOfWork對象實例。 – Jalal 2012-08-12 18:30:45

+1

然後讓ViewModel在構造函數中獲取IUnitOfWork的一個實例,並將其傳遞到該ViewModel中使用的所有存儲庫中。 – 2012-08-13 03:35:45

+0

手動傳遞?我有任何方式Unity容器爲我做? – Jalal 2012-08-13 05:08:54