2012-08-12 23 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