/// <summary> /// Creates an intercepted object for the specified target using the provided aspect chain. /// </summary> /// <param name="serviceType">Type of service object</param> /// <param name="target">Target object to create an intercepted object for</param> /// <param name="aspects">Aspects to be used for the service object's method calls</param> /// <returns>Intercepted service object</returns> public static object GetInterceptedObject(Type serviceType, object target, AspectChain aspects) { if (serviceType == null) { throw new ArgumentNullException("serviceType"); } // --- Check the cache InterceptedTypeDescriptor interceptor; if (!s_Interceptors.TryGetValue(serviceType, out interceptor)) { lock (s_Interceptors) { // --- Validate again to prevent a parallel type creation if (!s_Interceptors.TryGetValue(serviceType, out interceptor)) { // --- Validate input parameters if (target == null) { throw new ArgumentNullException("target"); } if (!serviceType.IsInterface || !serviceType.IsInstanceOfType(target)) { throw new InvalidOperationException("Service type must be an interface" + " type and the target object must implement that interface."); } // --- No generics is accepted if (serviceType.IsGenericType || serviceType.GetMethods().Any(met => met.IsGenericMethod) || serviceType.GetInterfaces().Any(intf => intf.IsGenericType || intf.GetMethods().Any(met => met.IsGenericMethod))) { throw new InvalidOperationException( "Service type must not have generic parameters or methods."); } // --- We do not have any wrapper types for the specified service type // --- Generate the interceptor type and save it in the cache interceptor = new InterceptedTypeDescriptor { InterceptedType = serviceType, Methods = GetInterfaceMethods(serviceType) }; GenerateWrappedType(interceptor, serviceType); s_Interceptors[serviceType] = interceptor; } } } // --- Instantiate the wrapped type var wrappedInstance = Activator.CreateInstance( interceptor.WrapperType, new[] { target, aspects }); return(wrappedInstance); }
/// <summary> /// Generates an intercepted type for the specified type /// </summary> /// <param name="descriptor">Intercepted type descriptor to generate the dynamic code into</param> /// <param name="interfaceType">Type of interface this type is generated for</param> /// <returns>Descriptor instance</returns> private static void GenerateWrappedType(InterceptedTypeDescriptor descriptor, Type interfaceType) { // --- Create the dynamic assembly and the dynamic type holding the wrapper EnsureModuleBuilder(); // --- Create the helper type for method information var methodHelperType = CreateMethodHelperType(interfaceType); var invokerHelperType = CreateInvokerHelperType(interfaceType); var wrapper = CreateWrapperType(interfaceType, methodHelperType, invokerHelperType); // --- Add a new type to the generated assembly descriptor.WrapperType = wrapper; }