标签:startup file end ocs bpm 解决 contract 精简 生成
我们基于官方教程并结合下列教程,继续。
在Acme.BookStore.Application.Contracts
中添加BookDto.cs
和CreateUpdateBookDto.cs
namespace Acme.BookStore.Application.Contracts.Dtos
{
public class BookDto : AuditedEntityDto<Guid>
{
public string Name { get; set; }
public BookType Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
}
}
namespace Acme.BookStore.Application.Contracts.Dtos
{
public class CreateUpdateBookDto
{
[Required]
[StringLength(128)]
public string Name { get; set; }
[Required]
public BookType Type { get; set; } = BookType.Undefined;
[Required]
[DataType(DataType.Date)]
public DateTime PublishDate { get; set; } = DateTime.Now;
[Required]
public float Price { get; set; }
}
}
在Acme.BookStore.Application
中添加BookStoreApplicationAutoMapperProfile.cs
namespace Acme.BookStore.Application
{
public class BookStoreApplicationAutoMapperProfile : Profile
{
public BookStoreApplicationAutoMapperProfile()
{
CreateMap<Book, BookDto>();
CreateMap<CreateUpdateBookDto, Book>();
}
}
}
在Acme.BookStore.Application.Contracts
中添加IBookAppService.cs
namespace Acme.BookStore.Application.Contracts.IServices
{
public interface IBookAppService :
ICrudAppService< //定义CRUD方法
BookDto, //用于展示
Guid, //实体主键类型
PagedAndSortedResultRequestDto, //用于分页
CreateUpdateBookDto> //用于新增或修改
{
}
}
在Acme.BookStore.Application
中添加BookAppService.cs
namespace Acme.BookStore.Application.Services
{
public class BookAppService :
CrudAppService<
Book, //Book实体
BookDto, //用于展示
Guid, //实体主键类型
PagedAndSortedResultRequestDto, //用于分页
CreateUpdateBookDto>, //用于新增或修改
IBookAppService //实现IBookAppService
{
public BookAppService(IRepository<Book, Guid> repository)
: base(repository)
{
}
}
}
在Acme.BookStore.WebApi
中修改Startup.cs
namespace Acme.BookStore.WebApi
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddApplication<BookStoreWebApiModule>();//添加Application
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.InitializeApplication();//初始化Application
}
}
}
在Abp中,原本在Startup中的配置,全部搬到
BookStoreWebApiModule
中进行配置。
所以Startup最终就剩这几句代码。
在Acme.BookStore.WebApi
中添加BookStoreWebApiModule.cs
namespace Acme.BookStore.WebApi
{
public class BookStoreWebApiModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
ConfigureAutoApiControllers();
ConfigureSwaggerServices(context.Services);
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Acme.BookStore.WebApi");
});
app.UseRouting();
app.UseConfiguredEndpoints();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
context.Response.Redirect("/swagger");
});
});
}
private void ConfigureAutoApiControllers()
{
Configure<AbpAspNetCoreMvcOptions>(options =>
{
//自动创建Controller
options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly);
});
}
private void ConfigureSwaggerServices(IServiceCollection services)
{
services.AddSwaggerGen(
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{ Title = "Acme.BookStore.WebApi", Version = "v1.0" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
}
);
}
}
}
这里我们主要是重载2个方法
ConfigureServices
和OnApplicationInitialization
方法。基本可以理解对应Startup的ConfigureServices
和Configure
Acme.BookStore.WebApi
中编辑appsettings.json
,添加数据库连接
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Acme.BookStore;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
如果这时候我们运行Acme.BookStore.WebApi
,发现报错了!我们该引用的都引用了,为什么还报错?
因为Abp是以Module来定义模块的。解决方案里各个项目层不都是创建了Module类并继承AbpModule吗?
如果你自己写的模块需要使用其他模块(依赖注入),那么须在Module
类上添加DependsOn
特性代码。不然基本会报错:Some services are not able to be constructed
。
namespace Acme.BookStore.WebApi
{
[DependsOn(typeof(AbpAspNetCoreMvcModule),//用到Abp自动生成自动创建Controller方法
typeof(BookStoreApplicationModule),//用到了Application层,提供服务
typeof(BookStoreEntityFrameworkCoreModule))]//用到了数据库实现
public class BookStoreWebApiModule : AbpModule
{
...
}
}
同理,其他项目中Module
类是不是也应该添加DependsOn
特性!
Acme.BookStore.Application
中编辑BookStoreApplicationModule.cs
namespace Acme.BookStore.Application
{
[DependsOn(typeof(AbpAutoMapperModule),
typeof(BookStoreDomainModule),
typeof(BookStoreApplicationContractsModule))]
public class BookStoreApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<BookStoreApplicationModule>();
});
}
}
}
除了添加
DependsOn
外,我们还得添加Map配置。options.AddMaps<BookStoreApplicationModule>();
会去加载继承Profile
的类。
Acme.BookStore.EntityFrameworkCore
中编辑BookStoreEntityFrameworkCoreModule.cs
namespace Acme.BookStore.EntityFrameworkCore
{
[DependsOn(typeof(BookStoreDomainModule),
typeof(AbpEntityFrameworkCoreSqlServerModule))]
public class BookStoreEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<BookStoreDbContext>(options =>
{
options.AddDefaultRepositories();//添加Abp默认Repositories实现
});
Configure<AbpDbContextOptions>(options =>
{
options.UseSqlServer();//使用SqlServer数据库
});
}
}
}
除了添加
DependsOn
外,我们还得配置数据库及数据仓库。
这时,再运行!发现swagger可以正常浏览了。我们测试一下Book添加方法(post /api/app/book)。先点Try it out
按钮,再直接点击Execute
按钮。
咦?报错了An internal error occurred during your request!
。
经过不停错误查找,原来是Acme.BookStore.Application
中BookAppService
所继承的CrudAppService中的ObjectMapper
属性报错了。
CrudAppService
自带的CreateAsync
方法中代码使用ObjectMapper.Map<Book,BookDto>(input)
。
几经周折,发现需要使用Autofac
才行。于是乎,在Acme.BookStore.WebApi
的Program.cs
添加UseAutofac()
,代码如下:
namespace Acme.BookStore.WebApi
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseAutofac();
}
}
这里添加完后,我们还得在Acme.BookStore.WebApi
中BookStoreWebApiModule
添加AbpAutofacModule
的依赖。
[DependsOn(typeof(AbpAutofacModule),
typeof(AbpAspNetCoreMvcModule),//用到Abp自动生成自动创建Controller方法
typeof(BookStoreApplicationModule),//用到了Application层,提供服务
typeof(BookStoreEntityFrameworkCoreModule))]//用到了数据库实现
public class BookStoreWebApiModule : AbpModule
{
...
}
这时,再运行!发现swagger可以正常浏览了。我们测试一下Book添加方法(post /api/app/book)。先点Try it out
按钮,再直接点击Execute
按钮。
成功了!再试试其他方法,都返回正确结果。
标签:startup file end ocs bpm 解决 contract 精简 生成
原文地址:https://www.cnblogs.com/HUGO_CM/p/13803508.html