温州网站建设定制,流量比对网站,品牌网是什么网站,教育机构域名一、简要说明本篇文章主要剖析与讲解 Abp vNext 在 Web API 项目下的启动流程#xff0c;让大家了解整个 Abp vNext 框架是如何运作的。总的来说 #xff0c;Abp vNext 比起 ABP 框架更加精简。因为在 vNext 版本当中#xff0c;原来归属于 Abp 库的许多内置的基本组件 (组织… 一、简要说明本篇文章主要剖析与讲解 Abp vNext 在 Web API 项目下的启动流程让大家了解整个 Abp vNext 框架是如何运作的。总的来说 Abp vNext 比起 ABP 框架更加精简。因为在 vNext 版本当中原来归属于 Abp 库的许多内置的基本组件 (组织单元、拦截器等) 被拆分成了单独的模块这样我们来看它整个启动流程就更加地直观清晰。二、源码分析要分析其源码我这里是从他官方的 Demo 模板入手的你可以在 https://abp.io 上构建你自己的模板项目。工具上我使用的是 Jetbrains 家的 Rider配置好符号服务器(External Symbols Server)我们就能够直接调试其底层源码。(因为 Abp vNext 项目使用了 Source Link)2.1 Startup 文件的入口点这里我选择的项目是 Web API直接来到其 Startup.cs 文件我们就可以看到在 Startup 类当中的 Configure() 与 ConfigureService() 方法内部我们注入并启用了 Abp vNext 框架。public class Startup{public IServiceProvider ConfigureServices(IServiceCollection services){ services.AddApplicationDemoAppModule(options { options.UseAutofac(); });return services.BuildServiceProviderFromFactory(); }public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){ app.InitializeApplication(); }}在上面我们可以看到ABP vNext 在注入服务的时候支持传入一个 ActionAbpApplicationCreationOptions 委托。上述代码中这个委托内部使用了 UseAutoFac() 将 AutoFac 的容器注入到了 MS IoC 当中关于这块代码下文会着重讲解。2.2 Abp 服务注册在上一节看到的服务注册代码是通过扩展 IServiceCollection 接口编写的一个扩展方法实现的在方法内部是通过 AbpApplicationFactory 静态工厂来创建一个 AbpApplicationBase 实例。public static class ServiceCollectionApplicationExtensions{public static IAbpApplicationWithExternalServiceProvider AddApplicationTStartupModule( [NotNull] this IServiceCollection services, [CanBeNull] ActionAbpApplicationCreationOptions optionsAction null)where TStartupModule : IAbpModule {return AbpApplicationFactory.CreateTStartupModule(services, optionsAction); }}在这个方法当中通过名字 WithExternalServiceProvider 我们就知道这个 Applictaion 是依赖于外部的 IServiceProvider 实例。提示它继承的 AbpApplicationBase 基类还拥有另外一个实现即 AbpApplicationWithInternalServiceProvider 类型该类型一般 用于控制台程序它会在 Abp vNext 框架内自行构建一个 IServiceProvider 对象。我们回到之前的代码在这个 AbpApplicationWithExternalServiceProvider 类型内部的构造方法很简单只是通过 IServiceCollection 对象把自己注入到了服务集合当中。internal class AbpApplicationWithExternalServiceProvider : AbpApplicationBase, IAbpApplicationWithExternalServiceProvider{public AbpApplicationWithExternalServiceProvider( [NotNull] Type startupModuleType, [NotNull] IServiceCollection services, [CanBeNull] ActionAbpApplicationCreationOptions optionsAction) : base( startupModuleType, services, optionsAction){ services.AddSingletonIAbpApplicationWithExternalServiceProvider(this); }public void Initialize(IServiceProvider serviceProvider){ Check.NotNull(serviceProvider, nameof(serviceProvider)); SetServiceProvider(serviceProvider); InitializeModules(); }}重点代码在于它的基类构造函数在基类构造函数当中 Abp vNext 注入了诸多 ASP.NET Core 需要的日志服务、本地化服务等。并且它也抽象出了一个 IModuleLoader用于辅助我们加载模块。internal AbpApplicationBase( [NotNull] Type startupModuleType, [NotNull] IServiceCollection services, [CanBeNull] ActionAbpApplicationCreationOptions optionsAction){ Check.NotNull(startupModuleType, nameof(startupModuleType)); Check.NotNull(services, nameof(services)); StartupModuleType startupModuleType; Services services; services.TryAddObjectAccessorIServiceProvider();var options new AbpApplicationCreationOptions(services); optionsAction?.Invoke(options); services.AddSingletonIAbpApplication(this); services.AddSingletonIModuleContainer(this); services.AddCoreServices(); services.AddCoreAbpServices(this, options); Modules LoadModules(services, options);}提示这里的对象访问器其实就是一个占位的类型对象这样方面后面替换其具体实现。例如在上文当中的 IServiceProvider 通过 ObjectAccessorT 对象包裹起来其值是 NULL但是在后面我们可以根据自己的需要替换其具体的 Value 。2.3 替换 IoC 容器再回到之前调用 AddApplicationT() 传递的委托方法在其内部我们调用了 UseAutofac() 方法。这个方法很简单内部就只有三行代码。这三行代码主要是初始化了一个 AutoFac 的容器构建对象其次注入 IServiceProviderFactory 和 Abp 的默认实现 AbpAutofacServiceProviderFactory 。public static void UseAutofac(this AbpApplicationCreationOptions options){var builder new ContainerBuilder(); options.Services.AddObjectAccessor(builder); options.Services.AddSingleton((IServiceProviderFactoryContainerBuilder) new AbpAutofacServiceProviderFactory(builder));}这个工厂类的就是在构建 IServiceProvider 的时候使用即 BuildServiceProviderFromFactory() 方法。该方法内部逻辑很简单就是从已经注册的服务集合(IServiceCollection)当中获得之前注册的工厂类通过调用工厂类的 CreateServiceProvider()方法构建 IServiceProvider并作为返回值替换掉默认的 IoC 容器。public static IServiceProvider BuildServiceProviderFromFactory([NotNull] this IServiceCollection services){ Check.NotNull(services, nameof(services));foreach (var service in services) {var factoryInterface service.ImplementationInstance?.GetType() .GetTypeInfo() .GetInterfaces() .FirstOrDefault(i i.GetTypeInfo().IsGenericType i.GetGenericTypeDefinition() typeof(IServiceProviderFactory));if (factoryInterface null) {continue; }var containerBuilderType factoryInterface.GenericTypeArguments[0];return (IServiceProvider)typeof(ServiceCollectionCommonExtensions) .GetTypeInfo() .GetMethods() .Single(m m.Name nameof(BuildServiceProviderFromFactory) m.IsGenericMethod) .MakeGenericMethod(containerBuilderType) .Invoke(null, new object[] { services, null }); }return services.BuildServiceProvider();}public static IServiceProvider BuildServiceProviderFromFactoryTContainerBuilder([NotNull] this IServiceCollection services, ActionTContainerBuilder builderAction null){ Check.NotNull(services, nameof(services));var serviceProviderFactory services.GetSingletonInstanceOrNullIServiceProviderFactoryTContainerBuilder();if (serviceProviderFactory null) {throw new AbpException($Could not find {typeof(IServiceProviderFactoryTContainerBuilder).FullName} in {services}.); }var builder serviceProviderFactory.CreateBuilder(services); builderAction?.Invoke(builder);return serviceProviderFactory.CreateServiceProvider(builder);}2.3 初始化 Abp 框架这里针对 IApplicationBuilder 的扩展是在模块包 Volo.Abp.AspNetCore 当中的这里仅讲解 ASP.NET Core Mvc 项目是如何处理的。public static void InitializeApplication([NotNull] this IApplicationBuilder app){ Check.NotNull(app, nameof(app)); app.ApplicationServices.GetRequiredServiceObjectAccessorIApplicationBuilder().Value app; app.ApplicationServices.GetRequiredServiceIAbpApplicationWithExternalServiceProvider().Initialize(app.ApplicationServices);}这里可能会疑惑 ObjectAccessorIApplicationBuilder 是在什么时候注入的其实该类型是在 AbpAspNetCoreModule 模块注册的。public class AbpAspNetCoreModule : AbpModule{public override void ConfigureServices(ServiceConfigurationContext context){ context.Services.AddObjectAccessorIApplicationBuilder(); }}接着看初始化方法内部的操作初始化方法定义是在基类当中方法名是 InitializeModules() 在方法内部通过 IModuleManager 来执行模块的初始化方法。protected virtual void InitializeModules(){using (var scope ServiceProvider.CreateScope()) { scope.ServiceProvider .GetRequiredServiceIModuleManager() .InitializeModules(new ApplicationInitializationContext(scope.ServiceProvider)); }}除了模块的初始化模块的销毁动作 Abp vNext 好像是没有作处理你可以挂载 IApplicationLifetime.ApplicationStopping 事件来手动执行模块的销毁方法。三、总结总体来说 Abp vNext 的启动流程与之前精简了许多这是因为在新的框架当中将许多基础组件从核心层移除了用户可以自由选择自己需要加载的组件。IoC 相关的代码则是通过的 Microsoft Dependency 提供的 IServiceProvider/IServiceCollection 进行操作没有了之前的 IocManager。原文地址https://www.cnblogs.com/myzony/p/10722480.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com