Esempio n. 1
0
        public override bool TryGenerate(ServiceDescriptor serviceDescriptor, CodeGenerationContext codeGenerationContext, out string[]?proxyTypeNames)
        {
            proxyTypeNames = null;
            var @interface = serviceDescriptor.ServiceType;

            if ([email protected])
            {
                return(false);
            }
            var implementationType = serviceDescriptor.ImplementationType;

            if (implementationType == null)
            {
                return(false);
            }

            Validate(implementationType);

            if ([email protected] && [email protected])
            {
                return(false);
            }

            var methods = implementationType
                          .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(it => it.IsPublic || it.IsFamily || it.IsFamilyAndAssembly)
                          .Where(it => it.DeclaringType != typeof(object))
            ;
            var interceptableMethods = methods.Where(it => _methodInvokerBuilder.CanIntercept(implementationType, it));

            if (!interceptableMethods.Any())
            {
                return(false);
            }

            foreach (var method in methods)
            {
                codeGenerationContext.References.Add(method.ReturnType.Assembly);
                foreach (var parameter in method.GetParameters())
                {
                    codeGenerationContext.References.Add(parameter.ParameterType.Assembly);
                }
            }

            MethodInfo[] interfaceMethods;
            MethodInfo[] targetMethods;
            if (@interface.IsGenericTypeDefinition && implementationType.IsGenericTypeDefinition)
            {
                GetGenericInterfaceMapping(@interface, implementationType, out interfaceMethods, out targetMethods);
            }
            else
            {
                var map = implementationType.GetInterfaceMap(@interface);
                interfaceMethods = map.InterfaceMethods;
                targetMethods    = map.TargetMethods;
            }


            var    nonInterfaceMethods    = interceptableMethods.Except(targetMethods).Where(it => it.IsVirtual);
            string?virtualMethodClassName = null;

            if (nonInterfaceMethods.Any())
            {
                virtualMethodClassName = _virtualMethodProxyGeneratorAccessor.Value.Generate(codeGenerationContext, implementationType, nonInterfaceMethods.ToArray());
            }

            if (!interceptableMethods.Intersect(targetMethods).Any())
            {
                proxyTypeNames = new string[] { virtualMethodClassName ! };
                return(true);
            }

            var interfaceProxyName = GenerateCore(codeGenerationContext, @interface, implementationType, interfaceMethods, targetMethods, virtualMethodClassName ?? implementationType.GetOutputName());

            proxyTypeNames = string.IsNullOrEmpty(virtualMethodClassName) ? new string[] { interfaceProxyName } : new string[] { interfaceProxyName, virtualMethodClassName };
            return(true);
        }