ABP 上的应用程序服务 URL 映射
Application service URL mapping on ABP
我是ABP新手,我this oficial tutorial成功了。
然后我添加了另一个 class (Planta) 并再次按照教程进行操作(没有删除 The Book class),但即使我可以创建 table并在其上提供数据(已验证),应用程序无法加载 table,当我检查 swagger 时,我发现了这个...
我原以为它是 Planta 而不是 BookAppServicePlanta,但我找不到哪里搞砸了。
我尝试解决的问题
- 我读过的关于 ABP 的资料最多。
- 我已经将每个 Planta 文件与它的 Book 副本进行了对比。
- 我已经删除数据库很多次了。
这是我所做的(详情如下):
- 我在
Acme.BookStore.Domain/Planta/Planta.cs
上创建了 class 植物群:
- 将实体添加到
Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs
- 将实体映射到
Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs
上的 table
- 删除了数据库,并删除了以前的迁移
- 创建了数据播种器
Acme.BookStore.Domain/BookStoreDataSeederContributor_Plant.cs
- 添加了新的迁移,并且 运行
Acme.BookStore.DbMigrator
- 已创建
Acme.BookStore.Application.Contracts/PlantDto.cs
- 已将其添加到
Acme.BookStore.Application/BookStoreApplicationAutoMapperProfile.cs
- 创建了
Acme.BookStore.Application.Contracts/CreateUpdatePlantDto.cs
(并将其也添加到自动映射器中,如 8 所示))
- 创建界面
Acme.BookStore.Application.Contracts/IBookAppServicePlanta.cs
- 已在
Acme.BookStore.Application/BookAppServicePlanta.cs
上实施
- 运行 申请
额外信息:
我为 Planta 及其表单创建了页面(教程第 2 部分和第 3 部分),但即使我仔细检查了这些文件,我也不相信问题出在这些文件上,因为 swagger 问题。
我在 Acme.BookStore.Domain/Planta/Planta.cs
上创建了 class 植物群:
using System;
using Volo.Abp.Domain.Entities.Auditing;
namespace Acme.BookStore.Plantas
{
public class Planta : AuditedAggregateRoot<Guid>
{
public string Nombre { get; set; }
public string Descripcion { get; set; }
public string Dirección { get; set; }
public string Lat { get; set; }
public string Long { get; set; }
public string Extra1 { get; set; }
public string Extra2 { get; set; }
public string Extra3 { get; set; }
}
}
将实体添加到 Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs
using Microsoft.EntityFrameworkCore;
using Acme.BookStore.Users;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.Identity;
using Volo.Abp.Users.EntityFrameworkCore;
using Acme.BookStore.Books;
using Acme.BookStore.Plantas;
namespace Acme.BookStore.EntityFrameworkCore
{
/* This is your actual DbContext used on runtime.
* It includes only your entities.
* It does not include entities of the used modules, because each module has already
* its own DbContext class. If you want to share some database tables with the used modules,
* just create a structure like done for AppUser.
*
* Don't use this DbContext for database migrations since it does not contain tables of the
* used modules (as explained above). See BookStoreMigrationsDbContext for migrations.
*/
[ConnectionStringName("Default")]
public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
{
public DbSet<AppUser> Users { get; set; }
public DbSet<Book> Books { get; set; }
public DbSet<Planta> Plantas { get; set; }
/* Add DbSet properties for your Aggregate Roots / Entities here.
* Also map them inside BookStoreDbContextModelCreatingExtensions.ConfigureBookStore
*/
public BookStoreDbContext(DbContextOptions<BookStoreDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
/* Configure the shared tables (with included modules) here */
builder.Entity<AppUser>(b =>
{
b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser
b.ConfigureByConvention();
b.ConfigureAbpUser();
/* Configure mappings for your additional properties
* Also see the BookStoreEfCoreEntityExtensionMappings class
*/
});
/* Configure your own tables/entities inside the ConfigureBookStore method */
builder.ConfigureBookStore();
}
}
}
将实体映射到 Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs
上的 table
using Acme.BookStore.Books;
using Acme.BookStore.Plantas;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace Acme.BookStore.EntityFrameworkCore
{
public static class BookStoreDbContextModelCreatingExtensions
{
public static void ConfigureBookStore(this ModelBuilder builder)
{
Check.NotNull(builder, nameof(builder));
/* Configure your own tables/entities inside here */
builder.Entity<Book>(b =>
{
b.ToTable(BookStoreConsts.DbTablePrefix + "Books",
BookStoreConsts.DbSchema);
b.ConfigureByConvention(); //auto configure for the base class props
b.Property(x => x.Name).IsRequired().HasMaxLength(128);
});
builder.Entity<Planta>(p =>
{
p.ToTable(BookStoreConsts.DbTablePrefix + "Plantas",
BookStoreConsts.DbSchema);
p.ConfigureByConvention(); //auto configure for the base class props
p.Property(y => y.Nombre).IsRequired().HasMaxLength(128);
});
}
}
}
删除了数据库,并删除了以前的迁移
创建了数据播种器Acme.BookStore.Domain/BookStoreDataSeederContributor_Plant.cs
using System;
using System.Threading.Tasks;
using Acme.BookStore.Plantas;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore
{
public class BookStoreDataSeederContributor_Plant
: IDataSeedContributor, ITransientDependency
{
private readonly IRepository<Planta, Guid> _plantaRepository;
public BookStoreDataSeederContributor_Plant(IRepository<Planta, Guid> plantaRepository)
{
_plantaRepository = plantaRepository;
}
public async Task SeedAsync(DataSeedContext context)
{
if (await _plantaRepository.GetCountAsync() > 0)
{
return;
}
await _plantaRepository.InsertAsync(
new Planta
{
Nombre = "Armijo Guajardo",
Descripcion = "excel god",
Dirección = "las lilas 123",
Lat = "564.765.98",
Long = "100.102.04",
Extra1 = "bla",
Extra2 = "bla bla",
Extra3 = "bla bla bla"
},
autoSave: true
);
}
}
}
添加了一个新的迁移,并且运行 Acme.BookStore.DbMigrator
已创建Acme.BookStore.Application.Contracts/PlantDto.cs
using System;
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore.Plantas
{
public class PlantDto : AuditedEntityDto<Guid>
{
public string Nombre { get; set; }
public string Descripcion { get; set; }
public string Dirección { get; set; }
public string Lat { get; set; }
public string Long { get; set; }
public string Extra1 { get; set; }
public string Extra2 { get; set; }
public string Extra3 { get; set; }
}
}
添加到 Acme.BookStore.Application/BookStoreApplicationAutoMapperProfile.cs
using Acme.BookStore.Books;
using Acme.BookStore.Plantas;
using AutoMapper;
namespace Acme.BookStore
{
public class BookStoreApplicationAutoMapperProfile : Profile
{
public BookStoreApplicationAutoMapperProfile()
{
CreateMap<Book, BookDto>();
CreateMap<CreateUpdateBookDto, Book>();
CreateMap<Planta, PlantDto>();
CreateMap<CreateUpdatePlantDto, Planta>();
}
}
}
创建了 Acme.BookStore.Application.Contracts/CreateUpdatePlantDto.cs
(并将其添加到自动映射器中,如 8 所示))
using System;
using System.ComponentModel.DataAnnotations;
namespace Acme.BookStore.Plantas
{
public class CreateUpdatePlantDto
{
[Required]
[StringLength(128)]
public string Nombre { get; set; }
[Required]
[StringLength(128)]
public string Descripcion { get; set; }
[Required]
[StringLength(128)]
public string Dirección { get; set; }
[Required]
[StringLength(128)]
public string Lat { get; set; }
[Required]
[StringLength(128)]
public string Long { get; set; }
[Required]
[StringLength(128)]
public string Extra1 { get; set; }
[Required]
[StringLength(128)]
public string Extra2 { get; set; }
[Required]
[StringLength(128)]
public string Extra3 { get; set; }
}
}
创建了界面Acme.BookStore.Application.Contracts/IBookAppServicePlanta.cs
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Acme.BookStore.Plantas
{
public interface IBookAppServicePlanta :
ICrudAppService< //Defines CRUD methods
PlantDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdatePlantDto> //Used to create/update a book
{
}
}
已在 Acme.BookStore.Application/BookAppServicePlanta.cs
上实施
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Plantas
{
public class BookAppServicePlanta :
CrudAppService<
Planta, //The Book entity
PlantDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdatePlantDto>, //Used to create/update a book
IBookAppServicePlanta //implement the IBookAppService
{
public BookAppServicePlanta(IRepository<Planta, Guid> repository)
: base(repository)
{
}
}
}
运行 申请
[编辑]
Acme.BookStore.Web/BookStoreWebAutoMapperProfile.cs
看起来像这样
using Acme.BookStore.Books;
using Acme.BookStore.Plantas;
using AutoMapper;
namespace Acme.BookStore.Web
{
public class BookStoreWebAutoMapperProfile : Profile
{
public BookStoreWebAutoMapperProfile()
{
CreateMap<BookDto, CreateUpdateBookDto>();
CreateMap<PlantDto, CreateUpdatePlantDto>();
}
}
}
[编辑]
我创建了一个teting文件Acme.BookStore.Application.Tests/BookAppServicePlanta_test.cs
,他们都成功了。
using System;
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Validation;
using Xunit;
namespace Acme.BookStore.Plantas
{
public class BookAppService_Tests : BookStoreApplicationTestBase
{
private readonly IBookAppServicePlanta _plantaAppService;
public BookAppService_Tests()
{
_plantaAppService = GetRequiredService<IBookAppServicePlanta>();
}
[Fact]
public async Task Should_Get_List_Of_Books()
{
//Act
var result = await _plantaAppService.GetListAsync(
new PagedAndSortedResultRequestDto()
);
//Assert
result.TotalCount.ShouldBeGreaterThan(0);
result.Items.ShouldContain(b => b.Nombre == "Armijo Guajardo");
}
[Fact]
public async Task Should_Create_A_Valid_Planta()
{
//Act
var result = await _plantaAppService.CreateAsync(
new CreateUpdatePlantDto
{
Nombre = "Pedro Cano",
Descripcion = "Cirujano",
Dirección = "Pedro de Valdivia",
Lat = "123213213",
Long = "456456456",
Extra1 = "emmmm",
Extra2 = "no se",
Extra3 = "que poner"
}
);
//Assert
result.Id.ShouldNotBe(Guid.Empty);
result.Nombre.ShouldBe("Pedro Cano");
}
[Fact]
public async Task Should_Not_Create_A_Planta_Without_Name()
{
var exception = await Assert.ThrowsAsync<AbpValidationException>(async () =>
{
await _plantaAppService.CreateAsync(
new CreateUpdatePlantDto
{
Descripcion = "Cirujano",
Dirección = "Pedro de Valdivia",
Lat = "123213213",
Long = "456456456",
Extra1 = "emmmm",
Extra2 = "no se",
Extra3 = "que poner"
}
);
});
exception.ValidationErrors
.ShouldContain(err => err.MemberNames.Any(mem => mem == "Nombre"));
}
}
}
我对 ABP 不熟悉,但是快速查看文档,您似乎没有遵循命名约定。
应用程序服务应遵循以下命名约定:Entity
AppService
但您似乎 copied/pasted 之前的 class BookAppService
只是在末尾添加了 Planta
。它应该是 PlantaAppService
而不是。
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Acme.BookStore.Plantas
{
public interface IPlantaAppService :
ICrudAppService< //Defines CRUD methods
PlantDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdatePlantDto> //Used to create/update a book
{
}
}
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Plantas
{
public class PlantaAppService:
CrudAppService<
Planta, //The Book entity
PlantDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdatePlantDto>, //Used to create/update a book
IPlantaAppService //implement the IPlantaAppService
{
public BookAppServicePlanta(IRepository<Planta, Guid> repository)
: base(repository)
{
}
}
}
我是ABP新手,我this oficial tutorial成功了。
然后我添加了另一个 class (Planta) 并再次按照教程进行操作(没有删除 The Book class),但即使我可以创建 table并在其上提供数据(已验证),应用程序无法加载 table,当我检查 swagger 时,我发现了这个...
我原以为它是 Planta 而不是 BookAppServicePlanta,但我找不到哪里搞砸了。
我尝试解决的问题
- 我读过的关于 ABP 的资料最多。
- 我已经将每个 Planta 文件与它的 Book 副本进行了对比。
- 我已经删除数据库很多次了。
这是我所做的(详情如下):
- 我在
Acme.BookStore.Domain/Planta/Planta.cs
上创建了 class 植物群: - 将实体添加到
Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs
- 将实体映射到
Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs
上的 table
- 删除了数据库,并删除了以前的迁移
- 创建了数据播种器
Acme.BookStore.Domain/BookStoreDataSeederContributor_Plant.cs
- 添加了新的迁移,并且 运行
Acme.BookStore.DbMigrator
- 已创建
Acme.BookStore.Application.Contracts/PlantDto.cs
- 已将其添加到
Acme.BookStore.Application/BookStoreApplicationAutoMapperProfile.cs
- 创建了
Acme.BookStore.Application.Contracts/CreateUpdatePlantDto.cs
(并将其也添加到自动映射器中,如 8 所示)) - 创建界面
Acme.BookStore.Application.Contracts/IBookAppServicePlanta.cs
- 已在
Acme.BookStore.Application/BookAppServicePlanta.cs
上实施
- 运行 申请
额外信息: 我为 Planta 及其表单创建了页面(教程第 2 部分和第 3 部分),但即使我仔细检查了这些文件,我也不相信问题出在这些文件上,因为 swagger 问题。
我在
Acme.BookStore.Domain/Planta/Planta.cs
上创建了 class 植物群:using System; using Volo.Abp.Domain.Entities.Auditing; namespace Acme.BookStore.Plantas { public class Planta : AuditedAggregateRoot<Guid> { public string Nombre { get; set; } public string Descripcion { get; set; } public string Dirección { get; set; } public string Lat { get; set; } public string Long { get; set; } public string Extra1 { get; set; } public string Extra2 { get; set; } public string Extra3 { get; set; } } }
将实体添加到
Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs
using Microsoft.EntityFrameworkCore; using Acme.BookStore.Users; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.Identity; using Volo.Abp.Users.EntityFrameworkCore; using Acme.BookStore.Books; using Acme.BookStore.Plantas; namespace Acme.BookStore.EntityFrameworkCore { /* This is your actual DbContext used on runtime. * It includes only your entities. * It does not include entities of the used modules, because each module has already * its own DbContext class. If you want to share some database tables with the used modules, * just create a structure like done for AppUser. * * Don't use this DbContext for database migrations since it does not contain tables of the * used modules (as explained above). See BookStoreMigrationsDbContext for migrations. */ [ConnectionStringName("Default")] public class BookStoreDbContext : AbpDbContext<BookStoreDbContext> { public DbSet<AppUser> Users { get; set; } public DbSet<Book> Books { get; set; } public DbSet<Planta> Plantas { get; set; } /* Add DbSet properties for your Aggregate Roots / Entities here. * Also map them inside BookStoreDbContextModelCreatingExtensions.ConfigureBookStore */ public BookStoreDbContext(DbContextOptions<BookStoreDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); /* Configure the shared tables (with included modules) here */ builder.Entity<AppUser>(b => { b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser b.ConfigureByConvention(); b.ConfigureAbpUser(); /* Configure mappings for your additional properties * Also see the BookStoreEfCoreEntityExtensionMappings class */ }); /* Configure your own tables/entities inside the ConfigureBookStore method */ builder.ConfigureBookStore(); } } }
将实体映射到
上的 tableAcme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContextModelCreatingExtensions.cs
using Acme.BookStore.Books; using Acme.BookStore.Plantas; using Microsoft.EntityFrameworkCore; using Volo.Abp; using Volo.Abp.EntityFrameworkCore.Modeling; namespace Acme.BookStore.EntityFrameworkCore { public static class BookStoreDbContextModelCreatingExtensions { public static void ConfigureBookStore(this ModelBuilder builder) { Check.NotNull(builder, nameof(builder)); /* Configure your own tables/entities inside here */ builder.Entity<Book>(b => { b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema); b.ConfigureByConvention(); //auto configure for the base class props b.Property(x => x.Name).IsRequired().HasMaxLength(128); }); builder.Entity<Planta>(p => { p.ToTable(BookStoreConsts.DbTablePrefix + "Plantas", BookStoreConsts.DbSchema); p.ConfigureByConvention(); //auto configure for the base class props p.Property(y => y.Nombre).IsRequired().HasMaxLength(128); }); } } }
删除了数据库,并删除了以前的迁移
创建了数据播种器
Acme.BookStore.Domain/BookStoreDataSeederContributor_Plant.cs
using System; using System.Threading.Tasks; using Acme.BookStore.Plantas; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; namespace Acme.BookStore { public class BookStoreDataSeederContributor_Plant : IDataSeedContributor, ITransientDependency { private readonly IRepository<Planta, Guid> _plantaRepository; public BookStoreDataSeederContributor_Plant(IRepository<Planta, Guid> plantaRepository) { _plantaRepository = plantaRepository; } public async Task SeedAsync(DataSeedContext context) { if (await _plantaRepository.GetCountAsync() > 0) { return; } await _plantaRepository.InsertAsync( new Planta { Nombre = "Armijo Guajardo", Descripcion = "excel god", Dirección = "las lilas 123", Lat = "564.765.98", Long = "100.102.04", Extra1 = "bla", Extra2 = "bla bla", Extra3 = "bla bla bla" }, autoSave: true ); } } }
添加了一个新的迁移,并且运行
Acme.BookStore.DbMigrator
已创建
Acme.BookStore.Application.Contracts/PlantDto.cs
using System; using Volo.Abp.Application.Dtos; namespace Acme.BookStore.Plantas { public class PlantDto : AuditedEntityDto<Guid> { public string Nombre { get; set; } public string Descripcion { get; set; } public string Dirección { get; set; } public string Lat { get; set; } public string Long { get; set; } public string Extra1 { get; set; } public string Extra2 { get; set; } public string Extra3 { get; set; } } }
添加到
Acme.BookStore.Application/BookStoreApplicationAutoMapperProfile.cs
using Acme.BookStore.Books; using Acme.BookStore.Plantas; using AutoMapper; namespace Acme.BookStore { public class BookStoreApplicationAutoMapperProfile : Profile { public BookStoreApplicationAutoMapperProfile() { CreateMap<Book, BookDto>(); CreateMap<CreateUpdateBookDto, Book>(); CreateMap<Planta, PlantDto>(); CreateMap<CreateUpdatePlantDto, Planta>(); } } }
创建了
Acme.BookStore.Application.Contracts/CreateUpdatePlantDto.cs
(并将其添加到自动映射器中,如 8 所示))using System; using System.ComponentModel.DataAnnotations; namespace Acme.BookStore.Plantas { public class CreateUpdatePlantDto { [Required] [StringLength(128)] public string Nombre { get; set; } [Required] [StringLength(128)] public string Descripcion { get; set; } [Required] [StringLength(128)] public string Dirección { get; set; } [Required] [StringLength(128)] public string Lat { get; set; } [Required] [StringLength(128)] public string Long { get; set; } [Required] [StringLength(128)] public string Extra1 { get; set; } [Required] [StringLength(128)] public string Extra2 { get; set; } [Required] [StringLength(128)] public string Extra3 { get; set; } } }
创建了界面
Acme.BookStore.Application.Contracts/IBookAppServicePlanta.cs
using System; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace Acme.BookStore.Plantas { public interface IBookAppServicePlanta : ICrudAppService< //Defines CRUD methods PlantDto, //Used to show books Guid, //Primary key of the book entity PagedAndSortedResultRequestDto, //Used for paging/sorting CreateUpdatePlantDto> //Used to create/update a book { } }
已在
上实施Acme.BookStore.Application/BookAppServicePlanta.cs
using System; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; namespace Acme.BookStore.Plantas { public class BookAppServicePlanta : CrudAppService< Planta, //The Book entity PlantDto, //Used to show books Guid, //Primary key of the book entity PagedAndSortedResultRequestDto, //Used for paging/sorting CreateUpdatePlantDto>, //Used to create/update a book IBookAppServicePlanta //implement the IBookAppService { public BookAppServicePlanta(IRepository<Planta, Guid> repository) : base(repository) { } } }
运行 申请
[编辑]
Acme.BookStore.Web/BookStoreWebAutoMapperProfile.cs
看起来像这样
using Acme.BookStore.Books;
using Acme.BookStore.Plantas;
using AutoMapper;
namespace Acme.BookStore.Web
{
public class BookStoreWebAutoMapperProfile : Profile
{
public BookStoreWebAutoMapperProfile()
{
CreateMap<BookDto, CreateUpdateBookDto>();
CreateMap<PlantDto, CreateUpdatePlantDto>();
}
}
}
[编辑]
我创建了一个teting文件Acme.BookStore.Application.Tests/BookAppServicePlanta_test.cs
,他们都成功了。
using System;
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Validation;
using Xunit;
namespace Acme.BookStore.Plantas
{
public class BookAppService_Tests : BookStoreApplicationTestBase
{
private readonly IBookAppServicePlanta _plantaAppService;
public BookAppService_Tests()
{
_plantaAppService = GetRequiredService<IBookAppServicePlanta>();
}
[Fact]
public async Task Should_Get_List_Of_Books()
{
//Act
var result = await _plantaAppService.GetListAsync(
new PagedAndSortedResultRequestDto()
);
//Assert
result.TotalCount.ShouldBeGreaterThan(0);
result.Items.ShouldContain(b => b.Nombre == "Armijo Guajardo");
}
[Fact]
public async Task Should_Create_A_Valid_Planta()
{
//Act
var result = await _plantaAppService.CreateAsync(
new CreateUpdatePlantDto
{
Nombre = "Pedro Cano",
Descripcion = "Cirujano",
Dirección = "Pedro de Valdivia",
Lat = "123213213",
Long = "456456456",
Extra1 = "emmmm",
Extra2 = "no se",
Extra3 = "que poner"
}
);
//Assert
result.Id.ShouldNotBe(Guid.Empty);
result.Nombre.ShouldBe("Pedro Cano");
}
[Fact]
public async Task Should_Not_Create_A_Planta_Without_Name()
{
var exception = await Assert.ThrowsAsync<AbpValidationException>(async () =>
{
await _plantaAppService.CreateAsync(
new CreateUpdatePlantDto
{
Descripcion = "Cirujano",
Dirección = "Pedro de Valdivia",
Lat = "123213213",
Long = "456456456",
Extra1 = "emmmm",
Extra2 = "no se",
Extra3 = "que poner"
}
);
});
exception.ValidationErrors
.ShouldContain(err => err.MemberNames.Any(mem => mem == "Nombre"));
}
}
}
我对 ABP 不熟悉,但是快速查看文档,您似乎没有遵循命名约定。
应用程序服务应遵循以下命名约定:Entity
AppService
但您似乎 copied/pasted 之前的 class BookAppService
只是在末尾添加了 Planta
。它应该是 PlantaAppService
而不是。
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Acme.BookStore.Plantas
{
public interface IPlantaAppService :
ICrudAppService< //Defines CRUD methods
PlantDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdatePlantDto> //Used to create/update a book
{
}
}
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Plantas
{
public class PlantaAppService:
CrudAppService<
Planta, //The Book entity
PlantDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdatePlantDto>, //Used to create/update a book
IPlantaAppService //implement the IPlantaAppService
{
public BookAppServicePlanta(IRepository<Planta, Guid> repository)
: base(repository)
{
}
}
}