1.安装.net 5.0, net6.0 ,安装vs2022
2. 打开abp.io网站,选择Blazer WebAsembly, EFCore,SQLServer
3. 运行 MetaBase.Platform.DbMigrator.csproj, 需要.net 5.0才能运行 ,如果出现
’abp‘不是内部或外部命令,也不是可运行的程序 或批处理文件
在装好dotnet 后,安装Abp.Cli
dotnet tool install -g Volo.Abp.Cli
如果已经装好,需要更新的话执行
dotnet tool update -g Volo.Abp.Cli
4. 在Domain 项目增加类
using System; using Volo.Abp.Domain.Entities; namespace TodoApp { public class TodoItem : BasicAggregateRoot<Guid> { public string Text { get; set; } } }
5. 在EntityFrameworkCore项目的XXXDbContext.cs 增加映射
public class PlatformDbContext : AbpDbContext<PlatformDbContext>, IIdentityDbContext, ITenantManagementDbContext { /* Add DbSet properties for your Aggregate Roots / Entities here. */ public DbSet<TodoItem> TodoItems { get; set; } //加入自定义实体类的映射---------------- } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); /* Include modules to your migration db context */ builder.ConfigurePermissionManagement(); builder.ConfigureSettingManagement(); builder.ConfigureBackgroundJobs(); builder.ConfigureAuditLogging(); builder.ConfigureIdentity(); builder.ConfigureIdentityServer(); builder.ConfigureFeatureManagement(); builder.ConfigureTenantManagement(); /* Configure your own tables/entities inside here */ builder.Entity<TodoItem>(b => { b.ToTable(PlatformConsts.DbTablePrefix + "TodoItems", PlatformConsts.DbSchema); b.ConfigureByConvention(); //using Volo.Abp.EntityFrameworkCore.Modeling; }); }
6.更新数据库
如果你使用的是Visual Studio, 则可能希望在 包管理器控制台 (PMC) 中使用 Add-Migration Added_TodoItem
和 Update-Database
命令. 在这种情况下, 请确保 TodoApp.EntityFrameworkCore
是PMC中的 默认项目.
抄一张分层架构图,
ABP的Service接口层是Application.Contracts, 它在这个项目定义Dto,但不引用Domain项目。(所以必须定义Dto,再在service实现层转换Dto=>Entity)
ABP的Service实现层是Application, 它在这个项目引用Domain项目。(在XXXApplicationAutoMapperProfile.cs 定义Dto和实体的对应规则)
7. 在Application.Contract 里定义接口和Dto,接口定义的是Task的异步方法, 注意Dto和Entity的不同,Entity默认Id作为主键名,假如 实体继承于FullAuditedEntity,更加会多很多字段
public interface ITodoAppService : IApplicationService { Task<List<TodoItemDto>> GetListAsync(); Task<TodoItemDto> CreateAsync(string text); Task DeleteAsync(Guid id); } public class TodoItemDto { public Guid Id { get; set; } public string Text { get; set; } }
注意接口要实现IapplicationService, 这样才能自动注册,不然运行时就会找不到
. There is no registered service of type 'MetaBase.Platform.ITodoAppService'. System.InvalidOperationException: Cannot provide a value for property 'TodoAppService' on type
8. 在application 里编写实现类
public class TodoAppService : ApplicationService, ITodoAppService { //IRepository为啥需要2个参数呢,不能从TodoItem知道它时guid做主键? private readonly IRepository<TodoItem, Guid> _todoItemRepository; public TodoAppService(IRepository<TodoItem, Guid> todoItemRepository) { _todoItemRepository = todoItemRepository; } public async Task<TodoItemDto> CreateAsync(string text) { var todoItem = await _todoItemRepository.InsertAsync(new TodoItem() { Text = text }) ; //entity=> Dto return new TodoItemDto() { Id = todoItem.Id, Text = todoItem.Text }; } /// <summary> /// Task 返回值不用返回的吗? /// </summary> /// <param name="id"></param> /// <returns></returns> public async Task DeleteAsync(Guid id) { await _todoItemRepository.DeleteAsync(id); } /// <summary> /// items.Select 要加了await才有????,没加时返回Task<list<X>>,加await时返回List<X> /// </summary> /// <returns></returns> public async Task<List<TodoItemDto>> GetListAsync() { var items = await _todoItemRepository.GetListAsync(); //entity=> Dto return items.Select(item => new TodoItemDto { Id = item.Id, Text = item.Text }).ToList(); } }
9,界面层代码, 这里用的时Blazor Assembly
Blazor项目的Pages
文件夹中Index.razor.cs
文件, 并替换为一下内容:
namespace MetaBase.Platform.Blazor.Pages { public partial class Index { [Inject] private ITodoAppService TodoAppService { get; set; } // [Inject]自动实例化??? private List<TodoItemDto> TodoItems { get; set; } = new List<TodoItemDto>(); private string NewTodoText { get; set; } protected override async Task OnInitializedAsync() { TodoItems = await TodoAppService.GetListAsync(); } private async Task Create() { var result = await TodoAppService.CreateAsync(NewTodoText); TodoItems.Add(result); NewTodoText = null; } private async Task Delete(TodoItemDto todoItem) { await TodoAppService.DeleteAsync(todoItem.Id); await Notify.Info("Deleted the todo item."); TodoItems.Remove(todoItem); } } }
Blazor 项目的Pages
文件夹中 Index.razor
文件, 并替换为以下代码块内容:
<div class="container"> <Card> <CardHeader> <CardTitle> TODO LIST </CardTitle> </CardHeader> <CardBody> <!-- FORM FOR NEW TODO ITEMS --> <form id="NewItemForm" @onsubmit:preventDefault @onsubmit="() => Create()" class="form-inline"> <input type="text" @bind-value="@NewTodoText" class="form-control mr-2" placeholder="enter text..."> <button type="submit" class="btn btn-primary">Submit</button> </form> <!-- TODO ITEMS LIST --> <ul id="TodoList"> @foreach (var todoItem in TodoItems) { <li data-id="@todoItem.Id"> <i class="far fa-trash-alt" @onclick="() => Delete(todoItem)" ></i> @todoItem.Text </li> } </ul> </CardBody> </Card> </div>
Pages
文件夹中的 Index.razor.css
文件, 并替换为以下内容
#TodoList{ list-style: none; margin: 0; padding: 0; } #TodoList li { padding: 5px; margin: 5px 0px; border: 1px solid #cccccc; background-color: #f5f5f5; } #TodoList li i { opacity: 0.5; } #TodoList li i:hover { opacity: 1; color: #ff0000; cursor: pointer; }
vs2022修改默认浏览器的位置变了,改在[文件]->[使用以下工具浏览(H)...]
!!!!!!!!!!!!!!!!!!TO Be Continue !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
疑惑: 客户端如何实例化 TodoAppService? 模块是如何加载的? 如果进行复杂的组合查询,能否进行SQL的查询呢?
相关知识: Dto ABP理论学习之数据传输对象(DTO) - tkbSimplest