Ejemplo n.º 1
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.º 2
0
        private void ImplementMethodByInterface(TypeBuilder typeBuilder, FieldBuilder agent, MethodInfo method, Type[] basicTypes, Type authType, Type exType)
        {
            var pis = method.GetParameters();

            Type[] paramTypes = pis.Select(c => c.ParameterType).ToArray();

            //识别方法上的标记(方法上的标记覆盖类上的标记)
            var atts = agent.FieldType.GetMethod(method.Name, paramTypes).GetCustomAttributes(true);

            //实现接口的方法标记
            MethodAttributes attr          = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final;
            MethodBuilder    methodBuilder = typeBuilder.DefineMethod(method.Name, attr, method.ReturnType, paramTypes);

            //构建各个参数的描述
            DefineParameters(methodBuilder, pis);

            //开始植入方法体
            ILGenerator il = methodBuilder.GetILGenerator();

            //定义返回值并初始化(如果有)
            bool         is_void = false;
            LocalBuilder result  = InitializeResult(il, method.ReturnType, ref is_void);

            FilterAspect(atts, ref basicTypes, ref authType, ref exType);

            //初始化上下文对象
            LocalBuilder context = null;
            LocalBuilder obj_arr = null;

            //如果存在AOP标记,则开始初始化上下文对象
            if (basicTypes != null || authType != null || exType != null)
            {
                context = Initialize.Context(il, paramTypes, ref obj_arr, method, agent);
            }

            //开始植入基本(执行前)的AOP代码
            var basics = Initialize.ExecutingBasics(il, basicTypes, context);

            //开始植入认证的AOP代码
            Label?lbl = null;

            Initialize.Authentication(il, authType, context, ref lbl);

            //开始植入异常(try)AOP代码
            EmitHelper.ImplantBeginException(il, exType);

            //利用成员代理和当前的调用参数,获取真正执行的函数结果
            Initialize.CallResult(il, agent, method, pis, paramTypes, result, is_void);

            //开始植入异常(catch)AOP代码
            EmitHelper.ImplantCatchException(il, exType, context);

            //如果有标签,则把标签定位到本位置(认证AOP使用)
            if (lbl.HasValue)
            {
                il.MarkLabel(lbl.Value);
            }

            //对ref参数的值进行重新赋值
            ReSetValue(il, paramTypes, obj_arr);

            //将本次执行的结果附加到当前的上下文环境中
            Initialize.AppendContextResult(il, context, result);

            //开始植入基本(执行后)的AOP代码
            Initialize.ImplantExecutedBasics(il, basics, basicTypes, context);

            //如果有返回值,则结果压栈
            if (!is_void)
            {
                il.Emit(OpCodes.Ldloc, result);
            }

            //返回结果
            il.Emit(OpCodes.Ret);
        }
Ejemplo n.º 3
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));
        }