(3) MasaFramework 入门第三篇,使用MasaFramework
首先我们需要创建一个MasaFramework模板的项目,项目名称TokenDemo,项目类型如图所示

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

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

创建完成以后的目录,然后在TokenDemo.Admin中添加项目引用TokenDemo.Caller
配置EntityFrameworkCore和Sqlite
修改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. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"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项目中的``Callers\OrderCaller.cs`文件
修改BaseAdderss为TokenDemo.Service.Order的服务地址
打开TokenDemo.Service.Order项目的Services\OrderService.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项目

打开TokenDemo\Admin项目的Pages\Home\Index.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项目,进入断点

得到结果
结尾
通过上文我们可以基本将MasaFramework的使用掌握,前端和后端的接口也掌握了
当前是MasaFramework的第三篇入门,我会继续学习MasaFramework并且分享给大家
来自token的分享
学习交流:737776595
(3) MasaFramework 入门第三篇,使用MasaFramework的更多相关文章
- JavaMail入门第三篇 发送邮件
JavaMail API中定义了一个java.mail.Transport类,它专门用于执行邮件发送任务,这个类的实例对象封装了某种邮件发送协议的底层实施细节,应用程序调用这个类中的方法就可以把Mes ...
- Html/Css(新手入门第三篇)
一.学习心得---参考优秀的网页来学习. 1我们只做的静态网页主要用的技术?html+css 只要网上看到的,他的源代码公开的.[1].先去分析,他们页面是如何布局(结构化)[2].再试着去做一下,- ...
- Android JNI入门第三篇——jni头文件分析
一. 首先写了java文件: public class HeaderFile { private native void doVoid(); native int doShort(); native ...
- Java线程入门第三篇
Java内存模型(jmm) Why:保证多线程正确协同工作 看图说明: 文字解释:线程a和线程b通信过程,首先线程a把本地内存的共享变量更新到主内存中,然后线程b去读取主内存的共享变量,最后更新到自己 ...
- Visualforce入门第三篇_2017.3.2
Visualforce实现显示Record List(列表) 详细见链接:https://trailhead.salesforce.com/modules/visualforce_fundamenta ...
- Hadoop入门第三篇-MapReduce试手以及MR工作机制
MapReduce几个小应用 上篇文章已经介绍了怎么去写一个简单的MR并且将其跑起来,学习一个东西动手还是很有必要的,接下来我们就举几个小demo来体验一下跑起来的快感. demo链接请参照附件:ht ...
- JavaMail入门第四篇 接收邮件
上一篇JavaMail入门第三篇 发送邮件中,我们学会了如何用JavaMail API提供的Transport类发送邮件,同样,JavaMail API中也提供了一些专门的类来对邮件的接收进行相关的操 ...
- JavaMail入门第五篇 解析邮件
上一篇JavaMail入门第四篇 接收邮件中,控制台打印出的内容,我们无法阅读,其实,让我们自己来解析一封复杂的邮件是很不容易的,邮件里面格式.规范复杂得很.不过,我们所用的浏览器内置了解析各种数据类 ...
- jQuery入门第三
jQuery入门第三 1.HTML 2.CSS 衣服 3.javascript 可以动的人 4.DOM 编程 对html文档的节点操作 5.jQuery 对 javascript的封装 简练的语法 复 ...
- Kotlin入门第三课:数据类型
前文链接: Kotlin学习第一课:从对比Java开始 Kotlin入门第二课:集合操作 初次尝试用Kotlin实现Android项目 Kotlin的数据类型与Java类似,因此这篇文章主要看Kotl ...
随机推荐
- Thread 的run方法和start方法的区别
start()方法是用来启动线程,实现了多线程运行 点进去查看源码,发现start方法创建一个线程 并让线程处于就绪状态,并且在start方法内会调用start0()方法,而start0作为本地方法 ...
- module 'tensorflow_core._api.v2.config' has no attribute 'experimental_list_devices'
module 'tensorflow_core._api.v2.config' has no attribute 'experimental_list_devices' kearsPython 报错如 ...
- nchu第二次面向对象编程博客作业
前言: 本次博客包含的内容有pta题目集4(四边形).5(五边形)以及期中考试三次题目集.其中第四次和第五次题目集难度较大,比较复杂,涉及的知识点也比较多.而期中考试由于是在课堂上完成,难度较小, ...
- pycharm 安装步骤
1.双击安装包 2.点击next 3.选择安装目录后点击next进入下一步 4.根据你电脑的实际情况选择安装32位还是64位 5.勾选 .py 后即可点击next进入下一步 6.默认,直接next 7 ...
- HDFS Shell 操作
HDFS Shell 操作 HDFS Shell 命令行格式 格式一:hadoop fs –命令名 参数 格式二:hdfs dfs –命令名 参数 HDFS 常用命令及参数 ls:查看 hdfs 中的 ...
- Oracle添加约束
约束 -contraint Oracle中约束类型:主键约束,唯一约束,非空约束,外键约束,check约束,下述主要是alter的方法去添加约束,也可以在建表时直接添加约束 主键约束 alter ta ...
- linux 中的errno 和 strerror(errno)
1. errno.h 中包含 errno 这个错误保存值 string.h 包含 strerror() 函数 ,它的原型 是 char *strerror(int errnum); 输入值应该是err ...
- MySQL中的json函数
json_valid 判断是否为合法json文档 json_unquote 去除json字符串的引号,将值转成string类型 json_extract 提取json值
- Markdown基础使用学习
Mark Down学习 标题:#+标题名字 二级标题:## +标题名字 三级... 字体 两个*+字+两个=加粗 一个=斜体 引用 一个大于号+内容 图片  符号全部小写 超链接 ...
- node邮件发送html,简单2步附代码
node 发送 html 邮件 安装 npm install nodemailer 新建 html 文件 ① 新建 views 目录下面新增 index.html(当然也可以使用其它目录结构,下面的代 ...