Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
220 views
in Technique[技术] by (71.8m points)

c# - How can I send a parameter to a ViewModel that I get a reference to with this: Startup.ServiceProvider.GetRequiredService?

Can anyone give me some advice. I am using

Microsoft.Extensions.DependencyInjection version 5.0.1 nuget package

and I would like to get a reference to a ViewModel class that needs a service inject to it, and at the same time pass a parameter to the ViewModel. Here I have an example where the

My class calling a ViewModel that needs to pass a parameter to it also. Can someone tell me how I can do this?

 public class ThemeManagementPage : HeadingView
 {
  private readonly ThemeManagementViewModel _vm;
  public ThemeManagementPage(int param1)
  {
     // This page is called with a parameter and then 
     // whhat I need to do is to pass the parameter `param1`
     // to the ViewModel which I have identified 
     // as a Transient (see bottom of post)

     BindingContext  = _vm = 
         Startup.ServiceProvider.GetRequiredService<ThemeManagementViewModel>();
  }
 }

 public partial class ThemeManagementViewModel : BaseViewModel
 {
    private readonly IResourceService _resourceService;
    public ThemeManagementViewModel(IResourceService resourceService, int param1)
    {
        _resourceService = resourceService;
        var x = param1
    }
 }

For reference here is my DI setup:

 public partial class ResourceService : IResourceService
 {
    private IDatabaseService _databaseService;
    public ResourceService(IDatabaseService databaseService)
    {
        _databaseService = databaseService;
    }
 }

 public interface IResourceService
 {
    void SetResourceColors();
 }

public static class Startup
{
  public static IServiceProvider ServiceProvider { get; set; }
  public static IServiceProvider Init()
  {
     var serviceProvider = new ServiceCollection().ConfigureServices()
        .BuildServiceProvider();
     ServiceProvider = serviceProvider;
     return serviceProvider;
  }
}

 public static class DependencyInjectionContainer
 {
    public static IServiceCollection ConfigureServices(this IServiceCollection services)
    {
        services.AddSingleton<IDatabaseService, DatabaseService>();
        services.AddSingleton<IResourceService, ResourceService>();
        services.AddTransient<ThemeManagementViewModel>();
        return services;
    }
 }
question from:https://stackoverflow.com/questions/66057300/how-can-i-send-a-parameter-to-a-viewmodel-that-i-get-a-reference-to-with-this-s

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since Microsoft.Extensions.DependencyInjection nuget package is being used then consider using

ActivatorUtilities.CreateInstance Method from the included Microsoft.Extensions.DependencyInjection.Abstractions.dll

Instantiate a type with constructor arguments provided directly and/or from an IServiceProvider.

public class ThemeManagementPage : HeadingView {
    private readonly ThemeManagementViewModel _vm;

    public ThemeManagementPage(int param1) {
        _vm = ActivatorUtilities.CreateInstance<ThemeManagementViewModel>(Startup.ServiceProvider, param1);
        BindingContext  = _vm;
    }

    //...
 }

The ActivatorUtilities.CreateInstance method will use the service provider to resolve the abstraction and use that along with the other parameter provided to inject into the target type when initializing it.

Design-wise, I am not a particular fan of such Service Locator approaches, but this should provide the desired behavior.

This should be redesigned to allow all the necessary dependencies to be explicitly injected into the view model and not passed through the view constructor but that would depend on the nature of supposed run-time parameter(s) to be injected. Which is currently not clear based on the post as currently written.

Some interesting reading Dependency Injection Code Smell: Injecting runtime data into components


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...