我有一个使用MVVM模式的WPF应用程序。我正在使用Autofac作为DI容器。像其他类似于我的应用程序一样,我有一个ViewModelBase类,该类实现INotifyPropertyChanged接口,并且还解析在容器中注册的依赖项:
public class ViewModelBase : ObservableObject
{
protected IErrorHandler _errorHandler;
protected IEventAggregator _eventAggregator;
protected ICustomDialogService _customDialogService;
protected IUserSettingsRepository _userSettingsRepository;
protected IReferralRepository _referralRepository;
protected Notification _notification;
protected IPrinting _printingService;
protected ILookupRepository _lookupRepository;
protected IWorklistRepository _worklistRepository;
protected IDialogCoordinator _dialogCoordinator;
public ViewModelBase()
{
_errorHandler = AppContainer.Resolve<IErrorHandler>();
_eventAggregator = AppContainer.Resolve<IEventAggregator>();
_customDialogService = AppContainer.Resolve<ICustomDialogService>();
_userSettingsRepository = AppContainer.Resolve<IUserSettingsRepository>();
_referralRepository = AppContainer.Resolve<IReferralRepository>();
_notification = AppContainer.Resolve<Notification>();
_printingService = AppContainer.Resolve<IPrinting>();
_lookupRepository = AppContainer.Resolve<ILookupRepository>();
_worklistRepository = AppContainer.Resolve<IWorklistRepository>();
_dialogCoordinator = AppContainer.Resolve<IDialogCoordinator>();
}
}
该应用程序有大约20个视图模型,所有视图模型都需要使用不同的依赖项-有时将不需要。每个视图模型都可以访问这些依赖关系(即使永远不会使用它们)是一种好习惯吗?
答案 0 :(得分:4)
通常,您是通过类构造函数或类似的方法提供依赖项的,而不是从构造函数内部提供的。因此,实际上您的课程都不应该知道您的DI容器的所有内容。相反,容器在 calling 上下文中解析依赖项,并将其提供给类构造函数。解决呼叫依存关系的呼叫者责任,不是班级的责任。这是控制原理反转的重点。
话虽如此,您的依存关系应通过以下方式解决:
var errorHandler = AppContainer.Resolve<IErrorHandler>();
var eventAggregator = AppContainer.Resolve<IEventAggregator>();
var myModel = new MyModel(errorHandler, eventAggregator);
通过这种方式myModel
仅获得正常运行所需的依赖项。
要创建另一个模型:
var customDialogService = AppContainer.Resolve<ICustomDialogService>();
var userSettingsRepository = AppContainer.Resolve<IUserSettingsRepository>();
var myModel = new MyModel2(customDialogService, userSettingsRepository);
答案 1 :(得分:3)
您的ViewModelBase
类出现以下问题:
因此,使用包含依赖项或 volatile 行为(即您希望在测试套件中模拟,替换或拦截的行为)的基类是个坏主意。
其他方法比使用基类对公共依赖项进行分组更为有效,例如: