ABP 源码解析 二. IOC初始化


介绍

此系列文章主要是对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
/// 
    /// Define interface for classes those are used to register dependencies.
    /// 定义用于注册依赖项的类的接口
    /// 
    public interface IIocRegistrar
    {
        /// 
        /// Adds a dependency registrar for conventional registration.
        /// 添加依赖注册器
        /// 
        /// dependency registrar
        void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar);

        /// 
        /// Registers types of given assembly by all conventional registrars. See  method.
        /// 注册指定的信息集
        /// 
        /// Assembly to register
        void RegisterAssemblyByConvention(Assembly assembly);

        /// 
        /// Registers types of given assembly by all conventional registrars. See  method.
        /// 注册指定的信息集
        /// 
        /// Assembly to register
        /// 指定的信息集
        /// 
        /// Additional configuration
        /// 配置
        /// 
        void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config);

        /// 
        /// Registers a type as self registration.
        /// 注册自身类型
        /// 
        /// Type of the class
        /// 类的类型
        /// 
        /// Lifestyle of the objects of this type
        /// 注册的生命周期
        /// 
        void Register(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            where T : class;

        /// 
        /// Registers a type as self registration.
        /// 注册自身类型
        /// 
        /// Type of the class
        /// 类的类型
        /// 
        /// Lifestyle of the objects of this type
        /// 注册的生命周期
        /// 
        void Register(Type type, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton);

        /// 
        /// Registers a type with it's implementation.
        /// 注册一个类型的实现
        /// 
        /// Registering type
        /// 注册类型
        /// 
        /// The type that implements 
        /// 实现类型
        /// 
        /// Lifestyle of the objects of this type
        /// 注册的生命周期
        /// 
        void Register(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            where TType : class
            where TImpl : class, TType;

        /// 
        /// Registers a type with it's implementation.
        /// 注册一个类型的实现
        /// 
        /// Type of the class
        /// 注册类型
        /// 
        /// The type that implements
        /// 实现类型
        /// 
        /// Lifestyle of the objects of this type
        /// 注册的生命周期
        /// 
        void Register(Type type, Type impl, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton);

        /// 
        /// Checks whether given type is registered before.
        /// 检查指定类型是否已注册
        /// 
        /// Type to check
        /// 指定类型
        /// 
        bool IsRegistered(Type type);

        /// 
        /// Checks whether given type is registered before.
        /// 检查指定类型是否已注册
        /// 
        /// Type to check
        /// 指定类型
        /// 
        bool IsRegistered();
    }
2. IIocResolver

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

  • 解析单个组件:Resolve
  • 解析全部组件:ResolveAll
  • 检查组件是否已注册:IsRegistered
/// 
    /// Define interface for classes those are used to resolve dependencies.
    /// 定义用于解析依赖的类的接口
    /// 
    public interface IIocResolver
    {
        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        /// 从IOC容器中获取一个对象
        ///  
        /// Type of the object to get
        /// 获取类型
        /// 
        /// The object instance
        /// 对象实例
        /// 
        T Resolve();

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        /// 从IOC容器中获取一个对象
        ///  
        /// Type of the object to cast
        /// 对象转到的类型
        /// 
        /// Type of the object to resolve
        /// 解析的对象类型
        /// 
        /// The object instance
        /// 对象实例
        /// 
        T Resolve(Type type);

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        /// 从IOC容器中获取一个对象
        ///  
        /// Type of the object to get
        /// 获取的对象类型
        /// 
        /// Constructor arguments
        /// 构造函数参数
        /// 
        /// The object instance
        /// 对象实例
        /// 
        T Resolve(object argumentsAsAnonymousType);

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        /// 从IOC容器中获取一个对象
        ///  
        /// Type of the object to get
        /// 获取对象的类型
        /// 
        /// The object instance
        /// 对象实例
        /// 
        object Resolve(Type type);

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        /// 从IOC容器中获取一个对象
        ///  
        /// Type of the object to get
        /// 获取对象的类型
        /// 
        /// Constructor arguments
        /// 构造函数参数
        /// 
        /// The object instance
        /// 对象实例
        /// 
        object Resolve(Type type, object argumentsAsAnonymousType);

        /// 
        /// Gets all implementations for given type.
        /// Returning objects must be Released (see ) after usage.
        /// 从IOC容器中获取全部对象
        ///  
        /// Type of the objects to resolve
        /// 解析对象的类型
        /// 
        /// Object instances
        /// 全部对象实例
        /// 
        T[] ResolveAll();

        /// 
        /// Gets all implementations for given type.
        /// Returning objects must be Released (see ) after usage.
        /// 从IOC容器中获取全部对象
        ///  
        /// Type of the objects to resolve
        /// 解析对象的类型
        /// 
        /// Constructor arguments
        /// 构造函数参数
        /// 
        /// Object instances
        /// 全部对象实例
        /// 
        T[] ResolveAll(object argumentsAsAnonymousType);

        /// 
        /// Gets all implementations for given type.
        /// Returning objects must be Released (see ) after usage.
        /// 从IOC容器中获取指定类型的全部对象
        ///  
        /// Type of the objects to resolve
        /// 解析对象的类型
        /// 
        /// Object instances
        /// 全部对象实例
        /// 
        object[] ResolveAll(Type type);

        /// 
        /// Gets all implementations for given type.
        /// Returning objects must be Released (see ) after usage.
        /// 从IOC容器中获取指定类型的全部对象
        ///  
        /// Type of the objects to resolve
        /// 解析对象的类型
        /// 
        /// Constructor arguments
        /// 构造函数参数
        /// 
        /// Object instances
        /// 全部对象实例
        /// 
        object[] ResolveAll(Type type, object argumentsAsAnonymousType);

        /// 
        /// Releases a pre-resolved object. See Resolve methods.
        /// 释放解析对象
        /// 
        /// Object to be released
        /// 被释放的对象
        /// 
        void Release(object obj);

        /// 
        /// Checks whether given type is registered before.
        /// 检查给定类型是否已注册
        /// 
        /// Type to check
        /// 指定类型
        /// 
        bool IsRegistered(Type type);
        
        /// 
        /// Checks whether given type is registered before.
        /// 检查给定类型是否已注册
        /// 
        /// Type to check
        /// 指定类型
        /// 
        bool IsRegistered();
    }
3.IIocManager

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

/// 
    /// This interface is used to directly perform dependency injection tasks.
    /// 用于注册和解析依赖项的接口
    /// 
    public interface IIocManager : IIocRegistrar, IIocResolver, IDisposable
    {
        /// 
        /// Reference to the Castle Windsor Container.
        /// Ioc容器
        /// 
        IWindsorContainer IocContainer { get; }

        /// 
        /// Checks whether given type is registered before.
        /// 检查指定类型是否已经注入
        /// 
        /// Type to check
        /// 检查的类型
        /// 
        new bool IsRegistered(Type type);

        /// 
        /// Checks whether given type is registered before.
        /// 检查指定类型是否已经注入
        /// 
        /// Type to check
        /// 检查的类型
        /// 
        new bool IsRegistered();
    }

IocManager 实现

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

/// 
    /// This class is used to directly perform dependency injection tasks.
    /// 负责依赖注入
    /// 
    public class IocManager : IIocManager
    {
        /// 
        /// The Singleton instance.
        /// IocManager单例
        /// 
        public static IocManager Instance { get; private set; }

        /// 
        /// Reference to the Castle Windsor Container.
        /// Castle Windsor 容器
        /// 
        public IWindsorContainer IocContainer { get; private set; }

        /// 
        /// List of all registered conventional registrars.
        /// 
        private readonly List _conventionalRegistrars;

        static IocManager()
        {
            Instance = new IocManager();
        }

        /// 
        /// Creates a new  object.
        /// Normally, you don't directly instantiate an .
        /// This may be useful for test purposes.
        /// 
        public IocManager()
        {
            IocContainer = new WindsorContainer();
            _conventionalRegistrars = new List();

            //Register self!
            IocContainer.Register(
                Component.For().UsingFactoryMethod(() => this)
                );
        }

        /// 
        /// Adds a dependency registrar for conventional registration.
        /// 
        /// dependency registrar
        public void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar)
        {
            _conventionalRegistrars.Add(registrar);
        }

        /// 
        /// Registers types of given assembly by all conventional registrars. See  method.
        /// 
        /// Assembly to register
        public void RegisterAssemblyByConvention(Assembly assembly)
        {
            RegisterAssemblyByConvention(assembly, new ConventionalRegistrationConfig());
        }

        /// 
        /// Registers types of given assembly by all conventional registrars. See  method.
        /// 
        /// Assembly to register
        /// Additional configuration
        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));
            }
        }

        /// 
        /// Registers a type as self registration.
        /// 
        /// Type of the class
        /// Lifestyle of the objects of this type
        public void Register(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) where TType : class
        {
            IocContainer.Register(ApplyLifestyle(Component.For(), lifeStyle));
        }

        /// 
        /// Registers a type as self registration.
        /// 
        /// Type of the class
        /// Lifestyle of the objects of this type
        public void Register(Type type, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
        {
            IocContainer.Register(ApplyLifestyle(Component.For(type), lifeStyle));
        }

        /// 
        /// Registers a type with it's implementation.
        /// 
        /// Registering type
        /// The type that implements 
        /// Lifestyle of the objects of this type
        public void Register(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            where TType : class
            where TImpl : class, TType
        {
            IocContainer.Register(ApplyLifestyle(Component.For().ImplementedBy(), lifeStyle));
        }

        /// 
        /// Registers a type with it's implementation.
        /// 
        /// Type of the class
        /// The type that implements 
        /// Lifestyle of the objects of this type
        public void Register(Type type, Type impl, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
        {
            IocContainer.Register(ApplyLifestyle(Component.For(type, impl).ImplementedBy(impl), lifeStyle));
        }

        /// 
        /// Checks whether given type is registered before.
        /// 
        /// Type to check
        public bool IsRegistered(Type type)
        {
            return IocContainer.Kernel.HasComponent(type);
        }

        /// 
        /// Checks whether given type is registered before.
        /// 
        /// Type to check
        public bool IsRegistered()
        {
            return IocContainer.Kernel.HasComponent(typeof(TType));
        }

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        ///  
        /// Type of the object to get
        /// The instance object
        public T Resolve()
        {
            return IocContainer.Resolve();
        }

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        ///  
        /// Type of the object to cast
        /// Type of the object to resolve
        /// The object instance
        public T Resolve(Type type)
        {
            return (T)IocContainer.Resolve(type);
        }

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        ///  
        /// Type of the object to get
        /// Constructor arguments
        /// The instance object
        public T Resolve(object argumentsAsAnonymousType)
        {
            return IocContainer.Resolve(argumentsAsAnonymousType);
        }

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        ///  
        /// Type of the object to get
        /// The instance object
        public object Resolve(Type type)
        {
            return IocContainer.Resolve(type);
        }

        /// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        ///  
        /// Type of the object to get
        /// Constructor arguments
        /// The instance object
        public object Resolve(Type type, object argumentsAsAnonymousType)
        {
            return IocContainer.Resolve(type, argumentsAsAnonymousType);
        }

        ///
        public T[] ResolveAll()
        {
            return IocContainer.ResolveAll();
        }

        ///
        public T[] ResolveAll(object argumentsAsAnonymousType)
        {
            return IocContainer.ResolveAll(argumentsAsAnonymousType);
        }

        ///
        public object[] ResolveAll(Type type)
        {
            return IocContainer.ResolveAll(type).Cast().ToArray();
        }

        ///
        public object[] ResolveAll(Type type, object argumentsAsAnonymousType)
        {
            return IocContainer.ResolveAll(type, argumentsAsAnonymousType).Cast().ToArray();
        }

        /// 
        /// Releases a pre-resolved object. See Resolve methods.
        /// 
        /// Object to be released
        public void Release(object obj)
        {
            IocContainer.Release(obj);
        }

        /// 
        public void Dispose()
        {
            IocContainer.Dispose();
        }

        private static ComponentRegistration ApplyLifestyle(ComponentRegistration 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();

            //Register self!
            IocContainer.Register(
                Component.For().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(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) where TType : class
        {
            IocContainer.Register(ApplyLifestyle(Component.For(), lifeStyle));
        }
3. 解析组件

抽象方法,从WindsorContainer中解析

/// 
        /// Gets an object from IOC container.
        /// Returning object must be Released (see ) after usage.
        ///  
        /// Type of the object to get
        /// The instance object
        public T Resolve()
        {
            return IocContainer.Resolve();
        }
///
        public T[] ResolveAll()
        {
            return IocContainer.ResolveAll();
        }
4. 检查是否已注册

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


        /// 
        /// Checks whether given type is registered before.
        /// 
        /// Type to check
        public bool IsRegistered(Type type)
        {
            return IocContainer.Kernel.HasComponent(type);
        }

        /// 
        /// Checks whether given type is registered before.
        /// 
        /// Type to check
        public bool IsRegistered()
        {
            return IocContainer.Kernel.HasComponent(typeof(TType));
        }

设计模式

1. 单例模式

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

/// 
        /// The Singleton instance.
        /// IocManager单例
        /// 
        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
    {
        /// 
        /// 当组件释放时需要调用Dispose
        /// 
        [Fact]
        public void Should_Call_Dispose_Of_Transient_Dependency_When_Object_Is_Released()
        {
            LocalIocManager.IocContainer.Register(
                Component.For().LifestyleTransient()
                );

            var obj = LocalIocManager.IocContainer.Resolve();

            LocalIocManager.IocContainer.Release(obj);

            obj.DisposeCount.ShouldBe(1);
        }

        /// 
        /// 当iocManager 释放之后,对象也被释放
        /// 
        [Fact]
        public void Should_Call_Dispose_Of_Transient_Dependency_When_IocManager_Is_Disposed()
        {
            LocalIocManager.IocContainer.Register(
                Component.For().LifestyleTransient()
                );

            var obj = LocalIocManager.IocContainer.Resolve();

            LocalIocManager.Dispose();

            obj.DisposeCount.ShouldBe(1);
        }

        /// 
        /// 当iocManager 释放之后,单例对象也被释放
        /// 
        [Fact]
        public void Should_Call_Dispose_Of_Singleton_Dependency_When_IocManager_Is_Disposed()
        {
            LocalIocManager.IocContainer.Register(
                Component.For().LifestyleSingleton()
                );

            var obj = LocalIocManager.IocContainer.Resolve();

            LocalIocManager.Dispose();

            obj.DisposeCount.ShouldBe(1);
        }
    }
public class ScopedIocResolver_Tests : TestBaseWithLocalIocManager
    {
        /// 
        /// scope需要正常运行
        /// 
        [Fact]
        public void UsingScope_Test_ShouldWork()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            SimpleDisposableObject simpleObj = null;

            LocalIocManager.UsingScope(scope => { simpleObj = scope.Resolve(); });

            simpleObj.DisposeCount.ShouldBe(1);
        }

        /// 
        /// 带有构造函数的scope能够正常运行
        /// 
        [Fact]
        public void UsingScope_Test_With_Constructor_ShouldWork()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            SimpleDisposableObject simpleObj = null;

            LocalIocManager.UsingScope(scope => { simpleObj = scope.Resolve(new { myData = 40 }); });

            simpleObj.MyData.ShouldBe(40);
        }

        /// 
        /// IIocScopedResolver接口正常
        /// 
        [Fact]
        public void IIocScopedResolver_Test_ShouldWork()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            SimpleDisposableObject simpleObj;
            SimpleDisposableObject2 simpleObj2;
            SimpleDisposableObject3 simpleObj3;

            using (var scope = LocalIocManager.CreateScope())
            {
                simpleObj = scope.Resolve();
                simpleObj2 = scope.Resolve();
                simpleObj3 = scope.Resolve();
            }

            simpleObj.DisposeCount.ShouldBe(1);
            simpleObj2.DisposeCount.ShouldBe(1);
            simpleObj3.DisposeCount.ShouldBe(1);
        }

        /// 
        /// IIocScopedResolver接口正常,解析组件有构造函数
        /// 
        [Fact]
        public void IIocScopedResolver_Test_With_ConstructorArgs_ShouldWork()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            SimpleDisposableObject simpleObj;
            SimpleDisposableObject2 simpleObj2;
            SimpleDisposableObject3 simpleObj3;

            using (var scope = LocalIocManager.CreateScope())
            {
                simpleObj = scope.Resolve(new { myData = 40 });
                simpleObj2 = scope.Resolve(new { myData = 4040 });
                simpleObj3 = scope.Resolve(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(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            IEnumerable simpleDependendcies;

            using (var scope = LocalIocManager.CreateScope())
            {
                simpleDependendcies = scope.ResolveAll();
            }

            simpleDependendcies.ShouldAllBe(d => d.DisposeCount == 1);
        }

        [Fact]
        public void IIocScopedResolver_Test_ResolveAll_Should_Work_WithConstructor()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            IEnumerable simpleDependendcies;

            using (var scope = LocalIocManager.CreateScope())
            {
                simpleDependendcies = scope.ResolveAll(new { myData = 40 });
            }

            simpleDependendcies.ShouldAllBe(x => x.MyData == 40);
        }

        [Fact]
        public void IIocScopedResolver_Test_ResolveAll_Should_Work_With_OtherResolvings()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            IEnumerable simpleDependendcies;
            SimpleDisposableObject simpleObject;

            using (var scope = LocalIocManager.CreateScope())
            {
                simpleDependendcies = scope.ResolveAll();
                simpleObject = scope.Resolve();
            }

            simpleDependendcies.ShouldAllBe(x => x.DisposeCount == 1);
            simpleObject.DisposeCount.ShouldBe(1);
        }

        [Fact]
        public void IIocScopedResolver_Test_ResolveAll_Should_Work_With_OtherResolvings_ConstructorArguments()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            IEnumerable simpleDependendcies;
            SimpleDisposableObject simpleObject;

            using (var scope = LocalIocManager.CreateScope())
            {
                simpleDependendcies = scope.ResolveAll(new { myData = 40 });
                simpleObject = scope.Resolve(new { myData = 40 });
            }

            simpleDependendcies.ShouldAllBe(x => x.MyData == 40);
            simpleObject.MyData.ShouldBe(40);
        }

        [Fact]
        public void IIocScopedResolver_Test_IsRegistered_ShouldWork()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            using (var scope = LocalIocManager.CreateScope())
            {
                scope.IsRegistered().ShouldBe(true);
                scope.IsRegistered(typeof(ISimpleDependency)).ShouldBe(true);
            }
        }

        [Fact]
        public void IIocScopedResolver_Test_Custom_Release_ShouldWork()
        {
            LocalIocManager.Register(DependencyLifeStyle.Transient);

            ISimpleDependency simpleDependency;

            using (var scope = LocalIocManager.CreateScope())
            {
                simpleDependency = scope.Resolve();
                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初始化)