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
在ABP中靈活使用AutoMapper - repeatedly