Ejemplo n.º 1
0
 protected ServiceBinderBase TestCallback(InstanceCreatorCallback callback)
 {
     if (callback == null)
     {
         throw new ArgumentNullException(nameof(callback));
     }
     return(this);
 }
Ejemplo n.º 2
0
    /// <summary>
    /// 将指定服务添加到服务容器中。
    /// </summary>
    /// <typeparam name="TService">要添加的服务类型。</typeparam>
    /// <param name="container">服务容器。</param>
    /// <param name="callback">用于创建服务的回调对象。这允许将服务声明为可用,但将对象的创建延迟到请求该服务之后。</param>
    /// <param name="singletonMode">true,则启用单例模式;否则为 false。</param>
    /// <param name="promote">true,则将此请求提升到任何父服务容器;否则为 false。</param>
    public static void AddService <TService>(this IIocContainer container, InstanceCreatorCallback callback, bool singletonMode = false, bool promote = false)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }

        container.AddService(typeof(TService), callback, singletonMode, promote);
    }
Ejemplo n.º 3
0
    /// <summary>
    /// 将指定服务添加到服务容器中。
    /// </summary>
    /// <typeparam name="TService">要添加的服务类型。</typeparam>
    /// <param name="container">服务容器。</param>
    /// <param name="callback">用于创建服务的回调对象。这允许将服务声明为可用,但将对象的创建延迟到请求该服务之后。</param>
    /// <param name="singletonMode">true,则启用单例模式;否则为 false。</param>
    /// <param name="promote">true,则将此请求提升到任何父服务容器;否则为 false。</param>
    /// <returns>服务容器。</returns>
    public static IIocContainer Add <TService>(this IIocContainer container, InstanceCreatorCallback callback, bool singletonMode = false, bool promote = false)
    {
        if (container == null)
        {
            throw new ArgumentNullException(nameof(container));
        }

        container.Add(typeof(TService), callback, singletonMode, promote);
        return(container);
    }
Ejemplo n.º 4
0
        /// <summary>
        /// 将指定的参数名和参数值添加到服务容器中。
        /// </summary>
        /// <param name="name">参数名称。</param>
        /// <param name="callback">用于创建参数的回调对象。这允许将参数声明为可用,但将值的创建延迟到请求该参数之后。</param>
        /// <param name="singletonMode">true,则启用单例模式;否则为 false。</param>
        /// <param name="promote">true,则将此请求提升到任何父服务容器;否则为 false。</param>
        public virtual void AddValue(string name, InstanceCreatorCallback callback, bool singletonMode = false, bool promote = false)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            if (this._hasParent && promote)
            {
                this._parentLocator.AddValue(name, callback, singletonMode, promote);
            }
            this.Map(name, singletonMode ? new SingletonInstanceBox(name, callback) : new InstanceBox(name, callback));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 将指定服务添加到服务容器中。
        /// </summary>
        /// <param name="serviceType">要添加的服务类型。</param>
        /// <param name="callback">用于创建服务的回调对象。这允许将服务声明为可用,但将对象的创建延迟到请求该服务之后。</param>
        /// <param name="singletonMode">true,则启用单例模式;否则为 false。</param>
        /// <param name="promote">true,则将此请求提升到任何父服务容器;否则为 false。</param>
        public virtual void AddService(Type serviceType, InstanceCreatorCallback callback, bool singletonMode = false, bool promote = false)
        {
            if (serviceType == null)
            {
                throw new ArgumentNullException("serviceType");
            }
            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            if (this._hasParent && promote)
            {
                this._parentLocator.AddService(serviceType, callback, singletonMode, promote);
            }

            this.Map(serviceType, singletonMode
                ? new SingletonInstanceBox(serviceType.FullName, callback)
                : new InstanceBox(serviceType.FullName, callback));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 将指定的参数名和参数值添加到服务容器中,并绑定到关联的服务类型的构造函数。
        /// </summary>
        /// <param name="serviceType">关联的服务类型。</param>
        /// <param name="name">参数名称。</param>
        /// <param name="callback">用于创建参数的回调对象。这允许将参数声明为可用,但将值的创建延迟到请求该参数之后。</param>
        /// <param name="singletonMode">true,则启用单例模式;否则为 false。</param>
        /// <param name="promote">true,则将此请求提升到任何父服务容器;否则为 false。</param>
        public virtual void AddValue(Type serviceType, string name, InstanceCreatorCallback callback, bool singletonMode = false, bool promote = false)
        {
            if(serviceType == null) throw new ArgumentNullException(nameof(serviceType));
            if(string.IsNullOrWhiteSpace(name)) throw new ArgumentNullException(nameof(name));
            if(callback == null) throw new ArgumentNullException(nameof(callback));

            if(this._hasParent && promote) this._parentLocator.AddValue(serviceType, name, callback, singletonMode, promote);

            this.Map(serviceType, name, singletonMode ? new SingletonInstanceBox(name, callback) : new InstanceBox(name, callback));
        }
Ejemplo n.º 7
0
        bool InnerMapCtor(Type actualType, Type expectedType, bool singletonMode
                          , ConstructorInfo ctor, ParameterInfo[] ps
                          , out InstanceBox typeInstance
                          , out Exception exception)
        {
            bool hasExpectedType = expectedType != null;

            if (!singletonMode &&
                (actualType.IsDefined(SingletonMappingAttribute.Type, true) || (hasExpectedType && expectedType.IsDefined(SingletonMappingAttribute.Type, true))))
            {
                singletonMode = true;
            }

            InstanceCreatorCallback callback = null;

            if (ps.Length == 0)
            {
                callback = lastMappingValues => this.WrappingObject(Activator.CreateInstance(actualType, true));
            }
            else
            {
                var psValues = new InstanceBox[ps.Length];
                for (int i = 0; i < ps.Length; i++)
                {
                    var         p          = ps[i];
                    var         pType      = p.ParameterType;
                    var         pName      = p.Name;
                    InstanceBox p_instance = null;
                    if (p.IsDefined(LastMappingAttribute.Type, true) ||
                        (pType.IsDefined(LastMappingAttribute.Type, true) && !p.IsDefined(IgnoreAttribute.Type, true)))
                    {
                        p_instance = new InstanceBox(pName, null, pType);
                    }

                    #region 从当前容器获取

                    else if (this.MapContains(actualType, pName))
                    {
                        p_instance = this.FindInstanceBox(actualType, pName);
                    }
                    else if (hasExpectedType && this.MapContains(expectedType, pName))
                    {
                        p_instance = this.FindInstanceBox(expectedType, pName);
                    }

                    else if (this.MapContains(pName))
                    {
                        p_instance = this.FindInstanceBox(pName);
                    }

                    else if (this.MapContains(actualType))
                    {
                        p_instance = this.FindInstanceBox(actualType);
                    }
                    else if (hasExpectedType && this.MapContains(expectedType))
                    {
                        p_instance = this.FindInstanceBox(expectedType);
                    }

                    #endregion

                    #region 从父级容器获取

                    else if (this._hasParent && this._parentLocator.ContainsValue(actualType, pName, true))
                    {
                        p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetValue(actualType, pName));
                    }
                    else if (this._hasParent && hasExpectedType && this._parentLocator.ContainsValue(expectedType, pName, true))
                    {
                        p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetValue(expectedType, pName));
                    }

                    else if (this._hasParent && this._parentLocator.ContainsValue(pName, true))
                    {
                        p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetValue(pName));
                    }
                    else if (this._hasParent && this._parentLocator.ContainsService(actualType, true))
                    {
                        p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetService(actualType));
                    }
                    else if (this._hasParent && hasExpectedType && this._parentLocator.ContainsService(expectedType, true))
                    {
                        p_instance = new InstanceBox(pName, lmp => this._parentLocator.GetService(expectedType));
                    }

                    #endregion

                    else if (!pType.IsPrimitive && pType != Types.Decimal)
                    {
                        //- 从映射事件获取 -or- 尝试智能解析
                        p_instance = this.OnMapResolve(pType) ?? this.AutoResolveExpectType(pType);
                    }

                    if (p_instance == null)
                    {
                        exception    = new ArgumentException(actualType.FullName + ":构造函数的参数“" + pName + "”尚未配置映射!", pName);
                        typeInstance = null;
                        return(false);
                    }
                    psValues[i] = p_instance;
                }

                var cotrHandler = Aoite.Reflection.ConstructorInfoExtensions.DelegateForCreateInstance(ctor);
                callback = lastMappingValues =>
                {
                    System.Collections.IEnumerator cpe = null;
                    Func <bool> moveNextLastMap        = () =>
                    {
                        if (cpe == null)
                        {
                            if (lastMappingValues == null)
                            {
                                return(false);
                            }
                            cpe = lastMappingValues.GetEnumerator();
                        }
                        return(cpe.MoveNext());
                    };

                    object[] values = new object[psValues.Length];
                    for (int i = 0; i < psValues.Length; i++)
                    {
                        var instanceBox = psValues[i];
                        if (instanceBox.LastMappingType != null)
                        {
                            if (moveNextLastMap())
                            {
                                values[i] = cpe.Current;
                                continue;
                            }
                            var lastMappingBox = OnLastMappingResolve(instanceBox.LastMappingType);
                            if (lastMappingBox == null)
                            {
                                throw new ArgumentException(actualType.FullName + ":构造函数的参数“" + instanceBox.Name + "”指定了后期映射关系,但调用方却没有传递映射值!", instanceBox.Name);
                            }
                            instanceBox = lastMappingBox;
                        }

                        values[i] = instanceBox.GetInstance();
                    }
                    return(WrappingObject(cotrHandler(values)));
                };
            }
            typeInstance = singletonMode ? new SingletonInstanceBox(actualType.FullName, callback) : new InstanceBox(actualType.FullName, callback);
            this.Map(expectedType ?? actualType, typeInstance);
            exception = null;
            return(true);
        }
Ejemplo n.º 8
0
 public IServiceBuilder Transient(InstanceCreatorCallback callback)
     => this.TestCallback(callback).SetCallSite(new TransientCallSite(() => callback));
Ejemplo n.º 9
0
 public IIocContainer Add(Type expectType, InstanceCreatorCallback callback, bool singletonMode = false, bool promote = false)
 => this.InnerAddType(expectType, b => singletonMode ? b.Singleton(callback) : b.As(callback), promote);
Ejemplo n.º 10
0
 public IServiceBuilder As(InstanceCreatorCallback callback)
     => this.TestCallback(callback).SetCallSite(this._container.AutoResolving(this._expectType, null, () => callback));
Ejemplo n.º 11
0
 protected ServiceBinderBase TestCallback(InstanceCreatorCallback callback)
 {
     if(callback == null) throw new ArgumentNullException(nameof(callback));
     return this;
 }
Ejemplo n.º 12
0
 public IServiceBuilder Transient(InstanceCreatorCallback callback)
 => this.TestCallback(callback).SetCallSite(new TransientCallSite(() => callback));
Ejemplo n.º 13
0
 public IServiceBuilder Singleton(InstanceCreatorCallback callback)
 => this.TestCallback(callback).SetCallSite(new SingletonCallSite(() => callback));
Ejemplo n.º 14
0
 public IServiceBuilder Scoped(InstanceCreatorCallback callback)
 => this.TestCallback(callback).SetCallSite(new ScopedCallSite(() => callback));
Ejemplo n.º 15
0
 public IServiceBuilder As(InstanceCreatorCallback callback)
 => this.TestCallback(callback).SetCallSite(this._container.AutoResolving(this._expectType, null, () => callback));
Ejemplo n.º 16
0
 public InstanceBox(string name, InstanceCreatorCallback callback, Type lastMappingType = null)
 {
     this.Name            = name;
     this.Callback        = callback;
     this.LastMappingType = lastMappingType;
 }
Ejemplo n.º 17
0
 public SingletonInstanceBox(string name, InstanceCreatorCallback callback) : base(name, callback)
 {
 }
Ejemplo n.º 18
0
 public IServiceBuilder Scoped(InstanceCreatorCallback callback)
     => this.TestCallback(callback).SetCallSite(new ScopedCallSite(() => callback));
Ejemplo n.º 19
0
 public IIocContainer Add(Type expectType, string name, InstanceCreatorCallback callback, bool singletonMode = false, bool promote = false)
 => this.InnerAddValue(expectType, name, b => singletonMode ? b.Singleton(callback) : b.Transient(callback), promote);
Ejemplo n.º 20
0
 public IServiceBuilder Singleton(InstanceCreatorCallback callback)
     => this.TestCallback(callback).SetCallSite(new SingletonCallSite(() => callback));