C# 继承依赖注入简化

C# 继承依赖注入简化,c#,inheritance,design-patterns,C#,Inheritance,Design Patterns,这个有点复杂,所以请通读一遍。我正在编写一些代码来实现WPF的MVVM模式。我有一个XAML标记扩展,用于查找datacontext上的特定属性。(这是一个很长很有趣的故事,但超出了范围)我的视图模型将被设置为视图上的DataConNext 下面是我如何实现BaseViewmodel的示例 public class ViewModelBase : IViewModelBase { protected CommandManagerHelper _commandManagerHelper;

这个有点复杂,所以请通读一遍。我正在编写一些代码来实现WPF的MVVM模式。我有一个XAML标记扩展,用于查找datacontext上的特定属性。(这是一个很长很有趣的故事,但超出了范围)我的视图模型将被设置为视图上的DataConNext

下面是我如何实现BaseViewmodel的示例

public class ViewModelBase : IViewModelBase
{
    protected CommandManagerHelper _commandManagerHelper;

    //todo find a way of eliminating the need for this constructor
    public OrionViewModelBase(CommandManagerHelper commandManagerHelper)
    {
        _commandManagerHelper = commandManagerHelper;
    }

    private IExampleService _exampleService;

    public IExampleService ExampleService
    {
        get
        {
            if (_exampleService == null)
            {
                _exampleService = _commandManagerHelper.GetExampleService();
            }

            return _exampleService;
        }
    }
}
这里发生的事情是,我实际上是在懒洋洋地加载exampleService。我确信使用Lazy是可能的,但是我还没有时间去实现它

我的Xaml标记将寻找并利用我的ExampleService,它也可以被视图模型中的代码使用。它将在整个应用程序中使用

需要注意的一点是,我的应用程序只有一个ExampleServer实例将被传递,从应用程序中的任意位置调用GetExampleService将返回相同的对象实例。ExampleService对象只有一个实例,尽管它没有编码为单例

下面是一个如何从ViewModelBase继承的示例

internal class ReportingViewmodel : ViewModelBase
{
    private readonly IReportingRepository _reportingRepository;

    public ReportingViewmodel(CommandManagerHelper commandManagerHelper, IReportingRepository reportingRepository) : base(commandManagerHelper)
    {
        _reportingRepository = reportingRepository;
    }
}
这段代码非常有效。但是,每次实现ViewModelBase的新继承成员时都必须键入“:base(commandManagerHelper)”很容易出错。我可能有100个这样的实现,每个都需要正确

我想知道的是。。。。有没有一种方法可以实现与SOLID原则相同的行为,而不必每次实现ViewModelBase实例时都调用base构造函数

i、 e.我希望ReportingViewModel看起来像这样

internal class ReportingViewmodel : ViewModelBase
{
    private readonly IReportingRepository _reportingRepository;

    public ReportingViewmodel(IReportingRepository reportingRepository)
    {
        _reportingRepository = reportingRepository;
    }
}
但仍然正确填充ExampleService

我目前正在考虑使用服务定位器模式来实现这一点,我也在考虑使用单例,我对其他更好的解决方案持开放态度

我之所以问这个问题而不是埋头于代码,是因为我知道单例通常是一种反模式,对我来说,它意味着代码中存在其他错误。
我刚刚读了一篇关于IoC的文章,文章中提到了服务定位器模式。

您必须调用基本构造函数。
IExampleService
只实例化一次并共享并不重要。您的
ViewModelBase
不(也不应该)“知道”这一点。它需要知道的是,注入的任何东西都实现了该接口。 这是最大的好处之一,因为当您对类进行单元测试时,您可以注入该接口的模拟版本。如果类依赖于对隐藏在基类中的某个对象的静态引用,那么就不可能用模拟来代替它进行测试


我用。(我可以这么说吗?我不是想做广告。)在许多其他事情中,它为您生成这些基本构造函数。我确信在某种程度上,它必须内置到Visual Studio中。

我也使用ReSharper:我正在寻找这个解决方案的最佳实现。我想问题还有另一个方面。我有一个使用自定义标记扩展的视图,并且必须设置视图datacontext,即使该视图实际上不需要视图模型(这是一个简单的显示对话框)。标记需要了解IExampleService,而不是视图。创建整个viewmodel仍然正确吗?或者让标记从其他地方提取扩展是否可以?(如果可以的话,意味着我可以改变viewmodels的组成方式)只需要想一想怎么做。反思一下,我认为让标记扩展在没有viewmodel的情况下工作是另一个话题。