Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

dependency injection - blazor wasm how to inject from di into custom class

is there a way to inject let say httpClient into my own custom class?

Just to be clear - i known how to use DI in blazor injecting into components or other services. Just for testing its possibility.

i want to do something like just in code

protected override async Task OnInitializedAsync()
{
  GSP gsp = new GSP("db1","table1");
  gsp.get("users", ()=>{ do something with data}); // and this should call api and get users
}

so i have

public class GSP
{
    [Inject]
    public HttpClient httpClient { get; set; }
 ...
}

but it is null

i checked also ctor option

    public GSP(HttpClient httpClient)
    {
        this.httpClient = httpClient;
    }

but then i have to pass this httpClient manualy that was injected into component for example.

i can do

  private HttpClient httpClient = new HttpClient { BaseAddress }

but then i have no BaseAdres. and heare we go again - easier way to get this BaseAddres in this place ? ;)

is it possible? or it is just 'bad practise' thats why i canot find that? thanks a lot !

question from:https://stackoverflow.com/questions/65901915/blazor-wasm-how-to-inject-from-di-into-custom-class

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

1 Answer

0 votes
by (71.8m points)

I think the explanations in this article are quite good:

Complex services might require additional services. In the following example, DataAccess requires the HttpClient default service. @inject (or the [Inject] attribute) isn't available for use in services. Constructor injection must be used instead. Required services are added by adding parameters to the service's constructor.

You are on the right track here:

 public GSP(HttpClient httpClient)
    {
        this.httpClient = httpClient;
    }

But this is where you are mistaken

but then i have to pass this httpClient manualy that was injected into component for example.

Don't pass anything manually. Instead inject your GSP class into your component.

in your razor component base class:

   [Inject]
    public GSP myGspService { get; set; }

or directly in the razor file:

@Inject GSP myGspService

If you want a new instance each time you use it, inject a GSPFactory class. You cannot inject non-registered parameters (such as your "db1" and "table1") using DI directly, the factory class would have to deal with that, or you would have to set them each timeyou create it..

in your razor component base class:

   [Inject]
    public GSPFactory myGspService { get; set; }

or directly in the razor file:

@Inject GSPFactory myGspService

and your factory class:

public class GSPFactory {
   Func<GSP> iocFactory;
   public GSPFactory(Func<GSP> iocFactory) {}
      this.iocFactory = iocFactory;
   }

   public GSP Create(string option1, string option2) {
      var gsp = this.iocFactory();
      gsp.Option1 = option1;
      gsp.Option2 = option2;
      return gsp;
   }
}

The setup could look like this:

Services.AddTransient<GSP>()
.AddTransient<Func<GSP>>(x => () => x.GetService<GSP>())
.AddSingleton<GSPFactory>() // (... plus httpClient etc)

factory class variant if you insist on having an injected property:

public class GSPFactory {
   HttpClient httpClient;
   public GSPFactory(HttpClient httpClient) {}
      this.httpClient= httpClient;
   }

   public GSP Create(string option1, string option2) {
      var gsp = new GSP(option1, option2);
      gsp.HttpClient= httpClient;
      return gsp;
   }
}

The setup could then simply look like this:

Services.AddSingleton<GSPFactory>() // (... plus httpClient etc)

In any case, you would always inject the factory, and get a new instance of GSP like this:

injectedGspFactory.Create("db1", "table1");

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...