ABP vNext V5 + VS2022+ .Net 6.0 學習筆記(1)


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.更新數據庫

 

dotnet ef database update

如果你使用的是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入門:Dto與實體模型的映射-AutoMapper

 在ABP中靈活使用AutoMapper - repeatedly

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM