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); }
/// <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); } } }