【问题标题】:Inject many classes in view model class在视图模型类中注入许多类
【发布时间】:2011-01-14 20:30:22
【问题描述】:

我使用 MVVM 设计开发 wpf 应用程序。作为 MVVM 框架,我使用 Caliburn Micro。我在外部程序集中拥有的服务,它通过 MEF 注入到视图模型类中。

服务中的问题我有很多小班,我尽量尊重SOLID原则。

[Export(typeof(IClassA)]
public class ClassA : IClassA
{}

[Export(typeof(IClassB)]
public class ClassB : IClassB
{}

[Export(typeof(IClassC)]
public class ClassC : IClassC
{}

//...
[Export(typeof(IClassK)]
public class ClassK : IClassK
{}

班级数约为 12-15。

我需要在视图模型类中使用这些类。所以我用这个:

public class MyViewModelClass
{
 private interface IClassA _a;
 private interface IClassB _b;
 private interface IClassC _c;


//...
 private interface IClassK _k;


[ImportingConstructor]
public MyViewModelClass(IClassA a, IClassB b, IClass c, ..., IClassK k)
{
_a=a; _b=b; _c=c; ...  _k=k

}

}

我不认为这种方式是正确的。或者它存在一些优雅、简单的东西。感谢您的意见和建议。

【问题讨论】:

    标签: wpf mvvm mef caliburn.micro


    【解决方案1】:

    致:阿贝·海德布莱希特。

    我有点困惑。如果我使用这个:

    public class MyViewModelClass : IPartImportsSatisfiedNotification
    {
        [Import]
        private IClassA _a;  // I need init _a?
        [Import]
        private IClassB _b; 
        [Import]
        private IClassC _c;
    
        ...
    
        public void OnImportsSatisfied()
        {
            // what code must be here ?
            //how can I check if all import was success
        }
    }
    

    因为。

    IPartImportsSatisfiedNotification 只有一个方法:OnImportsSatisfied,当所有可以满足的导入都满足时调用。

    我认为最好在视图模型类的构造函数中对服务类的初始化接口进行单元测试。

    【讨论】:

    • OnImportsSatisfied 不会被调用,除非所有导入都成功。基本上,该方法中的代码将是您放入构造函数中的代码,用于在构造函数中正常初始化对象。由于导入在您的构造函数中不可用,因此在调用该方法之前您不能使用它们。如果无法满足任何导入,则会抛出正常的 MEF 异常,提醒您缺少导出。
    【解决方案2】:

    MEF 可以导入到字段(甚至是私有字段)。如果您想让您的生活更轻松一点,您可以使用ImportAttribute 来装饰这些字段。如果您想知道所有导入何时完成,只需实现IPartImportsSatisfiedNotification 接口即可:

    public class MyViewModelClass : IPartImportsSatisfiedNotification
    {
        [Import]
        private IClassA _a; 
        [Import]
        private IClassB _b; 
        [Import]
        private IClassC _c;
    
        ...
    
        public void OnImportsSatisfied()
        {
            // add initialization code here
        }
    }
    

    这几乎需要您使用 MEF 来确保正确实例化您的 ViewModel,但取决于您的场景,这可能不是什么大问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      • 2018-08-25
      • 2021-12-26
      • 2018-06-18
      • 1970-01-01
      • 1970-01-01
      • 2011-08-07
      相关资源
      最近更新 更多