美文网首页ABP
ABP 源码解析 二. IOC初始化

ABP 源码解析 二. IOC初始化

作者: 诸葛_小亮 | 来源:发表于2018-08-08 22:16 被阅读18次

    介绍

    此系列文章主要是对ABP源码进行解读,初探作者在创造ABP的框架思路,和使用到的设计模式进行。
    通过解读ABP源码,可以提升ABP使用方式,可以提升编码意识,提高面向对象编程思想。

    《ABP 源码解析 一. ABP启动》中介绍了ABP是如何启动的。
    此篇文章主要解读ABP框架中IOC相关内容介绍。

    ABP中的Ioc容器依赖Castle Windsor

    ABP启动中,可以看到是如何使用IOC的,在AbpBootstrapper构造函数中,有如下代码

                // 设置Ioc管理器
                IocManager = options.IocManager;
    
    

    由此可知,ABP容器是通过options传递到启动类中的,通过阅读AbpBootstrapperOptions

            public AbpBootstrapperOptions()
            {
                IocManager = Abp.Dependency.IocManager.Instance;
                PlugInSources = new PlugInSourceList();
            }
    

    得知选项中的IocManagerAbp.Dependency.IocManager.Instance所得。
    接下来我们主要依据IocManager.Instance进行代码分析。


    类文件结构图

    IocManager IIocManager IIocRegistrar IIocResolver IConventionalRegistrationContext IConventionalDependencyRegistrar ConventionalRegistrationConfig DependencyLifeStyle

    源码解析

    主要接口

    abp和ioc有关的接口主要有三个

    • IIocRegistrar:用于注册依赖项的类的接口
    • IIocResolver:用于解析依赖的类的接口
    • IIocManager:用于注册和解析依赖项的接口
    1. IIocRegistrar

    IIocRegistrar主要提供了各种注册依赖项的方法,以及提供是否已注册的检测方法
    主要有:

    • 普通注册:AddConventionalRegistrar
    • 程序集注册:RegisterAssemblyByConvention
    • 类型注册:Register
    • 检查是否已注册:IsRegistered
    /// <summary>
        /// Define interface for classes those are used to register dependencies.
        /// 定义用于注册依赖项的类的接口
        /// </summary>
        public interface IIocRegistrar
        {
            /// <summary>
            /// Adds a dependency registrar for conventional registration.
            /// 添加依赖注册器
            /// </summary>
            /// <param name="registrar">dependency registrar</param>
            void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar);
    
            /// <summary>
            /// Registers types of given assembly by all conventional registrars. See <see cref="IocManager.AddConventionalRegistrar"/> method.
            /// 注册指定的信息集
            /// </summary>
            /// <param name="assembly">Assembly to register</param>
            void RegisterAssemblyByConvention(Assembly assembly);
    
            /// <summary>
            /// Registers types of given assembly by all conventional registrars. See <see cref="IocManager.AddConventionalRegistrar"/> method.
            /// 注册指定的信息集
            /// </summary>
            /// <param name="assembly">Assembly to register
            /// 指定的信息集
            /// </param>
            /// <param name="config">Additional configuration
            /// 配置
            /// </param>
            void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config);
    
            /// <summary>
            /// Registers a type as self registration.
            /// 注册自身类型
            /// </summary>
            /// <typeparam name="T">Type of the class
            /// 类的类型
            /// </typeparam>
            /// <param name="lifeStyle">Lifestyle of the objects of this type
            /// 注册的生命周期
            /// </param>
            void Register<T>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
                where T : class;
    
            /// <summary>
            /// Registers a type as self registration.
            /// 注册自身类型
            /// </summary>
            /// <param name="type">Type of the class
            /// 类的类型
            /// </param>
            /// <param name="lifeStyle">Lifestyle of the objects of this type
            /// 注册的生命周期
            /// </param>
            void Register(Type type, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton);
    
            /// <summary>
            /// Registers a type with it's implementation.
            /// 注册一个类型的实现
            /// </summary>
            /// <typeparam name="TType">Registering type
            /// 注册类型
            /// </typeparam>
            /// <typeparam name="TImpl">The type that implements <see cref="TType"/>
            /// 实现类型
            /// </typeparam>
            /// <param name="lifeStyle">Lifestyle of the objects of this type
            /// 注册的生命周期
            /// </param>
            void Register<TType, TImpl>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
                where TType : class
                where TImpl : class, TType;
    
            /// <summary>
            /// Registers a type with it's implementation.
            /// 注册一个类型的实现
            /// </summary>
            /// <param name="type">Type of the class
            /// 注册类型
            /// </param>
            /// <param name="impl">The type that implements
            /// 实现类型
            /// <paramref name="type"/></param>
            /// <param name="lifeStyle">Lifestyle of the objects of this type
            /// 注册的生命周期
            /// </param>
            void Register(Type type, Type impl, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton);
    
            /// <summary>
            /// Checks whether given type is registered before.
            /// 检查指定类型是否已注册
            /// </summary>
            /// <param name="type">Type to check
            /// 指定类型
            /// </param>
            bool IsRegistered(Type type);
    
            /// <summary>
            /// Checks whether given type is registered before.
            /// 检查指定类型是否已注册
            /// </summary>
            /// <typeparam name="TType">Type to check
            /// 指定类型
            /// </typeparam>
            bool IsRegistered<TType>();
        }
    
    2. IIocResolver

    IIocResolver接口主要提供了如何从ioc容器中解析组件的方法,主要有

    • 解析单个组件:Resolve
    • 解析全部组件:ResolveAll
    • 检查组件是否已注册:IsRegistered
    /// <summary>
        /// Define interface for classes those are used to resolve dependencies.
        /// 定义用于解析依赖的类的接口
        /// </summary>
        public interface IIocResolver
        {
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取一个对象
            /// </summary> 
            /// <typeparam name="T">Type of the object to get
            /// 获取类型
            /// </typeparam>
            /// <returns>The object instance
            /// 对象实例
            /// </returns>
            T Resolve<T>();
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取一个对象
            /// </summary> 
            /// <typeparam name="T">Type of the object to cast
            /// 对象转到的类型
            /// </typeparam>
            /// <param name="type">Type of the object to resolve
            /// 解析的对象类型
            /// </param>
            /// <returns>The object instance
            /// 对象实例
            /// </returns>
            T Resolve<T>(Type type);
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取一个对象
            /// </summary> 
            /// <typeparam name="T">Type of the object to get
            /// 获取的对象类型
            /// </typeparam>
            /// <param name="argumentsAsAnonymousType">Constructor arguments
            /// 构造函数参数
            /// </param>
            /// <returns>The object instance
            /// 对象实例
            /// </returns>
            T Resolve<T>(object argumentsAsAnonymousType);
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取一个对象
            /// </summary> 
            /// <param name="type">Type of the object to get
            /// 获取对象的类型
            /// </param>
            /// <returns>The object instance
            /// 对象实例
            /// </returns>
            object Resolve(Type type);
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取一个对象
            /// </summary> 
            /// <param name="type">Type of the object to get
            /// 获取对象的类型
            /// </param>
            /// <param name="argumentsAsAnonymousType">Constructor arguments
            /// 构造函数参数
            /// </param>
            /// <returns>The object instance
            /// 对象实例
            /// </returns>
            object Resolve(Type type, object argumentsAsAnonymousType);
    
            /// <summary>
            /// Gets all implementations for given type.
            /// Returning objects must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取全部对象
            /// </summary> 
            /// <typeparam name="T">Type of the objects to resolve
            /// 解析对象的类型
            /// </typeparam>
            /// <returns>Object instances
            /// 全部对象实例
            /// </returns>
            T[] ResolveAll<T>();
    
            /// <summary>
            /// Gets all implementations for given type.
            /// Returning objects must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取全部对象
            /// </summary> 
            /// <typeparam name="T">Type of the objects to resolve
            /// 解析对象的类型
            /// </typeparam>
            /// <param name="argumentsAsAnonymousType">Constructor arguments
            /// 构造函数参数
            /// </param>
            /// <returns>Object instances
            /// 全部对象实例
            /// </returns>
            T[] ResolveAll<T>(object argumentsAsAnonymousType);
    
            /// <summary>
            /// Gets all implementations for given type.
            /// Returning objects must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取指定类型的全部对象
            /// </summary> 
            /// <param name="type">Type of the objects to resolve
            /// 解析对象的类型
            /// </param>
            /// <returns>Object instances
            /// 全部对象实例
            /// </returns>
            object[] ResolveAll(Type type);
    
            /// <summary>
            /// Gets all implementations for given type.
            /// Returning objects must be Released (see <see cref="Release"/>) after usage.
            /// 从IOC容器中获取指定类型的全部对象
            /// </summary> 
            /// <param name="type">Type of the objects to resolve
            /// 解析对象的类型
            /// </param>
            /// <param name="argumentsAsAnonymousType">Constructor arguments
            /// 构造函数参数
            /// </param>
            /// <returns>Object instances
            /// 全部对象实例
            /// </returns>
            object[] ResolveAll(Type type, object argumentsAsAnonymousType);
    
            /// <summary>
            /// Releases a pre-resolved object. See Resolve methods.
            /// 释放解析对象
            /// </summary>
            /// <param name="obj">Object to be released
            /// 被释放的对象
            /// </param>
            void Release(object obj);
    
            /// <summary>
            /// Checks whether given type is registered before.
            /// 检查给定类型是否已注册
            /// </summary>
            /// <param name="type">Type to check
            /// 指定类型
            /// </param>
            bool IsRegistered(Type type);
            
            /// <summary>
            /// Checks whether given type is registered before.
            /// 检查给定类型是否已注册
            /// </summary>
            /// <typeparam name="T">Type to check
            /// 指定类型
            /// </typeparam>
            bool IsRegistered<T>();
        }
    
    3.IIocManager

    IIocManager继承自:IIocRegistrar,IIocResolver,提供Ioc容器访问属性

    /// <summary>
        /// This interface is used to directly perform dependency injection tasks.
        /// 用于注册和解析依赖项的接口
        /// </summary>
        public interface IIocManager : IIocRegistrar, IIocResolver, IDisposable
        {
            /// <summary>
            /// Reference to the Castle Windsor Container.
            /// Ioc容器
            /// </summary>
            IWindsorContainer IocContainer { get; }
    
            /// <summary>
            /// Checks whether given type is registered before.
            /// 检查指定类型是否已经注入
            /// </summary>
            /// <param name="type">Type to check
            /// 检查的类型
            /// </param>
            new bool IsRegistered(Type type);
    
            /// <summary>
            /// Checks whether given type is registered before.
            /// 检查指定类型是否已经注入
            /// </summary>
            /// <typeparam name="T">Type to check
            /// 检查的类型
            /// </typeparam>
            new bool IsRegistered<T>();
        }
    

    IocManager 实现

    IocManager是主要实现类,在此类中,初始化Windsor容器,编译能够将类型注入到ioc容器中和从ioc容器中解析组件。

    /// <summary>
        /// This class is used to directly perform dependency injection tasks.
        /// 负责依赖注入
        /// </summary>
        public class IocManager : IIocManager
        {
            /// <summary>
            /// The Singleton instance.
            /// IocManager单例
            /// </summary>
            public static IocManager Instance { get; private set; }
    
            /// <summary>
            /// Reference to the Castle Windsor Container.
            /// Castle Windsor 容器
            /// </summary>
            public IWindsorContainer IocContainer { get; private set; }
    
            /// <summary>
            /// List of all registered conventional registrars.
            /// </summary>
            private readonly List<IConventionalDependencyRegistrar> _conventionalRegistrars;
    
            static IocManager()
            {
                Instance = new IocManager();
            }
    
            /// <summary>
            /// Creates a new <see cref="IocManager"/> object.
            /// Normally, you don't directly instantiate an <see cref="IocManager"/>.
            /// This may be useful for test purposes.
            /// </summary>
            public IocManager()
            {
                IocContainer = new WindsorContainer();
                _conventionalRegistrars = new List<IConventionalDependencyRegistrar>();
    
                //Register self!
                IocContainer.Register(
                    Component.For<IocManager, IIocManager, IIocRegistrar, IIocResolver>().UsingFactoryMethod(() => this)
                    );
            }
    
            /// <summary>
            /// Adds a dependency registrar for conventional registration.
            /// </summary>
            /// <param name="registrar">dependency registrar</param>
            public void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar)
            {
                _conventionalRegistrars.Add(registrar);
            }
    
            /// <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)
                {
                    registerer.RegisterAssembly(context);
                }
    
                if (config.InstallInstallers)
                {
                    IocContainer.Install(FromAssembly.Instance(assembly));
                }
            }
    
            /// <summary>
            /// Registers a type as self registration.
            /// </summary>
            /// <typeparam name="TType">Type of the class</typeparam>
            /// <param name="lifeStyle">Lifestyle of the objects of this type</param>
            public void Register<TType>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) where TType : class
            {
                IocContainer.Register(ApplyLifestyle(Component.For<TType>(), lifeStyle));
            }
    
            /// <summary>
            /// Registers a type as self registration.
            /// </summary>
            /// <param name="type">Type of the class</param>
            /// <param name="lifeStyle">Lifestyle of the objects of this type</param>
            public void Register(Type type, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            {
                IocContainer.Register(ApplyLifestyle(Component.For(type), lifeStyle));
            }
    
            /// <summary>
            /// Registers a type with it's implementation.
            /// </summary>
            /// <typeparam name="TType">Registering type</typeparam>
            /// <typeparam name="TImpl">The type that implements <see cref="TType"/></typeparam>
            /// <param name="lifeStyle">Lifestyle of the objects of this type</param>
            public void Register<TType, TImpl>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
                where TType : class
                where TImpl : class, TType
            {
                IocContainer.Register(ApplyLifestyle(Component.For<TType, TImpl>().ImplementedBy<TImpl>(), lifeStyle));
            }
    
            /// <summary>
            /// Registers a type with it's implementation.
            /// </summary>
            /// <param name="type">Type of the class</param>
            /// <param name="impl">The type that implements <paramref name="type"/></param>
            /// <param name="lifeStyle">Lifestyle of the objects of this type</param>
            public void Register(Type type, Type impl, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            {
                IocContainer.Register(ApplyLifestyle(Component.For(type, impl).ImplementedBy(impl), lifeStyle));
            }
    
            /// <summary>
            /// Checks whether given type is registered before.
            /// </summary>
            /// <param name="type">Type to check</param>
            public bool IsRegistered(Type type)
            {
                return IocContainer.Kernel.HasComponent(type);
            }
    
            /// <summary>
            /// Checks whether given type is registered before.
            /// </summary>
            /// <typeparam name="TType">Type to check</typeparam>
            public bool IsRegistered<TType>()
            {
                return IocContainer.Kernel.HasComponent(typeof(TType));
            }
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
            /// </summary> 
            /// <typeparam name="T">Type of the object to get</typeparam>
            /// <returns>The instance object</returns>
            public T Resolve<T>()
            {
                return IocContainer.Resolve<T>();
            }
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="Release"/>) after usage.
            /// </summary> 
            /// <typeparam name="T">Type of the object to cast</typeparam>
            /// <param name="type">Type of the object to resolve</param>
            /// <returns>The object instance</returns>
            public T Resolve<T>(Type type)
            {
                return (T)IocContainer.Resolve(type);
            }
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
            /// </summary> 
            /// <typeparam name="T">Type of the object to get</typeparam>
            /// <param name="argumentsAsAnonymousType">Constructor arguments</param>
            /// <returns>The instance object</returns>
            public T Resolve<T>(object argumentsAsAnonymousType)
            {
                return IocContainer.Resolve<T>(argumentsAsAnonymousType);
            }
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
            /// </summary> 
            /// <param name="type">Type of the object to get</param>
            /// <returns>The instance object</returns>
            public object Resolve(Type type)
            {
                return IocContainer.Resolve(type);
            }
    
            /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
            /// </summary> 
            /// <param name="type">Type of the object to get</param>
            /// <param name="argumentsAsAnonymousType">Constructor arguments</param>
            /// <returns>The instance object</returns>
            public object Resolve(Type type, object argumentsAsAnonymousType)
            {
                return IocContainer.Resolve(type, argumentsAsAnonymousType);
            }
    
            ///<inheritdoc/>
            public T[] ResolveAll<T>()
            {
                return IocContainer.ResolveAll<T>();
            }
    
            ///<inheritdoc/>
            public T[] ResolveAll<T>(object argumentsAsAnonymousType)
            {
                return IocContainer.ResolveAll<T>(argumentsAsAnonymousType);
            }
    
            ///<inheritdoc/>
            public object[] ResolveAll(Type type)
            {
                return IocContainer.ResolveAll(type).Cast<object>().ToArray();
            }
    
            ///<inheritdoc/>
            public object[] ResolveAll(Type type, object argumentsAsAnonymousType)
            {
                return IocContainer.ResolveAll(type, argumentsAsAnonymousType).Cast<object>().ToArray();
            }
    
            /// <summary>
            /// Releases a pre-resolved object. See Resolve methods.
            /// </summary>
            /// <param name="obj">Object to be released</param>
            public void Release(object obj)
            {
                IocContainer.Release(obj);
            }
    
            /// <inheritdoc/>
            public void Dispose()
            {
                IocContainer.Dispose();
            }
    
            private static ComponentRegistration<T> ApplyLifestyle<T>(ComponentRegistration<T> registration, DependencyLifeStyle lifeStyle)
                where T : class
            {
                switch (lifeStyle)
                {
                    case DependencyLifeStyle.Transient:
                        return registration.LifestyleTransient();
                    case DependencyLifeStyle.Singleton:
                        return registration.LifestyleSingleton();
                    default:
                        return registration;
                }
            }
        }
    
    1. 初始化容器

    在IocManager 构造函数,初始化了 WindsorContainer容器,并且将自身实例,注入到容器中,以便能解析IocManager, IIocManager, IIocRegistrar, IIocResolver组件

    public IocManager()
            {
                IocContainer = new WindsorContainer();
                _conventionalRegistrars = new List<IConventionalDependencyRegistrar>();
    
                //Register self!
                IocContainer.Register(
                    Component.For<IocManager, IIocManager, IIocRegistrar, IIocResolver>().UsingFactoryMethod(() => this)
                    );
            }
    
    2. 注册组件

    由于已经初始化了WindsorContainer容器,abp抽象了集中常用的注册方式,直接注入到容器中

    public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config)
            {
                var context = new ConventionalRegistrationContext(assembly, this, config);
    
                foreach (var registerer in _conventionalRegistrars)
                {
                    registerer.RegisterAssembly(context);
                }
    
                if (config.InstallInstallers)
                {
                    IocContainer.Install(FromAssembly.Instance(assembly));
                }
            }
    
    public void Register<TType>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) where TType : class
            {
                IocContainer.Register(ApplyLifestyle(Component.For<TType>(), lifeStyle));
            }
    
    3. 解析组件

    抽象方法,从WindsorContainer中解析

    /// <summary>
            /// Gets an object from IOC container.
            /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
            /// </summary> 
            /// <typeparam name="T">Type of the object to get</typeparam>
            /// <returns>The instance object</returns>
            public T Resolve<T>()
            {
                return IocContainer.Resolve<T>();
            }
    
    ///<inheritdoc/>
            public T[] ResolveAll<T>()
            {
                return IocContainer.ResolveAll<T>();
            }
    
    4. 检查是否已注册

    检测组件是否已在WindsorContainer中注册

    
            /// <summary>
            /// Checks whether given type is registered before.
            /// </summary>
            /// <param name="type">Type to check</param>
            public bool IsRegistered(Type type)
            {
                return IocContainer.Kernel.HasComponent(type);
            }
    
            /// <summary>
            /// Checks whether given type is registered before.
            /// </summary>
            /// <typeparam name="TType">Type to check</typeparam>
            public bool IsRegistered<TType>()
            {
                return IocContainer.Kernel.HasComponent(typeof(TType));
            }
    

    设计模式

    1. 单例模式

    IocManager提供的单例模式,严格意义上,IocManager类还不算是单例,因为其构造方法是public,也就意味着,可以直接创建IocManager实例。

    /// <summary>
            /// The Singleton instance.
            /// IocManager单例
            /// </summary>
            public static IocManager Instance { get; private set; }
    
            static IocManager()
            {
                Instance = new IocManager();
            }
    
           public IocManager()
            {
            }
    

    2. 代理模式

    IocManager也使用到了代理模式,抽象封装自己的接口信息,代理IWindsorContainer,丰富框架内的接口。


    测试代码

    和ioc容器有关的测试,如下图


    ioc测试
    public class IocManager_LifeStyle_Tests : TestBaseWithLocalIocManager
        {
            /// <summary>
            /// 当组件释放时需要调用Dispose
            /// </summary>
            [Fact]
            public void Should_Call_Dispose_Of_Transient_Dependency_When_Object_Is_Released()
            {
                LocalIocManager.IocContainer.Register(
                    Component.For<SimpleDisposableObject>().LifestyleTransient()
                    );
    
                var obj = LocalIocManager.IocContainer.Resolve<SimpleDisposableObject>();
    
                LocalIocManager.IocContainer.Release(obj);
    
                obj.DisposeCount.ShouldBe(1);
            }
    
            /// <summary>
            /// 当iocManager 释放之后,对象也被释放
            /// </summary>
            [Fact]
            public void Should_Call_Dispose_Of_Transient_Dependency_When_IocManager_Is_Disposed()
            {
                LocalIocManager.IocContainer.Register(
                    Component.For<SimpleDisposableObject>().LifestyleTransient()
                    );
    
                var obj = LocalIocManager.IocContainer.Resolve<SimpleDisposableObject>();
    
                LocalIocManager.Dispose();
    
                obj.DisposeCount.ShouldBe(1);
            }
    
            /// <summary>
            /// 当iocManager 释放之后,单例对象也被释放
            /// </summary>
            [Fact]
            public void Should_Call_Dispose_Of_Singleton_Dependency_When_IocManager_Is_Disposed()
            {
                LocalIocManager.IocContainer.Register(
                    Component.For<SimpleDisposableObject>().LifestyleSingleton()
                    );
    
                var obj = LocalIocManager.IocContainer.Resolve<SimpleDisposableObject>();
    
                LocalIocManager.Dispose();
    
                obj.DisposeCount.ShouldBe(1);
            }
        }
    
    public class ScopedIocResolver_Tests : TestBaseWithLocalIocManager
        {
            /// <summary>
            /// scope需要正常运行
            /// </summary>
            [Fact]
            public void UsingScope_Test_ShouldWork()
            {
                LocalIocManager.Register<SimpleDisposableObject>(DependencyLifeStyle.Transient);
    
                SimpleDisposableObject simpleObj = null;
    
                LocalIocManager.UsingScope(scope => { simpleObj = scope.Resolve<SimpleDisposableObject>(); });
    
                simpleObj.DisposeCount.ShouldBe(1);
            }
    
            /// <summary>
            /// 带有构造函数的scope能够正常运行
            /// </summary>
            [Fact]
            public void UsingScope_Test_With_Constructor_ShouldWork()
            {
                LocalIocManager.Register<SimpleDisposableObject>(DependencyLifeStyle.Transient);
    
                SimpleDisposableObject simpleObj = null;
    
                LocalIocManager.UsingScope(scope => { simpleObj = scope.Resolve<SimpleDisposableObject>(new { myData = 40 }); });
    
                simpleObj.MyData.ShouldBe(40);
            }
    
            /// <summary>
            /// IIocScopedResolver接口正常
            /// </summary>
            [Fact]
            public void IIocScopedResolver_Test_ShouldWork()
            {
                LocalIocManager.Register<SimpleDisposableObject>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<SimpleDisposableObject2>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<SimpleDisposableObject3>(DependencyLifeStyle.Transient);
    
                SimpleDisposableObject simpleObj;
                SimpleDisposableObject2 simpleObj2;
                SimpleDisposableObject3 simpleObj3;
    
                using (var scope = LocalIocManager.CreateScope())
                {
                    simpleObj = scope.Resolve<SimpleDisposableObject>();
                    simpleObj2 = scope.Resolve<SimpleDisposableObject2>();
                    simpleObj3 = scope.Resolve<SimpleDisposableObject3>();
                }
    
                simpleObj.DisposeCount.ShouldBe(1);
                simpleObj2.DisposeCount.ShouldBe(1);
                simpleObj3.DisposeCount.ShouldBe(1);
            }
    
            /// <summary>
            /// IIocScopedResolver接口正常,解析组件有构造函数
            /// </summary>
            [Fact]
            public void IIocScopedResolver_Test_With_ConstructorArgs_ShouldWork()
            {
                LocalIocManager.Register<SimpleDisposableObject>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<SimpleDisposableObject2>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<SimpleDisposableObject3>(DependencyLifeStyle.Transient);
    
                SimpleDisposableObject simpleObj;
                SimpleDisposableObject2 simpleObj2;
                SimpleDisposableObject3 simpleObj3;
    
                using (var scope = LocalIocManager.CreateScope())
                {
                    simpleObj = scope.Resolve<SimpleDisposableObject>(new { myData = 40 });
                    simpleObj2 = scope.Resolve<SimpleDisposableObject2>(new { myData = 4040 });
                    simpleObj3 = scope.Resolve<SimpleDisposableObject3>(new { myData = 404040 });
                }
    
                simpleObj.MyData.ShouldBe(40);
                simpleObj2.MyData.ShouldBe(4040);
                simpleObj3.MyData.ShouldBe(404040);
            }
    
            [Fact]
            public void IIocScopedResolver_Test_ResolveAll_Should_DisposeAll_Registrants()
            {
                LocalIocManager.Register<ISimpleDependency, SimpleDependency>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<ISimpleDependency, SimpleDependency2>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<ISimpleDependency, SimpleDependency3>(DependencyLifeStyle.Transient);
    
                IEnumerable<ISimpleDependency> simpleDependendcies;
    
                using (var scope = LocalIocManager.CreateScope())
                {
                    simpleDependendcies = scope.ResolveAll<ISimpleDependency>();
                }
    
                simpleDependendcies.ShouldAllBe(d => d.DisposeCount == 1);
            }
    
            [Fact]
            public void IIocScopedResolver_Test_ResolveAll_Should_Work_WithConstructor()
            {
                LocalIocManager.Register<ISimpleDependency, SimpleDependency>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<ISimpleDependency, SimpleDependency2>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<ISimpleDependency, SimpleDependency3>(DependencyLifeStyle.Transient);
    
                IEnumerable<ISimpleDependency> simpleDependendcies;
    
                using (var scope = LocalIocManager.CreateScope())
                {
                    simpleDependendcies = scope.ResolveAll<ISimpleDependency>(new { myData = 40 });
                }
    
                simpleDependendcies.ShouldAllBe(x => x.MyData == 40);
            }
    
            [Fact]
            public void IIocScopedResolver_Test_ResolveAll_Should_Work_With_OtherResolvings()
            {
                LocalIocManager.Register<ISimpleDependency, SimpleDependency>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<ISimpleDependency, SimpleDependency2>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<ISimpleDependency, SimpleDependency3>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<SimpleDisposableObject>(DependencyLifeStyle.Transient);
    
                IEnumerable<ISimpleDependency> simpleDependendcies;
                SimpleDisposableObject simpleObject;
    
                using (var scope = LocalIocManager.CreateScope())
                {
                    simpleDependendcies = scope.ResolveAll<ISimpleDependency>();
                    simpleObject = scope.Resolve<SimpleDisposableObject>();
                }
    
                simpleDependendcies.ShouldAllBe(x => x.DisposeCount == 1);
                simpleObject.DisposeCount.ShouldBe(1);
            }
    
            [Fact]
            public void IIocScopedResolver_Test_ResolveAll_Should_Work_With_OtherResolvings_ConstructorArguments()
            {
                LocalIocManager.Register<ISimpleDependency, SimpleDependency>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<ISimpleDependency, SimpleDependency2>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<ISimpleDependency, SimpleDependency3>(DependencyLifeStyle.Transient);
                LocalIocManager.Register<SimpleDisposableObject>(DependencyLifeStyle.Transient);
    
                IEnumerable<ISimpleDependency> simpleDependendcies;
                SimpleDisposableObject simpleObject;
    
                using (var scope = LocalIocManager.CreateScope())
                {
                    simpleDependendcies = scope.ResolveAll<ISimpleDependency>(new { myData = 40 });
                    simpleObject = scope.Resolve<SimpleDisposableObject>(new { myData = 40 });
                }
    
                simpleDependendcies.ShouldAllBe(x => x.MyData == 40);
                simpleObject.MyData.ShouldBe(40);
            }
    
            [Fact]
            public void IIocScopedResolver_Test_IsRegistered_ShouldWork()
            {
                LocalIocManager.Register<ISimpleDependency, SimpleDependency>(DependencyLifeStyle.Transient);
    
                using (var scope = LocalIocManager.CreateScope())
                {
                    scope.IsRegistered<ISimpleDependency>().ShouldBe(true);
                    scope.IsRegistered(typeof(ISimpleDependency)).ShouldBe(true);
                }
            }
    
            [Fact]
            public void IIocScopedResolver_Test_Custom_Release_ShouldWork()
            {
                LocalIocManager.Register<ISimpleDependency, SimpleDependency>(DependencyLifeStyle.Transient);
    
                ISimpleDependency simpleDependency;
    
                using (var scope = LocalIocManager.CreateScope())
                {
                    simpleDependency = scope.Resolve<ISimpleDependency>();
                    scope.Release(simpleDependency);
                }
    
                simpleDependency.DisposeCount.ShouldBe(1);
            }
        }
    
        public interface ISimpleDependency : IDisposable
        {
            int MyData { get; set; }
            int DisposeCount { get; set; }
        }
    
        public class SimpleDependency : ISimpleDependency
        {
            public int MyData { get; set; }
    
            public int DisposeCount { get; set; }
    
            public void Dispose()
            {
                DisposeCount++;
            }
        }
    
        public class SimpleDependency2 : ISimpleDependency
        {
            public int DisposeCount { get; set; }
    
            public int MyData { get; set; }
    
            public void Dispose()
            {
                DisposeCount++;
            }
        }
    
        public class SimpleDependency3 : ISimpleDependency
        {
            public int MyData { get; set; }
    
            public int DisposeCount { get; set; }
    
            public void Dispose()
            {
                DisposeCount++;
            }
        }
        
    
    运行测试结果
    我的公众号

    相关文章

      网友评论

        本文标题:ABP 源码解析 二. IOC初始化

        本文链接:https://www.haomeiwen.com/subject/wkxvvftx.html