首页 .Net ABP 源码解析 二. IOC初始化

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
/// <summary>
    /// Define interface for >/// 定义用于注册依赖项的类的接口
    /// </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 >/// 类的类型
        /// </typeparam>
        /// <param name="lifeStyle">Life> DependencyLifeStyle.Singleton)
            where T : >;

        /// <summary>
        /// Registers a type as self registration.
        /// 注册自身类型
        /// </summary>
        /// <param name="type">Type of the >/// 类的类型
        /// </param>
        /// <param name="lifeStyle">Life> 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">Life> DependencyLifeStyle.Singleton)
            where TType : >where TImpl : >, TType;

        /// <summary>
        /// Registers a type with it's implementation.
        /// 注册一个类型的实现
        /// </summary>
        /// <param name="type">Type of the >/// 注册类型
        /// </param>
        /// <param name="impl">The type that implements
        /// 实现类型
        /// <paramref name="type"/></param>
        /// <param name="lifeStyle">Life> 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 >/// 定义用于解析依赖的类的接口
    /// </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 >/// 负责依赖注入
    /// </summary>
    public >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 >Life>{
            IocContainer.Register(ApplyLife>Type of the >Life>{
            IocContainer.Register(ApplyLife>Registering type</typeparam>
        /// <typeparam name="TImpl">The type that implements <see cref="TType"/></typeparam>
        /// <param name="lifeStyle">Life>{
            IocContainer.Register(ApplyLife>Type of the >The type that implements <paramref name="type"/></param>
        /// <param name="lifeStyle">Life>{
            IocContainer.Register(ApplyLife>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> ApplyLife >
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 : >{
            IocContainer.Register(ApplyLife >
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 >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>().Life> 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>().Life> 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>().Life> LocalIocManager.IocContainer.Resolve<SimpleDisposableObject>();

            LocalIocManager.Dispose();

            obj.DisposeCount.ShouldBe(1);
        }
    }
public >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 >SimpleDependency : ISimpleDependency
    {
        public int MyData { get; set; }

        public int DisposeCount { get; set; }

        public void Dispose()
        {
            DisposeCount++;
        }
    }

    public >SimpleDependency2 : ISimpleDependency
    {
        public int DisposeCount { get; set; }

        public int MyData { get; set; }

        public void Dispose()
        {
            DisposeCount++;
        }
    }

    public >SimpleDependency3 : ISimpleDependency
    {
        public int MyData { get; set; }

        public int DisposeCount { get; set; }

        public void Dispose()
        {
            DisposeCount++;
        }
    }
    
运行测试结果

我的公众号
特别声明:本站部分内容收集于互联网是出于更直观传递信息的目的。该内容版权归原作者所有,并不代表本站赞同其观点和对其真实性负责。如该内容涉及任何第三方合法权利,请及时与824310991@qq.com联系,我们会及时反馈并处理完毕。