zoukankan      html  css  js  c++  java
  • 【原创】ABP之IConventionalDependencyRegistra接口分析

    类图:

    作用:

     abp中默认把对象的注册分为5中约定注册方式:

    1.AbpAspNetCoreConventionalRegistrar

     public class AbpAspNetCoreConventionalRegistrar : IConventionalDependencyRegistrar
        {
            public void RegisterAssembly(IConventionalRegistrationContext context)
            {
                //ViewComponents
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .BasedOn<ViewComponent>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .LifestyleTransient()
                );
    
                //PerWebRequest
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<IPerWebRequestDependency>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .WithService.Self()
                        .WithService.DefaultInterfaces()
                        .LifestyleCustom<MsScopedLifestyleManager>()
                );
            }
        }

     2、ApiControllerConventionalRegistrar 

     /// <summary>
        /// Registers all Web API Controllers derived from <see cref="ApiController"/>.
        /// </summary>
        public class ApiControllerConventionalRegistrar : IConventionalDependencyRegistrar
        {
            public void RegisterAssembly(IConventionalRegistrationContext context)
            {
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .BasedOn<ApiController>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .LifestyleTransient()
                    );
            }
        }

    3、BasicConventionalRegistrar 

     /// <summary>
        /// This class is used to register basic dependency implementations such as <see cref="ITransientDependency"/> and <see cref="ISingletonDependency"/>.
        /// </summary>
        public class BasicConventionalRegistrar : IConventionalDependencyRegistrar
        {
            public void RegisterAssembly(IConventionalRegistrationContext context)
            {
                //Transient
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<ITransientDependency>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .WithService.Self()
                        .WithService.DefaultInterfaces()
                        .LifestyleTransient()
                    );
    
                //Singleton
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<ISingletonDependency>()//如果服务继承了该接口就会自动注册为单例模式,这也就是我们使用ABP时对象自动创建神奇的地方了
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .WithService.Self()
                        .WithService.DefaultInterfaces()
                        .LifestyleSingleton()
                    );
    
                //Windsor Interceptors
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<IInterceptor>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .WithService.Self()
                        .LifestyleTransient()
                    );
            }
        }

    4、ControllerConventionalRegistrar

     /// <summary>
        /// Registers all MVC Controllers derived from <see cref="Controller"/>.
        /// </summary>
        public class ControllerConventionalRegistrar : IConventionalDependencyRegistrar
        {
            /// <inheritdoc/>
            public void RegisterAssembly(IConventionalRegistrationContext context)
            {
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .BasedOn<Controller>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .LifestyleTransient()
                    );
    
                //PerWebRequest
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<IPerWebRequestDependency>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .WithService.Self()
                        .WithService.DefaultInterfaces()
                        .LifestylePerWebRequest()
                );
            }
        }

    5、FluentValidationValidatorRegistrar 

      public class FluentValidationValidatorRegistrar : IConventionalDependencyRegistrar
        {
            public void RegisterAssembly(IConventionalRegistrationContext context)
            {
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .BasedOn(typeof(IValidator<>)).WithService.Base()
                        .LifestyleTransient()
                );
            }
        }

    当我们通过IocContainer调用AddConventionalRegistrar(Assembly assembly)这种方式注册时就会分别调用上面5个方法的RegisterAssembly()从assembly中查找是否有符合要求的对象,如果有就把该对象注册

    使用场景如下:

    [DependsOn(typeof(AbpWebCommonModule))]
        public class AbpAspNetCoreModule : AbpModule
        {
            public override void PreInitialize()
            {
                IocManager.AddConventionalRegistrar(new AbpAspNetCoreConventionalRegistrar());//assembly调用次数由这里决定,如果5中约定注册方式都被添加了,就会查找5次,如果满足条件就注册
    
                IocManager.Register<IAbpAspNetCoreConfiguration, AbpAspNetCoreConfiguration>();
    
                Configuration.ReplaceService<IPrincipalAccessor, AspNetCorePrincipalAccessor>(DependencyLifeStyle.Transient);
                Configuration.ReplaceService<IAbpAntiForgeryManager, AbpAspNetCoreAntiForgeryManager>(DependencyLifeStyle.Transient);
                Configuration.ReplaceService<IClientInfoProvider, HttpContextClientInfoProvider>(DependencyLifeStyle.Transient);
    
                Configuration.Modules.AbpAspNetCore().FormBodyBindingIgnoredTypes.Add(typeof(IFormFile));
    
                Configuration.MultiTenancy.Resolvers.Add<DomainTenantResolveContributor>();
                Configuration.MultiTenancy.Resolvers.Add<HttpHeaderTenantResolveContributor>();
                Configuration.MultiTenancy.Resolvers.Add<HttpCookieTenantResolveContributor>();
            }
    
            public override void Initialize()
            {
                IocManager.RegisterAssemblyByConvention(typeof(AbpAspNetCoreModule).GetAssembly());//此方法调用前必须在PreInitialize()中先调用IocManager.AddConventionalRegistrar才会起作用,否则对象不会被依赖注入
     } }

     一般在模块注入时使用,相信大家经常这样用

    那么为什么会执行5次注入呢?请看下面代码:

     /// <summary>
            /// Adds a dependency registrar for conventional registration.
            /// </summary>
            /// <param name="registrar">dependency registrar</param>
            public void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar)
            {
                _conventionalRegistrars.Add(registrar);//这个变量是全局变量,用来当做缓存,如果IocManager. AddConventionalRegistrar()在模块中被调用5次约定注册方式,下面的循环就会跑5次
            }
    
            /// <summary>
            /// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method.
            /// </summary>
            /// <param name="assembly">Assembly to register</param>
            public void RegisterAssemblyByConvention(Assembly assembly)
            {
                RegisterAssemblyByConvention(assembly, new ConventionalRegistrationConfig());
            }
    
            /// <summary>
            /// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method.
            /// </summary>
            /// <param name="assembly">Assembly to register</param>
            /// <param name="config">Additional configuration</param>
            public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config)
            {
                var context = new ConventionalRegistrationContext(assembly, this, config);
    
                foreach (var registerer in _conventionalRegistrars)//循环几次由_conventionalRegistrars决定
                {
                    registerer.RegisterAssembly(context);
                }
    
                if (config.InstallInstallers)
                {
                    IocContainer.Install(FromAssembly.Instance(assembly));
                }
            }

     这5中约定注册方式是ABP默认的,我们在开发中也可以根据自己的需求扩展自己需要的注入方式

    欢迎批评和提建议!

    待续.........................................

  • 相关阅读:
    机器学习技法2-Dual Support Vector Machine
    机器学习技法1-Linear Support Vector Machine
    Section 2.2
    Section 2.1 专题乱乱的
    Section 1.5 也许这才是暴力搜索
    usaco生成器
    Section 1.4 搜索
    Section 1.3
    Section 1.2.5 Dual Palindromes 水
    Section 1.2.4 Palindromic Squares 大水
  • 原文地址:https://www.cnblogs.com/dujq/p/10496911.html
Copyright © 2011-2022 走看看