blazor wasm 如何从 di 注入自定义 class
blazor wasm how to inject from di into custom class
有没有办法将 httpClient 注入我自己的自定义 class?
澄清一下 - 我知道如何在 blazor 中使用 DI 注入组件或其他服务。
只是为了测试它的可能性。
我想在代码中做一些类似的事情
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
}
所以我有
public class GSP
{
[Inject]
public HttpClient httpClient { get; set; }
...
}
但它是null
我还检查了 ctor 选项
public GSP(HttpClient httpClient)
{
this.httpClient = httpClient;
}
但是我必须手动传递这个注入到组件中的 httpClient。
我可以
private HttpClient httpClient = new HttpClient { BaseAddress }
但是我没有 BaseAdres。听说我们又来了——在这个地方获取这个 BaseAddres 的更简单的方法? ;)
可能吗?或者只是 'bad practise' 这就是我找不到的原因?
非常感谢!
通过 ctor 和 HttpClientFactory 你可以做这样的事情:
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services
.AddTransient<GSP>()
.AddHttpClient().ConfigureHttpClient(httpClient =>
{
httpClient.BaseAddress = builder.HostEnvironment.BaseAddress;
});
await host.RunAsync();
}
}
或没有 HttpClientFactory
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services
.AddTransient(p => new GSP(new HttpClient { BaseAddress = builder.HostEnvironment.BaseAddress });
await host.RunAsync();
}
}
我觉得this article里面的解释很好:
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.
你走在正确的轨道上:
public GSP(HttpClient httpClient)
{
this.httpClient = httpClient;
}
但你错了
but then i have to pass this httpClient manualy that was injected into
component for example.
不要手动传递任何东西。而是将 GSP
class 注入到您的组件中。
在你的剃须刀组件库中 class:
[Inject]
public GSP myGspService { get; set; }
或直接在 razor 文件中:
@Inject GSP myGspService
如果每次使用都想要一个新的实例,注入一个GSPFactory
class。您不能直接使用 DI 注入未注册的参数(例如您的“db1”和“table1”),工厂 class 必须处理这个问题,或者您必须在每次创建时设置它们。
在你的剃须刀组件库中 class:
[Inject]
public GSPFactory myGspService { get; set; }
或直接在 razor 文件中:
@Inject GSPFactory myGspService
和你的工厂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;
}
}
设置可能如下所示:
Services.AddTransient<GSP>()
.AddTransient<Func<GSP>>(x => () => x.GetService<GSP>())
.AddSingleton<GSPFactory>() // (... plus httpClient etc)
factory class 变体如果你坚持注射 属性:
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;
}
}
设置可能看起来像这样:
Services.AddSingleton<GSPFactory>() // (... plus httpClient etc)
在任何情况下,您总是会注入工厂,并像这样获得一个新的 GSP 实例:
injectedGspFactory.Create("db1", "table1");
有没有办法将 httpClient 注入我自己的自定义 class?
澄清一下 - 我知道如何在 blazor 中使用 DI 注入组件或其他服务。 只是为了测试它的可能性。
我想在代码中做一些类似的事情
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
}
所以我有
public class GSP
{
[Inject]
public HttpClient httpClient { get; set; }
...
}
但它是null
我还检查了 ctor 选项
public GSP(HttpClient httpClient)
{
this.httpClient = httpClient;
}
但是我必须手动传递这个注入到组件中的 httpClient。
我可以
private HttpClient httpClient = new HttpClient { BaseAddress }
但是我没有 BaseAdres。听说我们又来了——在这个地方获取这个 BaseAddres 的更简单的方法? ;)
可能吗?或者只是 'bad practise' 这就是我找不到的原因? 非常感谢!
通过 ctor 和 HttpClientFactory 你可以做这样的事情:
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services
.AddTransient<GSP>()
.AddHttpClient().ConfigureHttpClient(httpClient =>
{
httpClient.BaseAddress = builder.HostEnvironment.BaseAddress;
});
await host.RunAsync();
}
}
或没有 HttpClientFactory
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services
.AddTransient(p => new GSP(new HttpClient { BaseAddress = builder.HostEnvironment.BaseAddress });
await host.RunAsync();
}
}
我觉得this article里面的解释很好:
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.
你走在正确的轨道上:
public GSP(HttpClient httpClient)
{
this.httpClient = httpClient;
}
但你错了
but then i have to pass this httpClient manualy that was injected into component for example.
不要手动传递任何东西。而是将 GSP
class 注入到您的组件中。
在你的剃须刀组件库中 class:
[Inject]
public GSP myGspService { get; set; }
或直接在 razor 文件中:
@Inject GSP myGspService
如果每次使用都想要一个新的实例,注入一个GSPFactory
class。您不能直接使用 DI 注入未注册的参数(例如您的“db1”和“table1”),工厂 class 必须处理这个问题,或者您必须在每次创建时设置它们。
在你的剃须刀组件库中 class:
[Inject]
public GSPFactory myGspService { get; set; }
或直接在 razor 文件中:
@Inject GSPFactory myGspService
和你的工厂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;
}
}
设置可能如下所示:
Services.AddTransient<GSP>()
.AddTransient<Func<GSP>>(x => () => x.GetService<GSP>())
.AddSingleton<GSPFactory>() // (... plus httpClient etc)
factory class 变体如果你坚持注射 属性:
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;
}
}
设置可能看起来像这样:
Services.AddSingleton<GSPFactory>() // (... plus httpClient etc)
在任何情况下,您总是会注入工厂,并像这样获得一个新的 GSP 实例:
injectedGspFactory.Create("db1", "table1");