• ABP之依赖注入


    写在开头

    ABP开源项目最近有点小火,还开展了线下活动。本着学习DDD的心态与学习开源代码的的好奇,我也看了一遍ABP源码,在此将自己学习ABP的一些心得记录下来。

    作为核心的IoC

    作为一种解耦的方式,一些IoC框架就成了项目了核心。比如蒋金楠的VideoMall与陈青阳的Byteart Retail项目都是使用Unity。而ABP则是使用Castle。

    Register与Resolve

    Register与Reslove是IoC基本功能,向容器中注类型对应关系再向容器按注入规则索取对象实体。ABP为Register与Resolve分别定义接口:IIocRegistrar、IocResolver,再由IIocManager继承这两个接口,所以在IIocManager中统一了Register与Resolve,其中IIocManger中定义了IWindsorContainer。再由IocManager去实现IIoCManager.这样就形成了一个完整的, Register与Resolve。类结构如下:

    其中,IoCManager当中用了单例去维持Register内容。

    生命周期

    ABP对于生命周期管理提供了两种方式。

    1. 手工注入

    系统提供了一生命周期的枚举类型:DependencyLifeStyle

        /// <summary>
        /// Lifestyles of types used in dependency injection system.
        /// </summary>
        public enum DependencyLifeStyle
        {
            /// <summary>
            /// Singleton object. Created a single object on first resolving
            /// and same instance is used for subsequent resolves.
            /// </summary>
            Singleton,
    
            /// <summary>
            /// Transient object. Created one object for every resolving.
            /// </summary>
            Transient
        }
    View Code

     

    IIoCResgister接口中重载了四个方法Register都有DependencyLifeStyle参数

    1. 系统自动识别

    系统识别的方式主要就对整个程序集进行注入,ABP提供了两个有关生命周期的接口,分别是:ISingletonDependency与ITransientDependency

    同时IIoCRegister接口中有两个RegisterAssemblyByConvention方法,

    这两个方法都用到了Assembly作为参数。

    关于这种方式的注入ABP提供了一个Assembly容器接口:IConventionalRegistrationContext与其默认实现ConventionalRegistrationContext,一个Assembly解析接口:IConventionalDependencyRegistrar及其默认实现BasicConventionalRegistrar,还有一配置ContextConventionalRegistrationConfig

    这两个接口与一个配置类共同解析程序集中可依赖注入的类型。

    其中主要解析与注入工作由IConventionalDependencyRegistrar中的RegisterAssembly方法完成,其具体实现为:

    public void RegisterAssembly(IConventionalRegistrationContext context)
            {
                //Transient
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<ITransientDependency>()
                        .WithService.Self()
                        .WithService.DefaultInterfaces()
                        .LifestyleTransient()
                    );
    
                //Singleton
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<ISingletonDependency>()
                        .WithService.Self()
                        .WithService.DefaultInterfaces()
                        .LifestyleSingleton()
                    );
    
                //Windsor Interceptors
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<IInterceptor>()
                        .WithService.Self()
                        .LifestyleTransient()
                    );
            }
    View Code

    在源代码当中我们可以看到对拦截器(IInterceptor)也有处理

    ABP默认只提供两种生命周期类型:Singleton(单例),Transient(实例)两种,对于其他的类型暂时不知道怎么处理。

    Resolve的Wrapper

    ABP为Resolve提供一个Wrapper,这个Wrapper的主要是对容器对象的Dispose管理

    在其实现DisposableDependencyObjectWrapper<T>中有体现:

        internal class DisposableDependencyObjectWrapper<T> : IDisposableDependencyObjectWrapper<T>
        {
            private readonly IIocResolver _iocResolver;
    
            public T Object { get; private set; }
    
            public DisposableDependencyObjectWrapper(IIocResolver iocResolver, T obj)
            {
                _iocResolver = iocResolver;
                Object = obj;
            }
    
            public void Dispose()
            {
                _iocResolver.Release(Object);
            }
        }
    View Code

    AbpCoreInstaller

    AbpCoreInstaller主要实现了ABP自身的注入。

  • 相关阅读:
    Django笔记
    在vue框架里添加bootstrap与axios
    Mysql8和Mysql5.7部署同一服务器
    docker迁入迁出mysql
    mysql导出csv
    Yearning启停脚本(开机自启)
    go 语言的基础知识
    阅读《深入理解Kafka核心设计与实践原理》第五章 日志存储
    阅读《深入理解Kafka核心设计与实践原理》第四章 主题与分区
    阅读《深入理解Kafka核心设计与实践原理》第三章 消费者
  • 原文地址:https://www.cnblogs.com/gangtianci/p/4684824.html
Copyright © 2020-2023  润新知