Exemplo n.º 1
0
        private string GenerateCore(CodeGenerationContext context, Type @interface, Type implementationType, MethodInfo[] interfaceMethods, MethodInfo[] targetMethods, string targetTypeName)
        {
            var proxyClassName = GetInterceptableProxyClassName(implementationType, out var constraints);

            context.References.Add(@interface.Assembly);
            context.References.Add(implementationType.Assembly);
            var interceptableMethods = targetMethods.Where(it => _methodInvokerBuilder.CanIntercept(implementationType, it)).ToArray();

            var isDisposable         = typeof(IDisposable).IsAssignableFrom(implementationType);
            var isAsyncDisposable    = typeof(IAsyncDisposable).IsAssignableFrom(implementationType);
            var disposableInterfaces = "";

            if (isAsyncDisposable && isAsyncDisposable)
            {
                disposableInterfaces = " , IDisposable, IAsyncDisposable";
            }
            else if (isAsyncDisposable)
            {
                disposableInterfaces = " , IDisposable";
            }
            else if (isAsyncDisposable)
            {
                disposableInterfaces = " , IAsyncDisposable";
            }
            context.WriteLines($"public class {proxyClassName} : {@interface.GetOutputName()}, IInterfaceProxy {disposableInterfaces}");
            if (constraints is not null)
            {
                using (context.Indent())
                {
                    foreach (var constraint in constraints)
                    {
                        context.WriteLines(constraint);
                    }
                }
            }
            using (context.CodeBlock())
            {
                //Fields
                GenerateFields(context, implementationType, @interface, interceptableMethods, out var methodInfoAccessorFieldNames, out var invokerAccessorFieldNames, out var invokerMethodNames);

                //InvocationContextClasses.
                var invocationContextClassNames = new Dictionary <MethodInfo, string>();
                foreach (var method in interceptableMethods)
                {
                    var className = ResolveInvocationContextClassName(method);
                    invocationContextClassNames[method] = GenerateInvocationContextClass(context, className, method);
                }

                //Constructor
                var constructorName = proxyClassName;
                if (implementationType.IsGenericTypeDefinition)
                {
                    var index = constructorName.IndexOf('<');
                    constructorName = proxyClassName[..index];
Exemplo n.º 2
0
        public string Generate(CodeGenerationContext context, Type baseType, MethodInfo[] interceptableMethods)
        {
            context.References.Add(baseType.Assembly);
            var proxyClassName = GetInterceptableProxyClassName(baseType, out var constraints);

            context.WriteLines($"public sealed class {proxyClassName} : {baseType.GetOutputName()}, IVirtualMethodProxy");

            #region  Generic argument constraints.
            if (constraints is not null)
            {
                using (context.Indent())
                {
                    foreach (var constraint in constraints)
                    {
                        context.WriteLines(constraint);
                    }
                }
            }
            #endregion

            using (context.CodeBlock())
            {
                #region Fields
                GenerateFields(context, baseType, null, interceptableMethods, out var methodInfoAccessorFieldNames, out var invokerAccessorFieldNames, out var invokerMethodNames);
                context.WriteLines();
                #endregion

                #region InvocationContextClasses.
                var invocationContextClassNames = new Dictionary <MethodInfo, string>();
                foreach (var method in interceptableMethods)
                {
                    var className = ResolveInvocationContextClassName(method);
                    invocationContextClassNames[method] = GenerateInvocationContextClass(context, className, method);
                    context.WriteLines();
                }
                #endregion

                #region Properties
                var properties = baseType.GetProperties();
                if (properties.Any())
                {
                    foreach (var property in properties)
                    {
                        string?getInvocationContextClassName = null;
                        string?setInvocationContextClassName = null;
                        string?getInvokerFieldName           = null;
                        string?setInvokerFieldName           = null;
                        string?getMethodAccessor             = null;
                        string?setMethodAccessor             = null;
                        var    getMethod = property.GetMethod;
                        var    setMethod = property.SetMethod;
                        if (getMethod != null)
                        {
                            if (methodInfoAccessorFieldNames.TryGetValue(getMethod, out var accessor))
                            {
                                getMethodAccessor = $"{accessor}.Value";
                            }
                        }
                        if (setMethod != null)
                        {
                            if (methodInfoAccessorFieldNames.TryGetValue(setMethod, out var accessor))
                            {
                                setMethodAccessor = $"{accessor}.Value";
                            }
                        }
                        if (getMethod != null)
                        {
                            invocationContextClassNames.TryGetValue(getMethod, out getInvocationContextClassName);
                            invokerAccessorFieldNames?.TryGetValue(getMethod, out getInvokerFieldName);
                        }
                        if (setMethod != null)
                        {
                            invocationContextClassNames.TryGetValue(setMethod, out setInvocationContextClassName);
                            invokerAccessorFieldNames?.TryGetValue(setMethod, out setInvokerFieldName);
                        }

                        if (!string.IsNullOrWhiteSpace(getInvocationContextClassName) || !string.IsNullOrWhiteSpace(setInvocationContextClassName))
                        {
                            GenerateProperty(context, property, getInvocationContextClassName, setInvocationContextClassName, getMethodAccessor, setMethodAccessor, getInvokerFieldName, setInvokerFieldName, null);
                        }
                    }
                }
                #endregion

                #region Constructors
                var constructorName = proxyClassName;
                if (baseType.IsGenericTypeDefinition)
                {
                    var index = constructorName.IndexOf('<');
                    constructorName = proxyClassName[..index];