首页 > 其他分享 >增量生成器简化BlazorServer兼容BlazorAuto模式

增量生成器简化BlazorServer兼容BlazorAuto模式

时间:2024-08-15 11:48:54浏览次数:16  
标签:BlazorServer AutoWasmApiGenerator global 生成器 System IUserService Services Blazor

本文简略介绍一下如何使用增量生成器(Incremental Generator)简化BlazorServer兼容Auto模式

比如现在有一个BlazorServer项目的Razor页面

// UserIndex.razor
@code {
    [Inject, NotNull] IUserService? Service { get; set; }
}

如果IUserService的实现不支持运行在WebAssembly,比如连接数据库,或者访问服务器文件等等,那么这种情况下,需要Server端提供接口,并且在Client端提供IUserService的接口调用实现

本文的目的就是通过增量生成器,完成Server端接口生成和Client端的接口调用

[WebController(Route = "user", Authorize = true)]
[ApiInvokerGenerate]
public interface IUserService
{
    Task<User?> GetUserAsync(string id);
}

nuget地址

dotnet add package AutoWasmApiGenerator --version 0.0.2

在Server端生成Controller

// <auto-generated/>
#pragma warning disable
namespace Project.Constraints.Services
{
    [global::Microsoft.AspNetCore.Mvc.ApiController]
    [global::Microsoft.AspNetCore.Mvc.Route("api/user")]
    [global::Microsoft.AspNetCore.Authorization.Authorize]
    [global::System.CodeDom.Compiler.GeneratedCode("AutoWasmApiGenerator.ControllerGenerator", "1.0.0.0")]
    /// <inheritdoc/>
    public class UserServiceController : global::Microsoft.AspNetCore.Mvc.ControllerBase
    {
        private readonly Project.Constraints.Services.IUserService proxyService;

        public UserServiceController(Project.Constraints.Services.IUserService service)
        {
            proxyService = service;
        }

        [global::Microsoft.AspNetCore.Mvc.HttpPost("GetUser")]
        [global::Microsoft.AspNetCore.Authorization.Authorize]
        [global::System.CodeDom.Compiler.GeneratedCode("AutoWasmApiGenerator.ControllerGenerator", "1.0.0.0")]
        public System.Threading.Tasks.Task<Project.Constraints.Models.Permissions.User?> GetUserAsync([global::Microsoft.AspNetCore.Mvc.FromBody]string id)
          => proxyService.GetUserAsync(id);
    }
}

在Client端生成调用类

// <auto-generated/>
#pragma warning disable
namespace Project.Constraints.Services
{
    [global::System.CodeDom.Compiler.GeneratedCode("AutoWasmApiGenerator.HttpServiceInvokerGenerator", "1.0.0.0")]
    [AutoInjectGenerator.AutoInjectAttribute(Group = "WASM")]
    /// <inheritdoc/>
    public partial class UserServiceApiInvoker : Project.Constraints.Services.IUserService
    {
        private readonly global::System.Text.Json.JsonSerializerOptions jsonOptions;

        private readonly global::System.Net.Http.IHttpClientFactory clientFactory;

        private readonly global::AutoWasmApiGenerator.IHttpClientHeaderHandler headerHandler;

        public UserServiceApiInvoker(global::System.Net.Http.IHttpClientFactory factory, global::AutoWasmApiGenerator.IHttpClientHeaderHandler hander)
        {
            clientFactory = factory;
            headerHandler = hander;
            jsonOptions = new global::System.Text.Json.JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
        }

        [global::System.CodeDom.Compiler.GeneratedCode("AutoWasmApiGenerator.HttpServiceInvokerGenerator", "1.0.0.0")]
        public async System.Threading.Tasks.Task<Project.Constraints.Models.Permissions.User?> GetUserAsync(string id)
        {
            var url = "api/user/GetUser";
            var client = clientFactory.CreateClient("UserService");
            var request = new global::System.Net.Http.HttpRequestMessage();
            request.Method = global::System.Net.Http.HttpMethod.Post;
            headerHandler.SetRequestHeader(request);
            var jsonContent = global::System.Text.Json.JsonSerializer.Serialize(id);
            request.Content = new StringContent(jsonContent, global::System.Text.Encoding.Default, "application/json");
            request.RequestUri = new Uri(url, UriKind.Relative);
            var response = await client.SendAsync(request);
            response.EnsureSuccessStatusCode();
            var jsonStream = await response.Content.ReadAsStreamAsync();
            return global::System.Text.Json.JsonSerializer.Deserialize<Project.Constraints.Models.Permissions.User?>(jsonStream, jsonOptions);
        }
    }
}

好的,现在Controller有了,Controller的调用类也有了

项目结构如下,项目的nuget包和引用项目根据Blazor Web App的项目模板进行修改即可

  • BlazorAdminServer端项目
  • BlazorAdmin.ClientClient端项目
  • Shared双端共用的项目,一般是共用的页面、实体模型、等等

BlazorAdmin Program.cs

......
......
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();

builder.Services.AutoInject();
builder.Services.AddControllers();
......
......
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies([.. AppConst.Pages]);
app.MapControllers();
......

BlazorAdmin.Client Program.cs

......
......
builder.Services.ConfigureHttpClientDefaults(c =>
{
    c.ConfigureHttpClient(h => { h.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress); });
});
builder.Services.AutoInjectWasm();
builder.Services.AddScoped<IUserService, UserServiceApiInvoker>();

当运行在Server端的时候,获取的IUserService实例是自己实现的接口,当运行在WebAssembly中时,获取的IUserService实例是UserServiceApiInvoker

感谢⭐start⭐支持项目源码

生成器源码

标签:BlazorServer,AutoWasmApiGenerator,global,生成器,System,IUserService,Services,Blazor
From: https://www.cnblogs.com/marvelTitile/p/18360614

相关文章

  • 增量生成器(Incremental Generator)实现自动注入
    在之前呢,为了偷懒,是使用了反射在项目启动的时候,自动注入项目需要的服务现在改为使用源生成器,自动生成服务注入的代码nuget地址dotnetaddpackageAutoInjectGenerator--version0.0.3一个提供了3个Attribute用于自动注入的配置AutoInjectAttributeAutoInjectContextAttr......
  • 朋友吐槽我为什么这么傻不在源生成器中用string.GetHashCode, 而要用一个不够优化的ha
    明明有更好的hash方法有位朋友对我吐槽前几天我列举的在源生成器的生成db映射实体的优化点提前生成部分hashcode进行比较所示代码publicstaticvoidGenerateReadTokens(thisIDataReaderreader,Span<int>s){for(inti=0;i<reader.FieldCount;i++){......
  • Python 中的生成器函数有什么作用及如何使用?
    生成器函数是一种特殊的函数,可以在迭代过程中动态生成值,而不是一次性返回所有值。它的作用有以下几点:节省内存:生成器函数一次只生成一个值,并在生成后立即释放内存,这样可以减小内存的占用,特别是在处理大数据集时非常有用。延迟计算:生成器函数可以按需生成值,只在需要的时......
  • 【AI绘画】FLUX:这款新的人工智能图像生成器非常善于创造人手
    FLUX.1是StableDiffusion的公开重量级继承者,可将文本转化为图像。FLUX.1dev生成图像:“Abeautifulqueenoftheuniverseholdingupherhands,faceinthebackground.”。就在7月下旬,人工智能初创公司黑森林实验室(BlackForestLabs)宣布成立公司,并发布了第一......
  • 如何利用Matlab网格生成器画太极
    注:首先要懂几何函数的定义!代码:1.主函数:clc,clear;closeall;g1=[1111;20-20;0-202;020-2;20-20;1221;0000;0000;0000;2222];%大○g2=[1111;010-1;10-10;-2-121;-1010;2211;1122;0000;-1-111;1111];%......
  • MyBatis代码生成器:SpringBoot 引入MybatisGenerator
    1.引入插件<plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.5</version>......
  • 在 Python 生成器中使用“with”语句管理资源
    今天,在编程时,我发现自己在生成器函数内管理资源(ssh连接),类似于以下内容:def_yield_fname(host_address,usr,pwd,datapath):withparamiko.SSHClient()asssh_client:ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh_client.......
  • 如何计算任意可迭代对象(例如生成器)中的项目数量?
    假设我有一个任意的可迭代对象-例如,一个迭代文件行和yield匹配正则表达式的生成器。我如何计算该可迭代对象中的项目数,假设我不这样做不关心元素本身?可以使用sum()函数来计算可迭代对象中的元素数量,而无需存储它们。以下是如何操作:defcount_item......
  • 14. 迭代器、生成器、模块与包、json模块
    1.迭代器1.1迭代器介绍迭代器是用来迭代取值的工具每一次迭代得到的结果会作为下一次迭代的初始值,单纯的重复并不是迭代#while循环实现迭代取值a=[1,2,3,4,5,6]index=0whileindex<len(a):print(a[index])index+=1 1.2可迭代对象内置有_......
  • python生成器
    一前言环境:python3.10win10二生成器1关于生成器先看一个例子    定义了一个函数,当我们运行该函数时,并未像普通函数那样执行函数体内的代码    从其中的英文可知,执行函数得到了一个生成器对象,这个生成器对象也叫做generatoriterator(生成器迭代器),generatorit......