继承依赖注入简化

时间:2016-04-27 22:32:39

标签: c# inheritance design-patterns

这个有点复杂,所以请仔细阅读。我正在研究一些为WPF实现MVVM模式的代码。我有一个XAML Markup扩展,用于在datacontext上查找特定属性。 (这是一个漫长而有趣的故事,但超出范围)我的视图模型将被设置为视图上的Dataconext。

以下是我如何实现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 Markup将寻找并使用我的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的实例时都不必调用基本构造函数?

即。我希望ReportingViewModel看起来像这样

internal class ReportingViewmodel : ViewModelBase
{
    private readonly IReportingRepository _reportingRepository;

    public ReportingViewmodel(IReportingRepository reportingRepository)
    {
        _reportingRepository = reportingRepository;
    }
}

但仍然正确填充了ExampleService。

我目前正在考虑使用服务定位器模式,我也在考虑使用Singleton,我对其他更好的解决方案持开放态度。

我问这个问题而不是深入研究代码的原因是我知道Singleton通常是反模式,对我来说它意味着代码中还有其他错误。 我刚刚阅读了一篇关于IoC的文章,它正在调整服务定位器模式,这是文章http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container

1 个答案:

答案 0 :(得分:2)

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

我使用ReSharper。 (我可以这么说吗?我不是故意做广告。)在许多其他事情中,它会为你生成那些基础构造函数。我确信在某些时候必须内置到Visual Studio中。

相关问题