Ejemplo n.º 1
0
        private object AppendProperties(object result, BindElement bind, int depth)
        {
            //如果是单例,则不在进行各个属性的再次查找,赋值
            if (bind.Issingleton)
            {
                return(result);
            }

            //对于注册类型可用于当前对象属性装配的逻辑查找
            CreateAssigment(bind);

            if (bind.Assigment.Action != null)
            {
                //根据匹配的可装配的节点生成实例对象
                IList <object> values = new List <object>();
                foreach (var item in bind.Assigment.RegisterTypes)
                {
                    values.Add(CreateInstance(item.Name, item.BindType, depth + 1)); //注意:这里有递归的调用(为防止死循环的发生,需要对调用深度进行限制)
                }
                //对所有可装配的属性进行赋值
                bind.Assigment.Action(result, values.ToArray());
            }

            return(result);
        }
Ejemplo n.º 2
0
        public void Register(string name, Type baseType, Type implementType, bool singleton, bool instance)
        {
            if (baseType == null)
            {
                throw new ArgumentNullException("baseType");
            }

            if (implementType == null)
            {
                throw new ArgumentNullException("implementType");
            }

            //如果指定了节点的名称,则判重
            if (!string.IsNullOrEmpty(name))
            {
                name = name.Trim();
                int count = BIND_DICTIONARY.Values.Count(c => string.Equals(name, c.Name, StringComparison.OrdinalIgnoreCase));

                if (count > 0)
                {
                    throw new Exception(string.Format("名称为[{0}]的节点已存在", name));
                }
            }

            //根据指定的name和当前注册的基类型,计算缓存的key
            string key = GetCacheName(name, baseType);

            //验证注册类型是否具有继承关系
            if (baseType != implementType && !baseType.IsAssignableFrom(implementType))
            {
                throw new ArgumentOutOfRangeException(string.Format("类型[{0}]和类型[{1}]不具有继承关系", baseType.FullName, implementType.FullName));
            }

            if (BIND_DICTIONARY.ContainsKey(key))
            {
                throw new ArgumentException(string.Format("类型[{0}]已经存在名称为[{1}]的项", baseType.FullName, name));
            }

            lock (BIND_DICTIONARY)
            {
                if (BIND_DICTIONARY.ContainsKey(key))
                {
                    throw new ArgumentException(string.Format("类型[{0}]已经存在名称为[{1}]的项", baseType.FullName, name));
                }

                BindElement reg = new BindElement();
                reg.Name        = name;
                reg.BindType    = baseType;
                reg.IsInstance  = instance;
                reg.Issingleton = singleton;
                reg.ToType      = implementType;

                BIND_DICTIONARY.Add(key, reg);
            }
        }
Ejemplo n.º 3
0
        private BindElement GetBindElement(Type type, string name)
        {
            BindElement bind   = null;
            var         values = BIND_DICTIONARY.Values;

            if (string.IsNullOrEmpty(name))
            {
                //首先进行属性类型的精确匹配
                bind = values.FirstOrDefault(c => c.BindType == type && string.IsNullOrEmpty(c.Name));
                if (bind != null)
                {
                    return(bind);
                }

                //查找能够与当前属性类型匹配的其子类的信息
                foreach (var item in values)
                {
                    //TOTO:这里是否限制在未指定名称的范围内查找
                    if (string.IsNullOrEmpty(item.Name) && type.IsAssignableFrom(item.BindType))
                    {
                        return(item);
                    }
                }

                return(null);
            }

            //如果指定了名称,则判断使用该名称的注册类型是否能够生成当前的属性值
            bind = values.FirstOrDefault(c => string.Equals(name, c.Name, StringComparison.OrdinalIgnoreCase));
            if (bind == null)
            {
                throw new Exception(string.Format("未找到名称为[{0}]的注册节点", name));
            }

            if (!type.IsAssignableFrom(bind.BindType))
            {
                throw new Exception(string.Format("节点[{0}]注册的类型[{0}]和当前的属性类型[{1}]不具有继承关系", name, bind.BindType.FullName, type.FullName));
            }

            return(bind);
        }
Ejemplo n.º 4
0
        private void CreateAssigment(BindElement bind)
        {
            if (bind.Assigment != null)
            {
                return;
            }

            lock (bind)
            {
                if (bind.Assigment != null)
                {
                    return;
                }

                IList <BindElement>  list_be = new List <BindElement>();
                IList <PropertyInfo> list_pi = new List <PropertyInfo>();

                Type elType = bind.AgentType == null ? bind.ToType : bind.AgentType;
                var  pis    = elType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

                foreach (var pi in pis)
                {
                    //如果此属性不可写,则直接忽略
                    if (!pi.CanWrite)
                    {
                        continue;
                    }

                    //查找属性是否有装配标记(没有则直接忽略)
                    var atts = pi.GetCustomAttributes(typeof(AssembleAttribute), false);
                    if (atts == null || atts.Length != 1)
                    {
                        continue;
                    }

                    var assemble = atts[0] as AssembleAttribute;
                    if (assemble == null)
                    {
                        continue;
                    }

                    string name = assemble.Name;
                    if (!string.IsNullOrEmpty(name))
                    {
                        name = name.Trim();
                    }

                    //开始匹配能够适配当前属性的注册节点
                    var be = GetBindElement(pi.PropertyType, name);

                    //如果没找到匹配的注册类型,则抛出异常
                    if (be == null)
                    {
                        throw new Exception(string.Format("未能在注册类型中匹配类型[{0}]中的属性[{1}]", bind.BindType.FullName, pi.Name));
                    }

                    //记录匹配的结果
                    list_pi.Add(pi);
                    list_be.Add(be);
                }

                PropertiesAction assigment = new PropertiesAction();

                if (list_pi.Count > 0)
                {
                    //记录匹配的节点
                    assigment.RegisterTypes = list_be;

                    //利用得到匹配的属性集合,得到赋值对应属性的委托
                    assigment.Action = EmitHelper.CreatePropertiesAction(list_pi.ToArray());
                }

                bind.Assigment = assigment;
            }
        }
Ejemplo n.º 5
0
        private object CreateInstance(string name, Type type, int depth)
        {
            //验证装配深度
            if (depth > m_MaxDepth)
            {
                throw new Exception(string.Format("当前的装配深度:{0},已超过设定值:{1}", depth, m_MaxDepth));
            }

            BindElement bind = null;
            string      key  = GetCacheName(name, type);

            if (!BIND_DICTIONARY.TryGetValue(key, out bind))
            {
                //未找到注册节点的所有接口类型,抛出异常
                if (type.IsInterface)
                {
                    throw new Exception(string.Format("未找到类型[{0}]名称[{0}]的注册节点", type.FullName, name));
                }

                //未找到注册节点的非接口类型,则主动注册一个(不进行AOP规则适配,仅对可装配的属性进行匹配)
                Register(name, type, type, false, false);

                if (!BIND_DICTIONARY.TryGetValue(key, out bind))
                {
                    throw new Exception(string.Format("未找到类型[{0}]名称[{0}]的注册节点", type.FullName, name));
                }
            }

            object result    = null;
            bool   singleton = bind.Issingleton;

            //如果是单例,则首先查找单例池
            if (singleton && INSTANCE_DICTIONARY.TryGetValue(key, out result))
            {
                return(result);
            }

            result = CreateInstance(key, singleton);
            if (result != null)
            {
                return(AppendProperties(result, bind, depth));
            }

            lock (FUNC_DICTIONARY)
            {
                result = CreateInstance(key, singleton);
                if (result != null)
                {
                    return(AppendProperties(result, bind, depth));
                }

                Type agentType = null;
                //如果注册的基类是非接口类型,则不适用AOP的规则,直接使用注册的实现类型来创建代理
                if (!bind.BindType.IsInterface || (bind.BindType.IsInterface && !HasAspectAttribute(bind.ToType)))
                {
                    agentType = CreateAgentTypeByClass(bind.BindType); //创建代理类
                }
                else
                {
                    agentType = CreateAgentTypeByInterface(bind.BindType, bind.ToType); //创建代理类

                    //更新BindElement
                    lock (bind)
                        bind.AgentType = agentType;
                }

                //创建生成类实例的委托
                var func = EmitHelper.CreateFunc(agentType);

                //生成本次的新的实例
                result = func();

                //加入缓存
                FUNC_DICTIONARY.Add(key, func);

                //处理单例
                if (singleton)
                {
                    lock (INSTANCE_DICTIONARY)
                    {
                        object instance = null;
                        if (INSTANCE_DICTIONARY.TryGetValue(key, out instance))
                        {
                            return(instance);
                        }
                        else
                        {
                            INSTANCE_DICTIONARY.Add(key, result);
                        }
                    }
                }
            }

            return(AppendProperties(result, bind, depth));
        }