예제 #1
0
		public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			if (_interceptorType == null && _interceptType == 0)
				return false;

			foreach (IAbstractTypeBuilder builder in builders)
			{
				InterceptorAspectBuilder interceptor = builder as InterceptorAspectBuilder;

				if (interceptor != null)
				{
					if (interceptor._interceptorType == null && interceptor._interceptType == 0)
						return false;

					if (builder == this)
						break;
				}
			}

			if (context.IsMethodOrProperty) switch (context.Step)
			{
				case BuildStep.Begin:   return true;
				case BuildStep.Before:  return (_interceptType & InterceptType.BeforeCall) != 0;
				case BuildStep.After:   return (_interceptType & InterceptType.AfterCall)  != 0;
				case BuildStep.Catch:   return (_interceptType & InterceptType.OnCatch)    != 0;
				case BuildStep.Finally: return (_interceptType & InterceptType.OnFinally)  != 0;
				case BuildStep.End:     return true;
			}

			return false;
		}
예제 #2
0
		public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
		{
			if (typeBuilder is PropertyChangedBuilder)
				return false;

			return base.IsCompatible(context, typeBuilder);
		}
예제 #3
0
		public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			if (context.IsBuildStep)
			{
				if (context.IsAbstractMethod)
				{
					// Give up if there is any builder that builds the method body.
					//
					if (builders.Count > 1)
						foreach (IAbstractTypeBuilder builder in builders)
							if (builder != this && builder.IsApplied(context, builders))
								return false;

					return true;
				}

				// Treat an abstract getter/setter as a regular method
				// when the property has [NoInstance] attribute 
				//
				if (context.IsAbstractGetter || context.IsAbstractSetter)
					return context.CurrentProperty.IsDefined(typeof(NoInstanceAttribute), true);
			}

			return false;
		}
예제 #4
0
		public override void Build(BuildContext context)
		{
			Context = context;

			FieldBuilder methodInfo = Context.CreatePrivateStaticField(
				"_methodInfo$ClearCacheAspect$" + ++_methodCounter, typeof(MethodInfo));

			EmitHelper emit = Context.MethodBuilder.Emitter;

			Label checkMethodInfo = emit.DefineLabel();

			emit
				.ldsfld   (methodInfo)
				.brtrue_s (checkMethodInfo)
				.ldarg_0
				.LoadType (_declaringType)
				.ldstr    (_methodName)
				;

			if (_parameterTypes == null || _parameterTypes.Length == 0)
			{
				emit.ldnull.end();
			}
			else
			{
				LocalBuilder field = emit.DeclareLocal(typeof(Type[]));

				emit
					.ldc_i4_ (_parameterTypes.Length)
					.newarr  (typeof(Type))
					.stloc   (field)
					;

				for (int i = 0; i < _parameterTypes.Length; i++)
				{
					emit
						.ldloc      (field)
						.ldc_i4     (i)
						.LoadType   (_parameterTypes[i])
						.stelem_ref
						.end()
						;
				}

				emit.ldloc(field);
			}

			emit
				.call      (typeof(ClearCacheAspect), "GetMethodInfo", typeof(object), typeof(Type), typeof(string), typeof(Type[]))
				.stsfld    (methodInfo)
				.MarkLabel (checkMethodInfo)
				.ldsfld    (methodInfo)
				.call      (typeof(CacheAspect), "ClearCache", typeof(MethodInfo))
				;
		}
예제 #5
0
		public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			if (context == null) throw new ArgumentNullException("context");

			return
				base.IsApplied(context, builders) &&
				context.CurrentProperty != null &&
				context.CurrentProperty.GetIndexParameters().Length == 0 &&
				(PropertyType == null ||
				 TypeHelper.IsSameOrParent(PropertyType, context.CurrentProperty.PropertyType));
		}
예제 #6
0
		public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			if (context == null) throw new ArgumentNullException("context");

			if (context.IsAbstractProperty && context.IsBeforeOrBuildStep)
			{
				return context.CurrentProperty.GetIndexParameters().Length <= 1;
			}

			return context.BuildElement == BuildElement.Type && context.IsAfterStep;
		}
예제 #7
0
		public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
		{
			if (context.IsBuildStep)
				return false;

			AbstractTypeBuilderList list = new AbstractTypeBuilderList(2);

			list.Add(this);
			list.Add(typeBuilder);

			BuildStep step = context.Step;

			try
			{
				context.Step = BuildStep.Build;

				return typeBuilder.IsApplied(context, list);
			}
			finally
			{
				context.Step = step;
			}
		}
예제 #8
0
		public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			if (context == null) throw new ArgumentNullException("context");

			return context.BuildElement == BuildElement.AbstractMethod;
		}
예제 #9
0
		public override int GetPriority(BuildContext context)
		{
			return TypeBuilderConsts.Priority.AsyncAspect;
		}
예제 #10
0
		private static Type EnsureDelegateType(BuildContext context, MethodInfo method)
		{
			// The delegate should be defined as inner type of context.TypeBuilder.
			// It's possible, but we can not define and use newly defined type as Emit target in its owner type.
			// To solve this problem, we should create a top level delegate and make sure its name is unique.
			//
			string delegateName = context.TypeBuilder.TypeBuilder.FullName + "$" + method.Name + "$Delegate";
			Type   delegateType = (Type) context.Items[delegateName];

			if (delegateType == null)
			{
				ParameterInfo[] pi = method.GetParameters();
				Type[]  parameters = new Type[pi.Length];

				for (int i = 0; i < pi.Length; i++)
					parameters[i] = pi[i].ParameterType;

				const MethodImplAttributes mia = MethodImplAttributes.Runtime | MethodImplAttributes.Managed;
				const MethodAttributes     ma  = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual;

				TypeBuilderHelper delegateBuilder = context.AssemblyBuilder.DefineType(delegateName,
					TypeAttributes.Class | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass,
					typeof(MulticastDelegate));

				// Create constructor
				//
				ConstructorBuilderHelper ctorBuilder = delegateBuilder.DefineConstructor(
					MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName, CallingConventions.Standard,
					typeof(object), typeof(IntPtr));
				ctorBuilder.ConstructorBuilder.SetImplementationFlags(mia);

				MethodBuilderHelper methodBuilder;

				// Define the BeginInvoke method for the delegate
				//
				Type[] beginParameters = new Type[parameters.Length + 2];

				Array.Copy(parameters, 0, beginParameters, 0, parameters.Length);
				beginParameters[parameters.Length]   = typeof(AsyncCallback);
				beginParameters[parameters.Length+1] = typeof(object);

				methodBuilder = delegateBuilder.DefineMethod("BeginInvoke", ma, typeof(IAsyncResult), beginParameters);
				methodBuilder.MethodBuilder.SetImplementationFlags(mia);

				// Define the EndInvoke method for the delegate
				//
				methodBuilder = delegateBuilder.DefineMethod("EndInvoke", ma, method.ReturnType, typeof(IAsyncResult));
				methodBuilder.MethodBuilder.SetImplementationFlags(mia);

				// Define the Invoke method for the delegate
				//
				methodBuilder = delegateBuilder.DefineMethod("Invoke", ma, method.ReturnType, parameters);
				methodBuilder.MethodBuilder.SetImplementationFlags(mia);

				context.Items[delegateName] = delegateType = delegateBuilder.Create();
			}

			return delegateType;
		}
예제 #11
0
		public override int GetPriority(BuildContext context)
		{
			return TypeBuilderConsts.Priority.PropChange;
		}
예제 #12
0
		public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			return context.BuildElement == BuildElement.InterfaceMethod;
		}
		public virtual int GetPriority(BuildContext context)
		{
			return TypeBuilderConsts.Priority.Normal;
		}
예제 #14
0
		public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			if (context == null) throw new ArgumentNullException("context");

			return context.IsFinallyStep && context.IsMethodOrProperty;
		}
예제 #15
0
		public override int GetPriority(BuildContext context)
		{
			return _priority;
		}
			public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
			{
				return context.IsVirtualMethod && context.Step == BuildStep.After;
			}
		public virtual bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
		{
			return true;
		}
예제 #18
0
		public override int GetPriority(BuildContext context)
		{
			return TypeBuilderConsts.Priority.DataAccessor;
		}
		public virtual void Build(BuildContext context)
		{
			if (context == null) throw new ArgumentNullException("context");

			Context = context;

			switch (context.Step)
			{
				case BuildStep.Begin: BeginMethodBuild(); return;
				case BuildStep.End:   EndMethodBuild();   return;
			}

			switch (context.BuildElement)
			{
				case BuildElement.Type:
					switch (context.Step)
					{
						case BuildStep.Before:   BeforeBuildType(); break;
						case BuildStep.Build:          BuildType(); break;
						case BuildStep.After:     AfterBuildType(); break;
						case BuildStep.Catch:     CatchBuildType(); break;
						case BuildStep.Finally: FinallyBuildType(); break;
					}

					break;

				case BuildElement.AbstractGetter:
					switch (context.Step)
					{
						case BuildStep.Before:   BeforeBuildAbstractGetter(); break;
						case BuildStep.Build:          BuildAbstractGetter(); break;
						case BuildStep.After:     AfterBuildAbstractGetter(); break;
						case BuildStep.Catch:     CatchBuildAbstractGetter(); break;
						case BuildStep.Finally: FinallyBuildAbstractGetter(); break;
					}

					break;

				case BuildElement.AbstractSetter:
					switch (context.Step)
					{
						case BuildStep.Before:   BeforeBuildAbstractSetter(); break;
						case BuildStep.Build:          BuildAbstractSetter(); break;
						case BuildStep.After:     AfterBuildAbstractSetter(); break;
						case BuildStep.Catch:     CatchBuildAbstractSetter(); break;
						case BuildStep.Finally: FinallyBuildAbstractSetter(); break;
					}

					break;

				case BuildElement.AbstractMethod:
					switch (context.Step)
					{
						case BuildStep.Before:   BeforeBuildAbstractMethod(); break;
						case BuildStep.Build:          BuildAbstractMethod(); break;
						case BuildStep.After:     AfterBuildAbstractMethod(); break;
						case BuildStep.Catch:     CatchBuildAbstractMethod(); break;
						case BuildStep.Finally: FinallyBuildAbstractMethod(); break;
					}

					break;

				case BuildElement.VirtualGetter:
					switch (context.Step)
					{
						case BuildStep.Before:   BeforeBuildVirtualGetter(); break;
						case BuildStep.Build:          BuildVirtualGetter(); break;
						case BuildStep.After:     AfterBuildVirtualGetter(); break;
						case BuildStep.Catch:     CatchBuildVirtualGetter(); break;
						case BuildStep.Finally: FinallyBuildVirtualGetter(); break;
					}

					break;

				case BuildElement.VirtualSetter:
					switch (context.Step)
					{
						case BuildStep.Before:   BeforeBuildVirtualSetter(); break;
						case BuildStep.Build:          BuildVirtualSetter(); break;
						case BuildStep.After:     AfterBuildVirtualSetter(); break;
						case BuildStep.Catch:     CatchBuildVirtualSetter(); break;
						case BuildStep.Finally: FinallyBuildVirtualSetter(); break;
					}

					break;

				case BuildElement.VirtualMethod:
					switch (context.Step)
					{
						case BuildStep.Before:   BeforeBuildVirtualMethod(); break;
						case BuildStep.Build:          BuildVirtualMethod(); break;
						case BuildStep.After:     AfterBuildVirtualMethod(); break;
						case BuildStep.Catch:     CatchBuildVirtualMethod(); break;
						case BuildStep.Finally: FinallyBuildVirtualMethod(); break;
					}

					break;

				case BuildElement.InterfaceMethod:
					BuildInterfaceMethod();
					break;
			}
		}
예제 #20
0
		public override int GetPriority(BuildContext context)
		{
			return TypeBuilderConsts.Priority.ClearCacheAspect;
		}
예제 #21
0
		public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
		{
			return true;
		}
		public virtual bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			return false;
		}
예제 #23
0
		public override void Build(BuildContext context)
		{
			if (context.BuildElement == BuildElement.Type)
			{
				context.TypeBuilder.TypeBuilder.SetCustomAttribute(_attributeBuilder);
			}
			else if (TargetElement is MethodInfo)
			{
				context.MethodBuilder.MethodBuilder.SetCustomAttribute(_attributeBuilder);
			}
			else if (TargetElement is PropertyInfo && context.IsAbstractProperty)
			{
				if (_attributeBuilder != null)
				{
					FieldBuilder field = (FieldBuilder)context.Fields[TargetElement];

					field.SetCustomAttribute(_attributeBuilder);

					// Suppress multiple instances when the property has both getter and setter.
					//
					_attributeBuilder = null;
				}
			}
		}
예제 #24
0
		public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
		{
			return IsRelative(typeBuilder) == false;
		}
예제 #25
0
		public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
		{
			return context.IsAfterStep && context.BuildElement == BuildElement.Type == TargetElement is TypeHelper;
		}
예제 #26
0
		public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
		{
			InterceptorAspectBuilder builder = typeBuilder as InterceptorAspectBuilder;

			return builder == null || _interceptorType != builder._interceptorType;
		}
			public override void Build(BuildContext context)
			{
				if (context.Step == BuildStep.Begin || context.Step == BuildStep.End)
					base.Build(context);
			}
예제 #28
0
		public override void Build(BuildContext context)
		{
			if (context.Step == BuildStep.Begin || context.Step == BuildStep.End)
			{
				base.Build(context);
				return;
			}

			Context = context;

			FieldBuilder interceptor = GetInterceptorField();
			LocalBuilder info        = GetInfoField();
			EmitHelper   emit        = Context.MethodBuilder.Emitter;

			// Push ref & out parameters.
			//
			ParameterInfo[] parameters = Context.CurrentMethod.GetParameters();

			for (int i = 0; i < parameters.Length; i++)
			{
				ParameterInfo p = parameters[i];

				if (!p.ParameterType.IsByRef)
					continue;

				emit
					.ldloc      (info)
					.callvirt   (typeof(InterceptCallInfo).GetProperty("ParameterValues").GetGetMethod())
					.ldc_i4     (i)
					.ldargEx    (p, true)
					.stelem_ref
					.end()
					;
			}

			// Push return value.
			//
			if (Context.ReturnValue != null)
			{
				emit
					.ldloc          (info)
					.ldloc          (Context.ReturnValue)
					.boxIfValueType (Context.CurrentMethod.ReturnType)
					.callvirt       (typeof(InterceptCallInfo).GetProperty("ReturnValue").GetSetMethod())
					;
			}

			// Set Exception.
			//
			if (Context.Step == BuildStep.Catch)
			{
				emit
					.ldloc(info)
					.ldloc(Context.Exception)
					.callvirt(typeof(InterceptCallInfo).GetProperty("Exception").GetSetMethod())
					;
			}

			// Set config string.
			//
			emit
				.ldloc    (info)
				.ldstrEx  (_configString)
				.callvirt (typeof(InterceptCallInfo).GetProperty("ConfigString").GetSetMethod())
				;

			// Set interceptor ID.
			//
			emit
				.ldloc    (info)
				.ldc_i4   (ID)
				.callvirt (typeof(InterceptCallInfo).GetProperty("InterceptorID").GetSetMethod())
				;

			// Set intercept result.
			//
			emit
				.ldloc    (info)
				.ldc_i4   ((int)InterceptResult.Continue)
				.callvirt (typeof(InterceptCallInfo).GetProperty("InterceptResult").GetSetMethod())
				;

			// Set intercept type.
			//
			InterceptType interceptType;

			switch (Context.Step)
			{
				case BuildStep.Before:  interceptType = InterceptType.BeforeCall; break;
				case BuildStep.After:   interceptType = InterceptType.AfterCall;  break;
				case BuildStep.Catch:   interceptType = InterceptType.OnCatch;    break;
				case BuildStep.Finally: interceptType = InterceptType.OnFinally;  break;
				default:
					throw new InvalidOperationException();
			}

			emit
				.ldloc    (info)
				.ldc_i4   ((int)interceptType)
				.callvirt (typeof(InterceptCallInfo).GetProperty("InterceptType").GetSetMethod())

				// Call interceptor.
				//
				.ldsfld   (interceptor)
				.ldloc    (info)
				.callvirt (typeof(IInterceptor), "Intercept", typeof(InterceptCallInfo))
				;

			// Pop return value.
			//
			if (Context.ReturnValue != null)
			{
				emit
					.ldloc          (info)
					.callvirt       (typeof(InterceptCallInfo).GetProperty("ReturnValue").GetGetMethod())
					.CastFromObject (Context.CurrentMethod.ReturnType)
					.stloc          (Context.ReturnValue)
					;
			}

			// Pop ref & out parameters.
			//
			for (int i = 0; i < parameters.Length; i++)
			{
				ParameterInfo p = parameters[i];

				if (!p.ParameterType.IsByRef)
					continue;

				Type type = p.ParameterType.GetElementType();

				emit
					.ldarg          (p)
					.ldloc          (info)
					.callvirt       (typeof(InterceptCallInfo).GetProperty("ParameterValues").GetGetMethod())
					.ldc_i4         (i)
					.ldelem_ref
					.CastFromObject (type)
					.stind          (type)
					;
			}

			// Check InterceptResult
			emit
				.ldloc    (info)
				.callvirt (typeof(InterceptCallInfo).GetProperty("InterceptResult").GetGetMethod())
				.ldc_i4   ((int)InterceptResult.Return)
				.beq      (Context.ReturnLabel)
				;
		}
예제 #29
0
		public override void Build(BuildContext context)
		{
			Context = context;

			if (CheckOverrideAttribute())
				return;

			EmitHelper      emit   = Context.MethodBuilder.Emitter;
			MethodInfo      method = Context.MethodBuilder.OverriddenMethod;
			ParameterInfo[] ps     = method.GetParameters();

			FieldInfo field = Context.Type.GetField(_memberName);

			if (field != null)
			{
				if (field.IsPrivate)
					throw new TypeBuilderException(string.Format(
						"Field '{0}.{1}' must be protected or public.",
						Context.Type.Name, _memberName));

				emit
					.ldarg_0
					.ldfld   (field)
					;

				CheckNull(emit);

				emit
					.ldarg_0
					.ldfld   (field)
					;
			}
			else
			{
				PropertyInfo prop = Context.Type.GetProperty(_memberName);

				if (prop != null)
				{
					MethodInfo mi = prop.GetGetMethod(true);

					if (mi == null)
						throw new TypeBuilderException(string.Format(
							"Property '{0}.{1}' getter not found.",
							Context.Type.Name, _memberName));

					if (mi.IsPrivate)
						throw new TypeBuilderException(string.Format(
							"Property '{0}.{1}' getter must be protected or public.",
							Context.Type.Name, _memberName));

					emit
						.ldarg_0
						.callvirt (mi)
						;

					CheckNull(emit);

					emit
						.ldarg_0
						.callvirt (mi)
						;
				}
				else
				{
					throw new TypeBuilderException(string.Format(
						"Member '{0}.{1}' not found.",
						Context.Type.Name, _memberName));
				}
			}

			for (int i = 0; i < ps.Length; i++)
				emit.ldarg(i + 1);

			emit.callvirt(method);

			if (Context.ReturnValue != null)
				emit.stloc(Context.ReturnValue);
		}
예제 #30
0
		private MethodInfo GetTargetMethod(BuildContext context, string prefix)
		{
			string targetMethodName = _targetMethodName;

			if (targetMethodName == null)
			{
				MethodInfo mi   = context.CurrentMethod;
				string     name = mi.Name;

				if (name.StartsWith(prefix))
					targetMethodName = name.Substring(prefix.Length);
				else
					throw new TypeBuilderException(string.Format(
						"Can not figure out the target method for the method '{0}.{1}'.",
							mi.DeclaringType.FullName, mi.Name));
			}

			return _parameterTypes == null?
				context.Type.GetMethod(targetMethodName):
				context.Type.GetMethod(targetMethodName, _parameterTypes);
		}