这个有点复杂,所以请仔细阅读。我正在研究一些为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。
答案 0 :(得分:2)
你无法退出调用基础构造函数。
IExampleService
仅被实例化一次并共享并不重要。你的ViewModelBase
没有(也不应该)“知道”那个。它需要知道的是,注入的任何东西都实现了该接口。
这是一个很大的好处,因为当您对测试类进行单元化时,您可以注入该接口的模拟版本。如果类依赖于对基类中隐藏的东西的静态引用,那么就不可能用模拟代替它来进行测试。
我使用ReSharper。 (我可以这么说吗?我不是故意做广告。)在许多其他事情中,它会为你生成那些基础构造函数。我确信在某些时候必须内置到Visual Studio中。