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

 

posted on 2021-11-06 13:24  Gu  阅读(1390)  评论(0编辑  收藏  举报