(3) MasaFramework 入门第三篇,使用MasaFramework

首先我们需要创建一个MasaFramework模板的项目,项目名称TokenDemo,项目类型如图所示

(3) MasaFramework 入门第三篇,使用MasaFramework

删除Web/TokenDemo.Admin项目,新建Masa Blazor Pro项目模板

项目,项目位置在src/Web项目
(3) MasaFramework 入门第三篇,使用MasaFramework

项目类型选择ServerAndWasm,为了让我们支持俩种模式

(3) MasaFramework 入门第三篇,使用MasaFramework

创建完成以后的目录,然后在TokenDemo.Admin中添加项目引用TokenDemo.Caller

配置EntityFrameworkCoreSqlite

修改TokenDemo.Service项目的包依赖为预览版

	<ItemGroup> 		<PackageReference Include="Masa.BuildingBlocks.Dispatcher.Events" Version="1.0.0-preview.18" /> 		<PackageReference Include="Masa.Contrib.Data.Contracts" Version="1.0.0-preview.18" /> 		<PackageReference Include="Masa.Contrib.Data.EFCore.Sqlite" Version="1.0.0-preview.18" /> 		<PackageReference Include="Masa.Contrib.Dispatcher.Events" Version="1.0.0-preview.18" /> 		<PackageReference Include="Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore" Version="1.0.0-preview.18" /> 		<PackageReference Include="FluentValidation" Version="11.5.1" /> 		<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" /> 		<PackageReference Include="Masa.Utils.Extensions.DependencyInjection" Version="1.0.0-preview.18" /> 		<PackageReference Include="Masa.Contrib.Service.MinimalAPIs" Version="1.0.0-preview.18" /> 		<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.3" /> 		<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> 	</ItemGroup> 

Masa.Contrib.Data.Contracts提供了数据过滤的能力, 但它不是必须的

然后会出现报错

LogMiddleware将代码修改为以下代码

namespace TokenDemo.Service.Infrastructure.Middleware;  public class LogMiddleware<TEvent> : EventMiddleware<TEvent>     where TEvent : notnull, IEvent {     private readonly ILogger<LogMiddleware<TEvent>> _logger;      public LogMiddleware(ILogger<LogMiddleware<TEvent>> logger)     {         _logger = logger;     }      public override async Task HandleAsync(TEvent action, EventHandlerDelegate next)     {         var typeName = action.GetType().FullName;          _logger.LogInformation("----- command {CommandType}", typeName);          await next();     } } 

ValidatorMiddleware将代码修改为以下代码

namespace TokenDemo.Service.Infrastructure.Middleware;  public class ValidatorMiddleware<TEvent> : EventMiddleware<TEvent>     where TEvent : notnull, IEvent {     private readonly ILogger<ValidatorMiddleware<TEvent>> _logger;     private readonly IEnumerable<IValidator<TEvent>> _validators;      public ValidatorMiddleware(IEnumerable<IValidator<TEvent>> validators, ILogger<ValidatorMiddleware<TEvent>> logger)     {         _validators = validators;         _logger = logger;     }      public override async Task HandleAsync(TEvent action, EventHandlerDelegate next)     {         var typeName = action.GetType().FullName;          _logger.LogInformation("----- Validating command {CommandType}", typeName);          var failures = _validators             .Select(v => v.Validate(action))             .SelectMany(result => result.Errors)             .Where(error => error != null)             .ToList();          if (failures.Any())         {             _logger.LogWarning("Validation errors - {CommandType} - Command: {@Command} - Errors: {@ValidationErrors}", typeName, action, failures);              throw new ValidationException("Validation exception", failures);         }          await next();     } } 

OrderEventHandler将代码修改为以下代码

namespace TokenDemo.Service.Infrastructure.Handlers;  public class OrderEventHandler {     readonly IOrderRepository _orderRepository;      public OrderEventHandler(IOrderRepository orderRepository)     {         _orderRepository = orderRepository;     }      [EventHandler(Order = 1)]     public async Task HandleAsync(QueryOrderListEvent @event)     {         @event.Orders = await _orderRepository.GetListAsync();     } }  public class OrderEventAfterHandler : IEventHandler<QueryOrderListEvent> {     public async Task HandleAsync(QueryOrderListEvent @event, CancellationToken cancellationToken = new CancellationToken())     {         await Task.CompletedTask;     } } 

修改appsettings.json 添加Sqlite地址

{   "Logging": {     "LogLevel": {       "Default": "Information",       "Microsoft": "Warning",       "Microsoft.Hosting.Lifetime": "Information"     }   },   "AllowedHosts": "*",   "ConnectionStrings": {     "DefaultConnection": "Data Source=Catalog.db;"   } } 

修改Program.cs代码

using TokenDemo.Service.Infrastructure;  var builder = WebApplication.CreateBuilder(args);  builder.Services     .AddAuthorization()     .AddAuthentication(options =>     {         options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;         options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;     })     .AddJwtBearer(options =>     {         options.Authority = "";         options.RequireHttpsMetadata = false;         options.Audience = "";     });  builder.Services.AddMasaDbContext<ShopDbContext>(dbContextBuilder => {     dbContextBuilder         .UseSqlite() //使用Sqlite数据库         .UseFilter(); //数据数据过滤 });  builder.Services.AddAutoInject(); var app = builder.Services     .AddEndpointsApiExplorer()     .AddSwaggerGen(options =>     {         options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()         {             Name = "Authorization",             Type = SecuritySchemeType.ApiKey,             Scheme = "Bearer",             BearerFormat = "JWT",             In = ParameterLocation.Header,             Description = "JWT Authorization header using the Bearer scheme. rnrn Enter 'Bearer' [space] and then your token in the text input below.rnrnExample: "Bearer xxxxxxxxxxxxxxx"",         });         options.AddSecurityRequirement(new OpenApiSecurityRequirement         {             {                 new OpenApiSecurityScheme                 {                     Reference = new OpenApiReference                     {                         Type = ReferenceType.SecurityScheme,                         Id = "Bearer"                     }                 },                 new string[] {}             }         });     })     .AddFluentValidationAutoValidation().AddFluentValidationClientsideAdapters()     .AddEventBus(eventBusBuilder =>     {         eventBusBuilder.UseMiddleware(typeof(ValidatorMiddleware<>));         eventBusBuilder.UseMiddleware(typeof(LogMiddleware<>));     })     .AddServices(builder);  // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) {     app.UseSwagger();     app.UseSwaggerUI(); } app.UseRouting();  app.UseAuthentication(); app.UseAuthorization();  app.UseHttpsRedirection();  app.Run(); 

添加EFCore迁移依赖

		<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.15"> 		  <PrivateAssets>all</PrivateAssets> 		  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> 		</PackageReference> 		<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.15"> 		  <PrivateAssets>all</PrivateAssets> 		  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> 		</PackageReference> 

程序包管理器控制台中输入 Add-Migration Init生成Init的迁移文件(如果出现 error NETSDK1082: Microsoft.AspNetCore.App 没有运行时包可用于指定的 RuntimeIdentifier“browser-wasm”这个错误的话就先把TokenDemo.Admin.WebAssembly项目移除)

使用Update-Database生成Sqlitem

然后就可以看到项目中生成了Catalog.db文件

启动TokenDemo.Service.Order我们就可以看到Swagger的界面了

如何对接接口

打开TokenDemo.Caller项目中的``CallersOrderCaller.cs`文件

修改BaseAdderssTokenDemo.Service.Order的服务地址

打开TokenDemo.Service.Order项目的ServicesOrderService.cs文件并且修改代码

namespace TokenDemo.Service.Services;  public class OrderService : ServiceBase {     public OrderService(IServiceCollection services) : base(services)     {         App.MapGet("/order/list", QueryList).Produces<List<Infrastructure.Entities.Order>>()             .WithName("GetOrders");     }      public async Task<IResult> QueryList(IEventBus eventBus)     {         var orderQueryEvent = new QueryOrderListEvent();         await eventBus.PublishAsync(orderQueryEvent);         return Results.Ok(orderQueryEvent.Orders);     } } 

然后在通过命令行启动TokenDemo.Service.Order项目

(3) MasaFramework 入门第三篇,使用MasaFramework

打开TokenDemoAdmin项目的PagesHomeIndex.razor文件并且修改代码

@page "/" @using TokenDemo.Caller.Callers @inherits LayoutComponentBase @inject NavigationManager Nav @inject OrderCaller OrderCaller @code {      protected override async Task OnAfterRenderAsync(bool firstRender)     {         Nav.NavigateTo(GlobalVariables.DefaultRoute,true);         var data = await OrderCaller.GetListAsync();         await base.OnAfterRenderAsync(firstRender);     }  }  

并且在await base.OnAfterRenderAsync(firstRender);这里打一个断点用于查看是否获取到消息

打开TokenDemo.Admin.Server项目的Program.cs,添加以下代码

builder.Services.AddCaller(typeof(TokenDemo.Caller.Callers.OrderCaller).Assembly); 

然后启动TokenDemo.Admin.Server项目,进入断点

(3) MasaFramework 入门第三篇,使用MasaFramework

得到结果

结尾

通过上文我们可以基本将MasaFramework的使用掌握,前端和后端的接口也掌握了

当前是MasaFramework的第三篇入门,我会继续学习MasaFramework并且分享给大家

来自token的分享

MASA Framework

学习交流:737776595

发表评论

评论已关闭。

相关文章