Esempio n. 1
0
        private static Type GetInterceptableProxyType(
            ICodeGeneratorFactory codeGeneratorFactory,
            IInterceptorResolver interceptorResolver,
            Type serviceType,
            Type implementationType)
        {
            var interceptors = serviceType.IsInterface
                ? interceptorResolver.GetInterceptors(serviceType, implementationType)
                : interceptorResolver.GetInterceptors(implementationType);
            var codeGenerator = codeGeneratorFactory.Create();
            var context       = new CodeGenerationContext(serviceType, implementationType, interceptors);
            var proxyType     = codeGenerator.GenerateInterceptableProxyClass(context);

            return(proxyType);
        }
Esempio n. 2
0
        /// <summary>
        /// Generates interceptable proxy class.
        /// </summary>
        /// <param name="context">The <see cref="CodeGenerationContext"/> representing code generation based execution context.</param>
        /// <returns>The generated interceptable proxy class</returns>
        public Type GenerateInterceptableProxyClass(CodeGenerationContext context)
        {
            _interfaceOrBaseType = context.InterfaceOrBaseType;
            _targetType          = context.TargetType;
            _interceptors        = context.Interceptors;

            var assemblyName    = new AssemblyName($"AssemblyFor{_interfaceOrBaseType.Name}{GenerateSurfix()}");
            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);

            _moduleBuilder = assemblyBuilder.DefineDynamicModule($"{assemblyName}.dll");

            if (_interfaceOrBaseType.IsInterface)
            {
                _typeBuilder = _moduleBuilder.DefineType($"{_interfaceOrBaseType.Name}{GenerateSurfix()}", TypeAttributes.Public, typeof(object), new Type[] { _interfaceOrBaseType });
                _targetField = _typeBuilder.DefineField("_target", _interfaceOrBaseType, FieldAttributes.Private);
            }
            else
            {
                _typeBuilder = _moduleBuilder.DefineType($"{_interfaceOrBaseType.Name}{GenerateSurfix()}", TypeAttributes.Public, _interfaceOrBaseType);
            }

            if (_interfaceOrBaseType.IsGenericType)
            {
                var interfaceParameters = ((TypeInfo)_interfaceOrBaseType).GenericTypeParameters;
                var parameterNames      = interfaceParameters.Select(it => it.Name).ToArray();
                var proxyParameters     = _typeBuilder.DefineGenericParameters(parameterNames);
                for (int index = 0; index < interfaceParameters.Length; index++)
                {
                    var parameter = proxyParameters[index];
                    parameter.SetGenericParameterAttributes(interfaceParameters[index].GenericParameterAttributes);

                    var constraints = new List <Type>();
                    foreach (Type constraint in interfaceParameters[index].GetGenericParameterConstraints())
                    {
                        if (constraint.IsClass)
                        {
                            parameter.SetBaseTypeConstraint(constraint);
                        }
                        else
                        {
                            constraints.Add(constraint);
                        }
                    }
                    if (constraints.Count > 0)
                    {
                        parameter.SetInterfaceConstraints(constraints.ToArray());
                    }
                }
            }

            _interceptorsField = _typeBuilder.DefineField("_interceptors", typeof(IInterceptorRegistry), FieldAttributes.Private);

            if (_interfaceOrBaseType.IsInterface)
            {
                GenerateForInterface();
            }
            else
            {
                GenerateForVirtualMethods();
            }

            return(_typeBuilder.CreateTypeInfo());
        }
        public ServiceDescriptorConverter(
            ServiceDescriptor serviceDescriptor,
            IInterceptorResolver interceptorResolver,
            IInterceptableProxyFactoryCache factoryCache,
            ICodeGeneratorFactory codeGeneratorFactory)
        {
            Guard.ArgumentNotNull(serviceDescriptor, nameof(serviceDescriptor));
            Guard.ArgumentNotNull(interceptorResolver, nameof(interceptorResolver));
            Guard.ArgumentNotNull(factoryCache, nameof(factoryCache));

            if (serviceDescriptor.ImplementationInstance != null || serviceDescriptor.ImplementationFactory != null || serviceDescriptor.IsInterceptable())
            {
                _primaryDescriptor = serviceDescriptor;
                return;
            }
            var serviceType        = serviceDescriptor.ServiceType;
            var implementationType = serviceDescriptor.ImplementationType;
            var lifetime           = serviceDescriptor.Lifetime;

            if (serviceType.IsInterface)
            {
                var interceptors = interceptorResolver.GetInterceptors(serviceType, implementationType);
                if (interceptors.IsEmpty)
                {
                    _primaryDescriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
                }
                else if (serviceType.IsGenericTypeDefinition)
                {
                    _secondaryDescriptor = new ServiceDescriptor(implementationType, implementationType, lifetime);
                    var codeGenerator = codeGeneratorFactory.Create();
                    var context       = new CodeGenerationContext(serviceType, implementationType, interceptors);
                    var proxyType     = codeGenerator.GenerateInterceptableProxyClass(context);
                    _primaryDescriptor = new ServiceDescriptor(serviceType, proxyType, lifetime);
                }
                else
                {
                    _primaryDescriptor = new ServiceDescriptor(serviceType, CreateOrGet, lifetime);
                    object CreateOrGet(IServiceProvider serviceProvider)
                    {
                        var target = ActivatorUtilities.CreateInstance(serviceProvider, implementationType);

                        return(factoryCache.GetInstanceFactory(serviceType, implementationType).Invoke(target));
                    }
                }
            }
            else
            {
                var interceptors = interceptorResolver.GetInterceptors(implementationType);
                if (interceptors.IsEmpty)
                {
                    _primaryDescriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
                }
                else
                {
                    var codeGenerator = codeGeneratorFactory.Create();
                    var context       = new CodeGenerationContext(implementationType, interceptors);
                    var proxyType     = codeGenerator.GenerateInterceptableProxyClass(context);
                    _primaryDescriptor = new ServiceDescriptor(serviceType, proxyType, lifetime);
                }
            }
        }