blazor wasm 如何从 di 注入自定义类
Posted
技术标签:
【中文标题】blazor wasm 如何从 di 注入自定义类【英文标题】:blazor wasm how to inject from di into custom class 【发布时间】:2021-04-30 06:29:34 【问题描述】:有没有办法将 httpClient 注入到我自己的自定义类中?
明确一点 - 我知道如何在 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 的更简单的方法? ;)
有可能吗?或者这只是“糟糕的做法”,这就是我找不到的原因? 非常感谢!
【问题讨论】:
重复? ***.com/questions/65629065/… 关闭但没有,因为我想自己创建对象并将 DI 注入作为该类的属性 【参考方案1】:通过 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();
【讨论】:
【参考方案2】:我觉得this article里的解释还不错:
复杂的服务可能需要额外的服务。在下面的 例如,DataAccess 需要 HttpClient 默认服务。 @注入 (或 [Inject] 属性)不可用于服务。 必须改用构造函数注入。所需的服务是 通过向服务的构造函数添加参数来添加。
你在正确的轨道上:
public GSP(HttpClient httpClient)
this.httpClient = httpClient;
但这是你误会的地方
但是我必须手动传递这个注入的 httpClient 以组件为例。
不要手动传递任何东西。而是将您的 GSP
类注入到您的组件中。
在您的剃须刀组件基类中:
[Inject]
public GSP myGspService get; set;
或直接在剃刀文件中:
@Inject GSP myGspService
如果您每次使用时都想要一个新实例,请注入一个GSPFactory
类。您不能直接使用 DI 注入未注册的参数(例如您的“db1”和“table1”),工厂类必须处理它,或者您必须在每次创建时设置它们..
在您的剃须刀组件基类中:
[Inject]
public GSPFactory myGspService get; set;
或直接在剃刀文件中:
@Inject GSPFactory myGspService
和你的工厂类:
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)
如果你坚持要注入属性,工厂类变体:
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");
【讨论】:
thx 我更新了我的 quastion,因为我稍微简化了它,我现在看到这也很重要 - 如果我想使用自己的 ctor,比如 new GSP("db1","table1"); ?也有可能吗?或者这是限制 - 我可以像你发布的那样 DI 这个 GSP 但不能使用自己的 ctors?以上是关于blazor wasm 如何从 di 注入自定义类的主要内容,如果未能解决你的问题,请参考以下文章
Blazor 应用程序作为 WASM 或服务器运行。无法让依赖注入在服务器模式下工作
在自定义类中访问 Blazor 服务器端的 AuthenticationStateProvider