【问题标题】:Dependency injection and base classes依赖注入和基类
【发布时间】:2020-01-30 05:39:39
【问题描述】:

这是在使用 Prism 的 xamarin.forms 应用程序中,但这个问题更像是一个基础的 c# 问题,我对此感到困惑。

我正在使用依赖注入,并且我的类型已在 app.xaml.cs 文件中注册 -> RegisterTypes 方法。

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterDialog<BusyDialog, BusyDialogViewModel>();

        containerRegistry.RegisterForNavigation<NavigationPage>();
        containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();
    }

我的基本视图模型ctor定义为:

    public ViewModelBase(INavigationService navigationService, IDialogService dialogService)
    {
        NavigationService = navigationService;
        DialogService = dialogService;
    }

所有其他视图模型都派生了这个基类。例如。

    public MainPageViewModel(INavigationService navigationService, IDialogService dialogService)
        : base(navigationService, dialogService)
    {
    }

我的问题是,在这个 MainPage ctor 中,我正在注入“INavigationService navigationService,IDialogService dialogService”。在我的所有视图模型中,我使用的是 NavigationService 和 DialogService(来自基类),所以这不是多余的代码吗?

我有大约 20 个视图模型,我将 IDialogService 添加到我的基类中,并意识到我必须更新每个视图模型中的构造函数。

有没有办法只注入基类并可供派生此基类的所有类使用,而无需在类构造函数中指定?

【问题讨论】:

  • 派生类需要在参数的情况下指定在基中调用哪个构造函数
  • 不,你不能注入基类。当你从一个类派生并且它有一个非空ctor时,派生类负责调用父类ctor。
  • 这能回答你的问题吗? Constructor Dependency Injection in Base Class
  • @Cheesebaron 在您提供的链接中看起来也没有可接受的答案。我的问题仍然存在。
  • 这可能是因为没有明确的答案。选择喜欢的解决方案。您要么使用具有所有依赖项的“中间件”类,然后通过它调用它们。或者您只需将base() 调用添加到所有继承类。另一种选择是使用组合而不是继承。哪一个是“最好的”主要是基于意见......

标签: c# xamarin xamarin.forms


【解决方案1】:

将依赖项注入基本类型的简单方法是定义一个新类型来保存所有依赖项;

public class ViewModelBaseDependencies{
    public ViewModelBaseDependencies(INavigationService navigationService, IDialogService dialogService){
    //...
}
public ViewModelBase(ViewModelBaseDependencies dependencies)
{
    NavigationService = dependencies.NavigationService;
    DialogService = dependencies.DialogService;
}
public MainPageViewModel(ViewModelBaseDependencies dependencies)
        : base(dependencies)

那么你只需要传递一个构造函数参数,就可以轻松添加新的依赖项了。

【讨论】:

  • 我没有关注。这堂课会在哪里?我的 baseviewmodel 和其他派生类如何知道这一点?你能用 ViewModelBase 和 MainPageViewModel:ViewModelBase 修改你的例子吗?
  • 示例中添加了构造函数
  • Navigation/DialogService 在我的 ViewModelBaseDependencies 中定义为属性。所以我的 ViewModelBase 不会有 Navigation/DialogService 类型的属性。公共类 ViewModelBaseDependencies { 公共 INavigationService NavigationService { 获取;私人套装; } 公共 IDialogService DialogService { 获取;私人套装; } 公共 ViewModelBaseDependencies(INavigationService navigationService, IDialogService dialogService) { NavigationService = navigationService;对话服务 = 对话服务; } }
猜你喜欢
  • 2020-03-17
  • 1970-01-01
  • 2012-03-08
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-23
相关资源
最近更新 更多