我的问题有两个部分。
首先是,如何使用依赖注入创建ViewModel
类的多个实例?例;
我正在使用MVVM
模式创建一个WPF
应用程序,Dependency Injection
Ninject
和SQLite
Database
EntityFramework.Core
。它的结构是这样的;
- 我有一个
View
,比如说Tier1View
绑定到一个ViewModel
,Tier1ViewModel
. - 在
Tier1View
内是一个ItemsControl
,带有Tier2UserControl
DataTemplate
,ItemsControl
的ItemSource
是一种有效Binding
ObservableCollection<Tier2ViewModel>
Data Context
每个Tier2UserControl
到一个实例Tier2ViewModel
. - 反过来,每个
Tier2UserControl
都有一个 项目控件Tier3UserControl
绑定ObservableCollection<Tier3ViewModel>
.
由于 Tier2 和 Tier3 ViewModel 的集合在编译时的大小不确定,因为它们依赖于数据库中的表作为初始数据,并且可以在运行时更改,这消除了以像此示例这样粗糙的方式使用构造函数注入的可能性(以至于我甚至羞于考虑它(。
public Tier1ViewModel(ITier2ViewModel firstInstance, ITier2ViewModel secondInstance, ...)
{
Collection.add(firstInstance);
Collection.add(secondInstance);
...
}
如何在同一类中创建依赖项的多个实例?之前有人建议我使用工厂(由 Ninject 支持(来解决我提出的关于将变量传递给注入依赖项的问题,并且我已经创建了成功的实现。
Collection.Add(IViewModelFactory.CreateTierNViewModel());
并将工厂注入到上层的构造函数中。
然而,这导致了我问题的第二部分。
每个实例都需要在集合中可识别 - 因此Run-Time Data
必须传递给每个实例"已创建"。
根据本文,使用工厂会增加应用程序的复杂性和可维护性。在我更好地理解编程的目标中,我试图避免的事情。它还指出,运行时数据不应注入到对象的构造中,而应通过方法传入。
通过包含来自SQLite
数据库的唯一Entities
来区分Tier3ViewModels
(它们实际上是这些Entities
View Models
(,因为Entities
只能在run-time
时知道,是创建依赖项实例的正确方法(由于缺乏对其他方式的了解, 使用工厂(,然后在该ViewModel
中有一个方法,将我的实体作为参数(或者更好的是该实体的抽象,例如IEntityType
(?
var instanceOf = Factory.CreateViewModel();
instanceOf.AddingMethod(IEntity);
我希望其中一些是可以翻译的!提前感谢任何帮助!
如果必须在 ViewModel 上传递数据对象,则在构造函数中声明这些对象。
public class Tier2ViewModel
{
public Tier2ViewModel(Tier2Entity tier2Entity) { //... }
}
从那里,您可以在不使用依赖项注入的情况下创建Tier2ViewModel
,只需在Tier1ViewModel
类中手动创建它们。
public class Tier1ViewModel
{
private void LoadTier2()
{
//TODO: load tier2Entities using EF
//TODO: foreach tier2Entity, create new Tier2ViewModel
//TODO: add each Tier2ViewModel instance to ObservableCollection<Tier2ViewModel>
}
}
但是,如果您真的想使用依赖注入,那么您就走上了使用Factory
类的正确轨道。而是在CreateViewModel
方法上传递Entity
对象。
public interface ITier2ViewModelFactory
{
Tier2ViewModel CreateViewModel(Tier2Entity tier2Entity);
}
public class Tier2ViewModelFactory : ITier2ViewModelFactory
{
public Tier2ViewModel CreateViewModel(Tier2Entity tier2Entity)
{
return new Tier2ViewModel(tier2Entity);
}
}
public class Tier1ViewModel
{
private readonly ITier2ViewModelFactory _tier2ViewModelFactory;
private void LoadTier2()
{
//TODO: load tier2Entities using EF
//TODO: foreach tier2Entity, call _tier2ViewModelFactory.CreateViewModel(tier2Entity)
//TODO: add each Tier2ViewModel instance to ObservableCollection<Tier2ViewModel>
}
如您所见,工厂添加了另一层抽象,对我来说,这对于使用 DI 创建实例是不必要的。就个人而言,我只会在对象的实例化涉及需要测试的复杂逻辑时才使用Factory
模式。