abp vnext 启动,加载module,依赖注入源码分析

2022/2/18 22:41:47

本文主要是介绍abp vnext 启动,加载module,依赖注入源码分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

  1. Program类 IHostBuilder UseAutofac(this IHostBuilder hostBuilder)扩展方法
    public static IHostBuilder UseAutofac(this IHostBuilder hostBuilder)
            {
                //创建一个Autofac容器,后面会通过BuildServiceProviderFromFactory方法调AbpAutofacServiceProviderFactory里的CreateBuilder方法替换IOC容器
                var containerBuilder = new ContainerBuilder();
    
                return hostBuilder.ConfigureServices((_, services) =>
                    {
                        services.AddObjectAccessor(containerBuilder);
                    })
                    .UseServiceProviderFactory(new AbpAutofacServiceProviderFactory(containerBuilder));
            }
    
  2. Startup里services.AddApplication<>();方法

里面调AbpApplicationFactory.Create<TStartupModule>(services, optionsAction);

 public static class AbpApplicationFactory
    {
        //控制台应用程序new AbpApplicationWithInternalServiceProvider:AbpApplicationBase
        //apiservice new AbpApplicationWithExternalServiceProvider:AbpApplicationBase
        public static IAbpApplicationWithInternalServiceProvider Create<TStartupModule>(
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
            where TStartupModule : IAbpModule
        {
            return Create(typeof(TStartupModule), optionsAction);
        }

        public static IAbpApplicationWithInternalServiceProvider Create(
            [NotNull] Type startupModuleType,
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
        {
            return new AbpApplicationWithInternalServiceProvider(startupModuleType, optionsAction);
        }

        public static IAbpApplicationWithExternalServiceProvider Create<TStartupModule>(
            [NotNull] IServiceCollection services,
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
            where TStartupModule : IAbpModule
        {
            return Create(typeof(TStartupModule), services, optionsAction);
        }

        public static IAbpApplicationWithExternalServiceProvider Create(
            [NotNull] Type startupModuleType,
            [NotNull] IServiceCollection services,
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
        {
            return new AbpApplicationWithExternalServiceProvider(startupModuleType, services, optionsAction);
        }
    }

  3.AbpApplicationBase里实现的内容

internal AbpApplicationBase(
            [NotNull] Type startupModuleType,
            [NotNull] IServiceCollection services,
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction)
        {
            Check.NotNull(startupModuleType, nameof(startupModuleType));
            Check.NotNull(services, nameof(services));

            StartupModuleType = startupModuleType;
            Services = services;
            //往ObjectAccessor里添加一个IServiceProvider,后面ApplicationInitializationContext.ServiceProvider拿出来用
            services.TryAddObjectAccessor<IServiceProvider>();

            //在services.AddApplication<AbpExceptionDemoModule>(option=》{});里赋值AbpApplicationCreationOptions
            var options = new AbpApplicationCreationOptions(services);
            optionsAction?.Invoke(options);

            services.AddSingleton<IAbpApplication>(this);
            services.AddSingleton<IModuleContainer>(this);

            //注入abp一些基础组件
            services.AddCoreServices();
            //注入模块相关组件
            services.AddCoreAbpServices(this, options);
            //将一些模块添加到集合,先添加[DependsOn]里的模块,再添加里赋值AbpApplicationCreationOptions.PlugInSources里的模块
            Modules = LoadModules(services, options);
            //按顺序加载Modules
            ConfigureServices();
        }

  4.ConfigureServices里实现的内容,遍历Modules执行PreConfigureServices方法,依次遍历Modules执行ConfigureServices,PostConfigureServices后清空ServiceConfigurationContext属性

  5.关于遍历Modules执行ConfigureServices

//ConfigureServices
            foreach (var module in Modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    if (!abpModule.SkipAutoServiceRegistration)
                    {
                        //在这里拉module所在程序集里的接口,类,按规则注入
                        Services.AddAssembly(module.Type.Assembly);
                    }
                }

                try
                {
                    module.Instance.ConfigureServices(context);
                }
                catch (Exception ex)
                {
                    throw new AbpInitializationException($"An error occurred during {nameof(IAbpModule.ConfigureServices)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex);
                }
            }
public abstract class ConventionalRegistrarBase : IConventionalRegistrar
    {
        public virtual void AddAssembly(IServiceCollection services, Assembly assembly)
        {
            //筛选非抽象类,泛型类,在ConventionalRegistrarList(DefaultConventionalRegistrar)里的方法依次执行AddType方法
            var types = AssemblyHelper
                .GetAllTypes(assembly)
                .Where(
                    type => type != null &&
                            type.IsClass &&
                            !type.IsAbstract &&
                            !type.IsGenericType
                ).ToArray();

            AddTypes(services, types);
        }

        public virtual void AddTypes(IServiceCollection services, params Type[] types)
        {
            foreach (var type in types)
            {
                AddType(services, type);
            }
        }

        public abstract void AddType(IServiceCollection services, Type type);

  6.看下DefaultConventionalRegistrar里的AddType方法

 

 public override void AddType(IServiceCollection services, Type type)
        {
            //判断是否有DisableConventionalRegistrationAttribu特性
            if (IsConventionalRegistrationDisabled(type))
            {
                return;
            }
            //获取DependencyAttribute特性
            var dependencyAttribute = GetDependencyAttributeOrNull(type);
            //dependencyAttribute.Lifetime有值就用dependencyAttribute的注入方式,否则就用ITransientDependency等接口
            var lifeTime = GetLifeTimeOrNull(type, dependencyAttribute);

            if (lifeTime == null)
            {
                return;
            }
            // 获得等待注册的类型定义,类型的定义优先使用 ExposeServices 特性指定的类型,如果没有则使用
            // 类型当中接口以 I 开始,后面为实现类型名称的接口。
            var exposedServiceTypes = GetExposedServiceTypes(type);

            TriggerServiceExposing(services, type, exposedServiceTypes);

            foreach (var exposedServiceType in exposedServiceTypes)
            {
                //创建一个注入描述
                var serviceDescriptor = CreateServiceDescriptor(
                    type,
                    exposedServiceType,
                    exposedServiceTypes,
                    lifeTime.Value
                );
                //判断是替换注入对象还是tryAdd,add
                if (dependencyAttribute?.ReplaceServices == true)
                {
                    services.Replace(serviceDescriptor);
                }
                else if (dependencyAttribute?.TryRegister == true)
                {
                    services.TryAdd(serviceDescriptor);
                }
                else
                {
                    services.Add(serviceDescriptor);
                }
            }
        }

  7.GetExposedServiceTypes方法获取实现类与实现类的接口,后面一起注入IServiceCollection里面

public static List<Type> GetExposedServices(Type type)
        {
            return type
                .GetCustomAttributes(true)
                .OfType<IExposedServiceTypesProvider>()//获取type中ExposedService特性里面的types
                .DefaultIfEmpty(DefaultExposeServicesAttribute)
                .SelectMany(p => p.GetExposedServiceTypes(type))//用GetExposedServiceTypes()处理types
                .Distinct()
                .ToList();
        }

  

public Type[] GetExposedServiceTypes(Type targetType)
        {
            var serviceList = ServiceTypes.ToList();

            if (IncludeDefaults)//目前属性没开放出来,默认true
            {
                foreach (var type in GetDefaultServices(targetType))//获取该接口与实现类除首字母I外是否相等,serviceList添加type
                {
                    serviceList.AddIfNotContains(type);
                }

                if (IncludeSelf)//目前属性没开放出来,默认true
                {
                    serviceList.AddIfNotContains(targetType);//添加自己
                }
            }
            else if (IncludeSelf)
            {
                serviceList.AddIfNotContains(targetType);
            }

            return serviceList.ToArray();
        }

        private static List<Type> GetDefaultServices(Type type)
        {
            var serviceTypes = new List<Type>();

            foreach (var interfaceType in type.GetTypeInfo().GetInterfaces())
            {
                var interfaceName = interfaceType.Name;

                if (interfaceName.StartsWith("I"))
                {
                    interfaceName = interfaceName.Right(interfaceName.Length - 1);
                }

                if (type.Name.EndsWith(interfaceName))
                {
                    serviceTypes.Add(interfaceType);
                }
            }

            return serviceTypes;
        }

  8.可以看到GetExposedServices()获取的是:实现类及 除首字母I外name与他相等的接口和IExposedService特性里的types

例:

        //获取到的ServiceTypes里的内容是IBTestService,ITestService,TestService
        //后面会依次注入这3个类型
        [ExposeServices(typeof(IBTestService))]
        public class TestService: ITestService:IMyTestService

  

 

 参考:https://www.cnblogs.com/zhiyong-ITNote/archive/2019/12/08/12005772.html

 

 



这篇关于abp vnext 启动,加载module,依赖注入源码分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程