Blazor Web 应用如何实现Auto模式

本文介绍Blazor Web应用Auto交互呈现模式的实现方案,如下示例是基于 Known 框架来实现的,该解决方案共有3个项目,具体实现步骤如下:

1. 前后端共用项目

  • 创建前后端共用类库项目Sample,定义系统的实体类、数据模型、服务接口、常量、枚举等,项目工程文件内容如下:
<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
</Project>
  • 在该项目中添加示例服务接口,继承框架IService
//IService为框架定义的Api服务接口,用于标识该接口为前后端交互接口
//程序启动时,框架自动查找Assembly中的接口,根据接口定义WebApi路由
//该示例路由为:/Test/GetMessage
public interface ITestService : IService {
    Task<string> GetMessageAsync();
}

2. 客户端项目

  • 创建客户端项目Sample.Client,引用WebAssembly所需依赖,引用Castle依赖动态代理Http请求后端WebApi,项目工程文件内容如下:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
        <StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.6" />
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.6" />
        <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
        <PackageReference Include="Castle.Core" Version="5.1.1" />
        <PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
        <ProjectReference Include="..\Sample\Sample.csproj" />
    </ItemGroup>
</Project>
  • 添加拦截器HttpClientInterceptor.cs类文件,继承Castle.DynamicProxy.IAsyncInterceptor,实现Http动态代理
using Castle.DynamicProxy;

namespace Sample.Client;

// HttpInterceptor为框架封装的拦截器
public class HttpClientInterceptor<T>(IServiceScopeFactory provider) : HttpInterceptor<T>(provider), IAsyncInterceptor where T : class {
    protected override async Task<HttpClient> CreateClientAsync() {
        var type = typeof(T);
        var factory = await ServiceFactory.CreateAsync<IHttpClientFactory>();
        var client = factory.CreateClient(type.Name);
        client.BaseAddress = new Uri(Config.HostUrl);
        return client;
    }

    public void InterceptAsynchronous(IInvocation invocation) {
        invocation.ReturnValue = SendAsync(invocation.Method, invocation.Arguments);
    }

    public void InterceptAsynchronous<TResult>(IInvocation invocation) {
        invocation.ReturnValue = SendAsync<TResult>(invocation.Method, invocation.Arguments);
    }

    public void InterceptSynchronous(IInvocation invocation) { }
}
  • Program.cs文件中添加客户端配置
//使用Castle代理生成器创建Http代理类型
private static readonly ProxyGenerator Generator = new();

services.AddHttpClient();
//添加KnownClient,注入拦截器提供者
services.AddKnownClient(info =>
{
    info.InterceptorType = type => typeof(HttpClientInterceptor<>).MakeGenericType(type);
    info.InterceptorProvider = (type, interceptor) =>
    {
        return Generator.CreateInterfaceProxyWithoutTarget(type, ((IAsyncInterceptor)interceptor).ToInterceptor());
    };
});
  • 添加测试页面组件Test.razor
@page "/test"

<h1>@message</h1>

@code {
    //注入服务与Server模式注入没有区别
    [Inject] private ITestService Service { get; set; }
    private string message;
    
    protected override async Task OnAfterRenderAsync(bool firstRender) {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
            message = await Service.GetMessageAsync();
        //这里的Service实例,会根据渲染模式自动切换
        //SSR时,就是后端实现ITestService的实现类的实例
        //CSR时,就是Castle代理生成器创建的代理类的实例
    }
}

3. 服务端项目

  • 创建服务端项目Sample.Web,项目工程文件内容如下:
<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.6" />
        <ProjectReference Include="..\Sample.Client\Sample.Client.csproj" />
    </ItemGroup>
</Project>
  • 修改App.razor文件中的呈现模式
<Routes @rendermode="InteractiveMode" />

@code {
    private InteractiveAutoRenderMode InteractiveMode => new(false);
}
  • 添加TestService.cs实现服务接口
class  TestService : ITestService {
    public Task<string> GetMessageAsync() => Task.FromResult("test");
}
  • Program.cs文件中添加服务端配置
//添加Known框架后端Core
services.AddKnownCore();
//添加Known框架自动生成WebApi
services.AddKnownWebApi();
//注入服务接口
services.AddScoped<ITestService, TestService>();

//使用Known框架静态文件和WebApi
app.UseKnown();

4. 结语

本文示例代码仅作Auto模式实现方案的参考,具体功能实现,可查看 Known 框架的实例源码。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容