1 重构Core.Infrastructure.Engine.ConfigureServices
public virtual void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
//把“Engine”实例存储到单例实例的字典成员实例中。
services.AddSingleton
//从单例实例的字典成员实例中获取获取Web应用程序域类型查找器实例。
var typeFinder = Singleton
//获取继承于“IStartup”的所有具体实现类的类型实例。
var startupConfigurations = typeFinder.FindClassesOfType
//通过反射方式把继承于“IStartup”的所有具体实现类进行实例化操作。
var instances = startupConfigurations
.Select(startup => (IStartup)Activator.CreateInstance(startup))
.OrderBy(startup => startup!.Order);
//把继承于“IStartup”的所有具体实现类的实例,依赖注入到.Net(Core)内置依赖注入容器实例中。
foreach (var instance in instances)
instance!.ConfigureServices(services, configuration);
services.AddSingleton(services);
}
2 Core.Infrastructure.IStartup
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Core.Infrastructure
{
///
/// 【启动--接口】
///
/// 摘要:
/// 把承于该接口的具体实现类,把具有某项特定功能的依赖注入中间件实例和管道中间件实例,集成到.NetCore框架中,使用基于.NetCore框架的应用程序正常运行或拥有该有特定功能。
///
///
public partial interface IStartup
{
#region 属性--接口实现
///
/// 【顺序】
///
/// 摘要:
/// 获取继承于“IStartup”接口的具体实现类中管的道中间件实例,被集成到内置管道实例中的顺序,默认值:10。
/// 注意:
/// .NetCore框架默定义了一些常用的内置管道中间件,并默认规定了这些内置管道中间件实例在内置管道实例中被调用的顺序,
/// 如果不按照该默认顺序调用这些内置管道中间件,在程序执行时就会出现逻辑异常。
///
///
int Order { get; }
#endregion
#region 方法--接口实现
/// .Net(Core)框架内置依赖注入容器实例。
/// .NetCore框架内置配置接口实例(存储着当前程序中所有*.json文件中的数据)。
///
/// 【配置服务】
///
/// 摘要:
/// 通过该方法成员,具有某项特定功能依赖注入中间件实例,注入到.Net(Core)框架内置依赖注入容器实例中。
///
///
void ConfigureServices(IServiceCollection services, IConfiguration configuration);
/// .NetCore框架内置管道接口实例。
///
/// 【配置】
///
/// 摘要:
/// 把参与程序与页面的“应/答”操作的具有某项特定功能的管道中间件实例,集成到.Net(Core)框架内置管道实例中。
///
///
void Configure(IApplicationBuilder application);
#endregion
}
}
3 Framework.Infrastructure.DependencyInjectionStartup
using Core.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Framework.Infrastructure
{
///
/// 【依赖注入启动--类】
///
/// 摘要:
/// 通过该类中的依赖注入方法成员,对当前程序中的依赖注入定义操作进行集中管理。
///
///
public class DependencyInjectionStartup : IStartup
{
#region 属性--接口实现
///
/// 【顺序】
///
/// 摘要:
/// 获取依赖注入启动类中管道中间件实例,被集成到内置管道实例中的顺序,默认值:2000。
/// 注意:
/// .NetCore框架默定义了一些常用的内置管道中间件,并默认规定了这些内置管道中间件实例在内置管道实例中被调用的顺序,
/// 如果不按照该默认顺序调用这些内置管道中间件,在程序执行时就会出现逻辑异常。
///
///
public int Order => 2000;
#endregion
#region 方法--接口实现
/// .Net(Core)框架内置依赖注入容器实例。
/// .NetCore框架内置配置接口实例(存储着当前程序中所有*.json文件中的数据)。
///
/// 【配置服务】
///
/// 摘要:
/// 通过该方法成员,对当前程序中的依赖注入定义操作进行集中管理。
///
///
public virtual void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddScoped
}
/// .NetCore框架内置管道接口实例。
///
/// 【配置】
///
/// 摘要:
/// 依赖注入功能不参与程序与页面的“应/答”操作,所有该方法成员中没有管道中间件集成到内置管道中间件的任何定义。
///
///
public void Configure(IApplicationBuilder application)
{
}
#endregion
}
}
4 Framework.Infrastructure.DbStartup
using Core.Infrastructure;
using Framework.Infrastructure.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Framework.Infrastructure
{
///
/// 【数据库启动--类】
///
/// 摘要:
/// 通过该类中的依赖注入方法成员,抽离“EntityFrameworkCore”中间件实例的依赖注入操作,为当前程序通过“EntityFrameworkCore”中间件实例与指定数据库软件中指定数据库的CURD交互操作,提供实例支持。
///
///
public class DbStartup : IStartup
{
#region 属性--接口实现
///
/// 【顺序】
///
/// 摘要:
/// 获取数据库启动类中管道中间件实例,被集成到内置管道实例中的顺序,默认值:10。
/// 注意:
/// .NetCore框架默定义了一些常用的内置管道中间件,并默认规定了这些内置管道中间件实例在内置管道实例中被调用的顺序,
/// 如果不按照该默认顺序调用这些内置管道中间件,在程序执行时就会出现逻辑异常。
///
///
public int Order => 10;
#endregion
#region 方法--接口实现
/// .Net(Core)框架内置依赖注入容器实例。
/// .NetCore框架内置配置接口实例(存储着当前程序中所有*.json文件中的数据)。
///
/// 【配置服务】
///
/// 摘要:
/// 通过该方法成员,抽离“EntityFrameworkCore”中间件实例的依赖注入操作,为当前程序通过“EntityFrameworkCore”中间件实例与指定数据库软件中指定数据库的CURD交互操作,提供实例支持。
///
///
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
//抽离“EntityFrameworkCore”中间件实例的依赖注入操作,为当前程序通过“EntityFrameworkCore”中间件实例与指定数据库软件中指定数据库的CURD交互操作,提供实例支持。
services.AddEFCoreContext();
}
/// .NetCore框架内置管道接口实例。
///
/// 【配置】
///
/// 摘要:
/// 数据库的CURD功能不参与程序与页面的“应/答”操作,有该方法成员中没有管道中间件集成到内置管道中间件的任何定义。
///
///
public void Configure(IApplicationBuilder application)
{
}
#endregion
}
}
5 Data.EFCoreContext.CreateDatabaseAndTableAsync
///
/// 【异步自动生成数据及其表?】
///
/// 摘要:
/// 获取1个值false(未生成)/true(已经生成),该值指示是否通过“EntityFrameworkCore”中间件在1个指定的数据库软件中是否已经自动生成1个指定的数据库及其表。
///
///
/// 返回:
/// 1个值false(未生成)/true(已经生成)。
///
///
public async Task
{
return await Database.EnsureCreatedAsync();
}
6 重构Program.cs文件
using Core.Infrastructure;
using Data;
using Framework.Infrastructure.Extensions;
var builder = WebApplication.CreateBuilder(args);
//如果启动项中不存在“appsettings.json”文件,则通过.Net(Core)的内置方法自动新建“appsettings.json”文件。
builder.Configuration.AddJsonFile("appsettings.json", true, true);
//把当前程序中所有继承了“IConfig”接口的具体实现类的实例,依赖注入到.Net(Core)内置依赖注入容器实例中,如果需要并把这些数据持久化存储到"appsettings.json"文件。
builder.Services.ConfigureApplicationSettings(builder);
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//把具体现类和中间件注入到内置依赖注入容器后,并把.NetCore框架内置依赖注入容器接口实例所存储的当前程序中的具体现类和中间件的实例通过“Engine”(引擎)单例实例存储到单例类的字典属性成员实例中。
//注意:从依赖注入到.Net(Core)框架内置容器中,获取“IServiceProvider”接口实例,必须定义在最后,
//否则“GetServices”/“GetRequiredService”方法将有可能不能获取取1个指定类的实例,因为该类的实例还没有依赖注入到.Net(Core)框架内置容器中。
builder.Services.ConfigureApplicationServices(builder);
var app = builder.Build();
按F5执行程序不管在 “Microsoft SQL Server”数据库软件中,还是在“MySql”数据库软件中都能自动生“ShopDemo” 数据库及其表。
对以上功能更为具体实现和注释见230122_015shopDemo(抽离特定功能(继承于“IStartup”类)实例的依赖注入)。