コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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;
        }