01手动搭建基本的ABP框架

手动搭建基本的ABP框架

ABP是用于创建现代Web应用程序的完整架构和强大的基础设施! 遵循最佳实践和约定,为你提供SOLID开发经验。

创建项目

创建类库:

  • Domian
  • Domain.Shared
  • Application
  • Application.Contracts
  • EntityFrameworkCore
  • HttpApi
  • HttpApi.Client

创建ASP.NET Core Web 应用 HttpApi.Host,作为后端接口主机。

Domain.Shared

领域共享层,该层存放领域层的常量、枚举、值对象、本土化配置文件和其他对象,这些对象实际是领域层的一部分,但是解决方案中所有的层/项目中都会使用到。

  • 该项目不依赖解决中的其他项目,其他项目直接或间接引用该项目。

需要添加的Nugget包:

  • Volo.Abp.Localization Volo 本地化模块,使应用程序支持全球化

创建文件夹Localization/MyLocalization,在该文件夹下放语言配置配置文件(如:zh-Hans.json)。

zh-Hans.json配置如下:

{
"culture": "zh-Hans",
"texts": {
"LongWelcomeMessage": "欢迎使用Abp框架",
// 一些其它配置
}
}

在文件夹Localization文件夹下新增类MyLocalizationResource.cs,添加以下代码:

namespace Domain.Shared.Localization
{
[LocalizationResourceName("MyLocalization")]
public class MyLocalizationResource
{
}
}

在根目录下新增类DomainSharedModule.cs,添加以下代码:

namespace Domain.Shared
{
// 添加依赖 本地化模组
[DependsOn(
typeof(AbpLocalizationModule)
)]
public class DomainSharedModule : AbpModule // 必须继承AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// 配置虚拟文件系统 配置全球化资源文件必须配置该选项
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<DomainSharedModule>();
});
// 配置全球化资源文件
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<MyLocalizationResource>("zh-Hans")
.AddVirtualJson("/Localization/MyLocalization");
options.DefaultResourceType = typeof(MyLocalizationResource);
});
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("MyLocalization", typeof(MyLocalizationResource));
});
base.ConfigureServices(context);
}
}
}

Domian

领域层,在该层实现系统核心业务逻辑,该层主要包含实体、集合跟、领域服务、值类型、仓储接口和解决方案的其他领域对象

  • 依赖Domain.Shared,项目中会用到它的一些常量、枚举、值对象和其他对象。

需要添加的Nugget包:

  • Volo.Abp.Ddd.Domain 领域驱动模块

添加类DomainModule.cs,添加以下代码:

namespace Domain
{
// 依赖领域驱动模块
// 依赖领域共享模块
[DependsOn(
typeof(AbpDddDomainModule),
typeof(DomainSharedModule)
)]
public class DomainModule:AbpModule
{
}
}

Application.Contracts

应用约定层,该层存放应用服务接口、数据传输对象、应用层常量和应用层提供程序。他用于分离应用层的接口和实现。这种方式可以将接口项目做为约定包共享给客户端。

  • 依赖Domain.Shared,因为它可能会在应用接口和DTO中使用常量、枚举和其他的共享对象。

需要添加的Nugget包:

  • Volo.Abp.Ddd.Application.Contracts 应用层约定模块

添加类ApplicationContractsModule.cs,添加以下代码:

namespace Application.Contracts
{
// 依赖应用层约定模块
// 依赖领域共享模块
[DependsOn(
typeof(AbpDddApplicationContractsModule),
typeof(DomainSharedModule)
)]
public class ApplicationContractsModule:AbpModule
{
}
}

Application

应用层,该层实现系统应用业务逻辑,实现服务接口。

  • 依赖Application.Contracts,需要实现服务接口与使用DTO。
  • 依赖Domain需要使用领域对象(实体、仓储接口等)执行应用程序逻辑。

需要添加Nugget包:

  • Volo.Abp.Ddd.Application 应用层模块
  • Volo.Abp.AutoMapper 自动映射模块

添加类ApplicationAutoMapperProfile.cs ,应用层自动映射配置类,添加以下代码:

namespace Application
{
public class ApplicationAutoMapperProfile: Profile
{
public ApplicationAutoMapperProfile()
{
// 配置自动映射
//CreateMap<T1, T2>();
}
}
}

添加类ApplicationModule.cs,添加以下代码:

namespace Application
{
// 依赖自动配置模块
// 依赖领域驱动应用层模块
// 依赖领域模块
// 依赖应用层约定模块
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpDddApplicationModule),
typeof(DomainModule),
typeof(ApplicationContractsModule)
)]
public class ApplicationModule:AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
base.ConfigureServices(context);
// 配置自动映射
Configure<AbpAutoMapperOptions>(options => {
options.AddMaps<ApplicationModule>();
});
}
}
}

EntityFrameworkCore

数据库层,定义了DbContext并实现Domain项目中定义的仓储接口。

  • 依赖Domain,需要引用实体和实现仓储接口。

需要添加Nugget包:

  • Volo.Abp.EntityFrameworkCore.SqlServer SqlServer数据库模块

添加类EntityFrameworkCoreModule.cs,添加以下代码

namespace EntityFrameworkCore
{
// 依赖SqlServer数据库模块
[DependsOn(
typeof(AbpEntityFrameworkCoreSqlServerModule),
typeof(DomainModule)
)]
public class EntityFrameworkCoreModule:AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
base.ConfigureServices(context);
// 配置使用 SqlServer
// Configure<AbpDbContextOptions>(options =>
// {
// options.UseSqlServer();
// });
}
}
}

HttpApi

用于定义API控制器。

大多数情况下,不需要手动定义API控制器,因为ABP的动态API功能会根据应用层自动创建API控制器。但是,如果你需要编写API控制器,则可以在该层中定义。

  • 依赖Application.Contracts 项目,因为它需要注入应用服务接口

需要添加Nugget包:

  • Volo.Abp.AspNetCore.Mvc AspNetCore MVC模块

添加类HttpApiModule.cs,添加以下代码

namespace HttpApi
{
// 依赖MVC模块
// 依赖应用约定模块
[DependsOn(
typeof(AbpAspNetCoreMvcModule),
typeof(ApplicationContractsModule)
)]
public class HttpApiModule:AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
ConfigureLocalization();
base.ConfigureServices(context);
}
private void ConfigureLocalization()
{
// 配置本地化资源库
Configure<AbpLocalizationOptions>(options => {
options.Resources
.Get<MyLocalizationResource>()
.AddBaseTypes(typeof(AbpUiResource));
});
}
}
}

HttpApi.Client

定义C#客户端代理,使用解决方案的HttpAPI项目。可以将该项目共享给第三方客户端,使其轻松的在DotNet应用程序中使用你的HttpAPI(其他类型应用程序可以手动或使用其平台的工具来使用你的API)。

ABP有动态C#API客户端功能,所以大多数情况下你不需要手动创建C#客户端代理。

  • 依赖Application.Contracts,需要使用应用服务接口和DTO

需要添加Nugget包:

  • Volo.Abp.Http.Client

添加类HttpApiClientModule.cs,添加以下代码

namespace HttpApi.Client
{
[DependsOn(
typeof(AbpHttpClientModule),
typeof(ApplicationContractsModule)
)]
public class HttpApiClientModule:AbpModule
{
public const string RemoteServiceName = "Default";
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddHttpClientProxies(
typeof(ApplicationContractsModule).Assembly,
RemoteServiceName
);
Configure<AbpVirtualFileSystemOptions>(options => {
options.FileSets.AddEmbedded<HttpApiClientModule>();
});
}
}
}

HttpApi.Host

HttpAPI主机层,她有自己的appsettings.json文件(数据库链接字符串等其他配置)

  • 依赖HttpApi

由于没有使用分层模式(没有选择--tiered选项),还同时依赖:

  • Application
  • EntityFrameworkCore

需要添加Nugget包:

  • Volo.Abp.Autofac 依赖注入模块
  • Volo.Abp.Swashbuckle

添加类HttpApiHostModule.cs,添加以下代码:

namespace HttpApi.Host
{
[DependsOn(
typeof(HttpApiModule),
typeof(AbpAutofacModule),
typeof(ApplicationModule),
typeof(EntityFrameworkCoreModule),
typeof(AbpSwashbuckleModule)
)]
public class HttpApiHostModule:AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var hostingEnvironment = context.Services.GetHostingEnvironment();
ConfigureUrls(configuration);
ConfigureVirtualFileSystem(context);
ConfigureConventionalControllers();
ConfigureLocalization();
ConfigureCors(context, configuration);
ConfigureSwaggerServices(context, configuration);
}
/// <summary>
/// 配置URL
/// </summary>
/// <param name="configuration"></param>
private void ConfigureUrls(IConfiguration configuration)
{
// 前端Ui地址配置
// Configure<AppUrlOptions>(options =>
// {
// options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
// options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(','));
// options.Applications["Angular"].RootUrl = configuration["App:ClientUrl"];
// });
}
/// <summary>
/// 配置 虚拟文件系统
/// </summary>
/// <param name="context"></param>
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
if (hostingEnvironment.IsDevelopment())
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.ReplaceEmbeddedByPhysical<DomainSharedModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Domain.Shared"));
options.FileSets.ReplaceEmbeddedByPhysical<DomainModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Domain"));
options.FileSets.ReplaceEmbeddedByPhysical<ApplicationContractsModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Application.Contracts"));
options.FileSets.ReplaceEmbeddedByPhysical<ApplicationModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}Application"));
});
}
}
/// <summary>
/// 配置 传统的控制器
/// </summary>
private void ConfigureConventionalControllers()
{
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(ApplicationModule).Assembly);
});
}
private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
{
// swagger配置及授权地址配置
context.Services.AddAbpSwaggerGenWithOAuth(
configuration["AuthServer:Authority"],
new Dictionary<string, string>
{
{"StudyAcme", "StudyAcme API"}
},
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "StudyAcme API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
});
}
/// <summary>
/// 配置本地化
/// </summary>
private void ConfigureLocalization()
{
Configure<AbpLocalizationOptions>(options =>
{
//options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
//options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
//options.Languages.Add(new LanguageInfo("en", "en", "English"));
//options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
//options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
//options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
//options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
//options.Languages.Add(new LanguageInfo("is", "is", "Icelandic", "is"));
//options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
//options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
//options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
//options.Languages.Add(new LanguageInfo("ro-RO", "ro-RO", "Română"));
//options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
//options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
//options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
//options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
//options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch", "de"));
//options.Languages.Add(new LanguageInfo("es", "es", "Español", "es"));
//options.Languages.Add(new LanguageInfo("el", "el", "Ελληνικά"));
});
}
/// <summary>
/// 配置Cors
/// <para>
/// 配置跨域请求
/// </para>
/// </summary>
/// <param name="context"></param>
/// <param name="configuration"></param>
private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
// ajax跨域访问白名单,没有配置,注释掉
//.WithOrigins(
// configuration["App:CorsOrigins"]
// .Split(",", StringSplitOptions.RemoveEmptyEntries)
// .Select(o => o.RemovePostFix("/"))
// .ToArray()
//)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
public override void OnApplicationInitialization(Volo.Abp.ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseUnitOfWork();
app.UseAuthorization();
app.UseSwagger();
app.UseAbpSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "StudyAcme API");
var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>();
c.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
c.OAuthScopes("StudyAcme");
});
app.UseAuditing();
app.UseConfiguredEndpoints();
}
}
}

Program.cs类中添加代码:

await builder.AddApplicationAsync<HttpApiHostModule>();

Program.cs完整代码:

using BlankAbp.HttpApi.Host;
try
{
var builder = WebApplication.CreateBuilder(args);
builder.Host.AddAppSettingsSecretsJson()
.UseAutofac();
await builder.AddApplicationAsync<HttpApiHostModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
return 0;
}
catch (Exception ex)
{
if (ex is HostAbortedException)
{
throw;
}
return 1;
}
finally
{
}

appsettings.json配置为:

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"AuthServer": {
// swagger授权地址
"Authority": "https://localhost:7067",
"RequireHttpsMetadata": "false",
"SwaggerClientId": "BlankAbp_Swagger"
}
}

添加测试服务

Application项目中添加类ApplicationAppService,并添加以下代码

/// <summary>
/// 应用层服务基类
/// </summary>
public abstract class ApplicationAppService:ApplicationService
{
protected ApplicationAppService()
{
// 配置本地资源
LocalizationResource = typeof(MyLocalizationResource);
}
}

Application项目中添加类TestService,并添加以下代码

public class TestService: ApplicationAppService
{
private IStringLocalizer<MyLocalizationResource> _l;
public TestService( IStringLocalizer<MyLocalizationResource> l) {
_l = l;
}
public string GetTest()
{
return "test service";
}
public string GetWellCome()
{
return _l["LongWelcomeMessage"].Value;
}
}

运行HttpApi.Host可见以下API:
Api

语言选择

使用/Abp/Languages/Switch?culture=zh-Hans&uiCulture=zh-Hans&returnUrl=/ 接口进行语言切换,该接口会在Cookie中添加或更新 lpx_lang=ZH; .AspNetCore.Culture=c=zh-Hans|uic=zh-Hans

示例代码

posted @   $("#阿飞")  阅读(1301)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示