将服务注入到 .NET MAUI 应用程序中的视图模型中

Sam*_*Sam 18 xamarin xamarin.forms maui .net-maui

我试图了解如何在 .NET MAUI 应用程序中实现依赖注入。

我有一个服务类及其接口,用于处理我的 REST 调用,如下所示:

public class MyRestApiService : IMyRestApiService
{
   public async Task<string> Get()
   {
      // Do someting
   }
}
Run Code Online (Sandbox Code Playgroud)

然后我将其放入我的 DI 容器中MauiProgram.cs

builder.Service.AddTransient<IMyRestApiService, MyRestApiService>();
Run Code Online (Sandbox Code Playgroud)

我还有一个将用于我的MainPage.xaml. 问题是,如果我对服务进行构造函数注入,XAML 似乎不喜欢它。

看起来MainPageViewModel像这样:

public class MainPageViewModel : BaseViewModel
{
   IMyRestApiService _apiService;
   public MainPageViewModel(IMyRestApiService apiService)
   {
      _apiService = apiService;
   }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试定义如下MainPageViewModel视图模型时MainPage.xaml,出现错误:

<ContentPage.BindingContext>
   <vm:MainPageViewModel />
</ContentPage.BindingContext>
Run Code Online (Sandbox Code Playgroud)

错误如下:

MainPageViewModel 类型不能用作对象元素,因为它不是公共的,或者没有定义公共无参数构造函数或类型转换器。

如何将我的服务注入到我的视图模型中?

Ger*_*uis 17

您将需要基本上从第一页开始解决所有问题,以便所有内容都就位并让依赖项注入正常工作。

看看这个例子:https://github.com/jfversluis/MauiDependencyInjectionSample

您将需要注册您的服务、视图模型和视图。在您的情况下,在您的MauiProgram.cs添加中:

// Change scopes as needed, this seems to make sense
builder.Service.AddTransient<MainPage>();
builder.Service.AddTransient<MainPageViewModel>();
builder.Service.AddSingleton<IMyRestApiService, MyRestApiService>();
Run Code Online (Sandbox Code Playgroud)

然后在您App.xaml.cs的(主)页面中也开始注入:

public partial class App : Application
{
    public App(MainPage page)
    {
        InitializeComponent();

        MainPage = page;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在你MainPage.xaml.cs添加一个像这样的构造函数:

public LoginPage(MainPageViewModel viewModel)
{
    InitializeComponent();

    BindingContext = viewModel;
}
Run Code Online (Sandbox Code Playgroud)

从那里开始,一切都应该遵循并连接起来。你想做什么

<ContentPage.BindingContext>
   <vm:MainPageViewModel />
</ContentPage.BindingContext>
Run Code Online (Sandbox Code Playgroud)

基本上是BindingContext通过属性来设置的。您可以,但是您必须自己指定参数并以某种方式从依赖项注入容器中解析它们,这通常是您不想做的。

  • 要让 Intellisense 回到 xaml 部分,您还可以添加: ```xmlns:vm="clr-namespace:SomeViewModels"``` ```x:DataType ="vm:SomeViewModel"``` (4认同)
  • @MichalDiviš 谢谢你!我的意思是在 .NET MAUI 存储库中:D 和 Sam,您可能不希望页面和视图模型具有单例,因为它们现在将保留状态。例如,如果您打开某个产品的页面,并且用户编辑了一些内容,那么这些编辑最终可能会出现在您下次打开的其他产品中。 (2认同)