代码之家  ›  专栏  ›  技术社区  ›  Tristan Trainer Ferguson Osas

如何使用ninject在c中创建viewmodel的多个实例,同时避免代码气味?

  •  1
  • Tristan Trainer Ferguson Osas  · 技术社区  · 7 年前

    我的问题有两部分。

    首先,如何创建 ViewModel 使用依赖注入的类?例子;

    我正在创建一个 WPF 应用程序使用 MVVM 模式, Dependency Injection 具有 Ninject 和一个 SQLite Database 具有 EntityFramework.Core . 它的结构是这样的;

    • 我有一个 View Tier1View 那一定是 视图模型 , Tier1ViewModel .
    • 第1视图 是一个 ItemsControl 用一个 DataTemplate 属于 Tier2UserControl , the ItemSource 对于 项目控制 是一个 ObservableCollection<Tier2ViewModel> 有效地 Binding 这个 Data Context 对于每一个 第二层用户控件 以…为例 Tier2ViewModel .
    • 依次每个 第二层用户控件 具有项控件 Tier3UserControl 绑定到 ObservableCollection<Tier3ViewModel> .

    由于TIER2和TIER3视图模型的集合在编译时的大小不确定,因为它们依赖于数据库中的表以获取初始数据,并且可以在运行时改变,这就排除了使用构造函数注入的方式这样粗略的可能性。我甚至羞于考虑它)。

    public Tier1ViewModel(ITier2ViewModel firstInstance, ITier2ViewModel secondInstance, ...)
    {
        Collection.add(firstInstance);
        Collection.add(secondInstance);
        ...
    }
    

    如何在同一个类中创建依赖项的多个实例?以前有人建议我使用一个工厂(ninject支持它)来解决我提出的一个问题,即如何将变量传递给一个注入的依赖项,我已经成功地实现了这一点。

    Collection.Add(IViewModelFactory.CreateTierNViewModel());
    

    并将工厂注入到上述层的构造函数中。

    然而这引出了我问题的第二部分。

    每个实例都需要在集合中标识,因此 Run-Time Data 必须传递给每个实例“created”。

    根据 this 文章,使用工厂增加了应用程序的复杂性和可维护性。为了更好地理解编程,我正在努力避免一些事情。它还指出,运行时数据不应注入对象的构造中,而应通过方法传入。

    这个 Tier3ViewModels 通过包含唯一的 Entities 数据库 数据库(实际上是 View Models 那些 实体 ),因为 实体 只能知道 run-time ,是创建依赖项实例的正确方法(对于使用工厂的其他方法缺乏了解),然后在其中包含方法 小精灵 它将我的实体作为一个参数(或者更好的是对该实体的抽象,比如 IEntityType )?

    var instanceOf = Factory.CreateViewModel();
    instanceOf.AddingMethod(IEntity);
    

    我希望其中一些是可翻译的!提前感谢您的帮助!

    1 回复  |  直到 7 年前
        1
  •  1
  •   Jan Paolo Go vikomall    7 年前

    如果必须在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 班级。但是却通过了 Entity 上的对象 CreateViewModel 方法。

    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创建了一个实例。就我个人而言,我只会使用 工厂 模式,如果对象的实例化将涉及需要测试的复杂逻辑。