Esempio n. 1
0
 private ProjectionInvoker(object handler,
                           ProjectionDescriptor projectionDescriptor,
                           IServiceProvider serviceProvider)
 {
     _handler = handler;
     _projectionDescriptor = projectionDescriptor;
     _serviceProvider      = serviceProvider;
 }
        private bool TryGetHandlingMember(MethodInfo member, out ProjectionDescriptor descriptor)
        {
            var parameters = member.GetParameters();

            if (parameters.Length == 0)
            {
                descriptor = default;
                return(false);
            }

            if (parameters.Any(p => p.ParameterType.IsByRef))
            {
                descriptor = default;
                return(false);
            }

            if (member.IsGenericMethod || member.IsGenericMethodDefinition)
            {
                descriptor = default;
                return(false);
            }

            if (member.IsDefined <NoProjectionMemberAttribute>())
            {
                descriptor = default;
                return(false);
            }

            var sourceType      = parameters[0].ParameterType;
            var memberAttribute = member.GetCustomAttribute <ProjectionMemberAttribute>();

            var projectionType = default(Type);

            var returnTypeDescriptor = TypeDescriptor.GetTypeDescriptor(member.ReturnType);

            if (IsSynchronousHandler(member, memberAttribute, returnTypeDescriptor) ||
                IsAsynchronousHandler(member, memberAttribute, returnTypeDescriptor))
            {
                projectionType = returnTypeDescriptor.ResultType;
            }
            else
            {
                descriptor = default;
                return(false);
            }

            var  projectNonExisting  = false;
            var  multipleResults     = false;
            Type multipleResultsType = null;

            // TODO: Do we allow types that are assignable to IEnumerable? What about IAsyncEnumerable?
            if (projectionType.IsGenericType && projectionType.GetGenericTypeDefinition() == typeof(IEnumerable <>))
            {
                multipleResultsType = projectionType;
                projectionType      = multipleResultsType.GetGenericArguments().First();
                multipleResults     = true;
            }

            if (memberAttribute != null)
            {
                if (memberAttribute.SourceType != null)
                {
                    if (!sourceType.IsAssignableFrom(memberAttribute.SourceType))
                    {
                        throw new InvalidOperationException();
                    }

                    sourceType = memberAttribute.SourceType;
                }

                if (memberAttribute.ProjectionType != null)
                {
                    if (member.ReturnType == typeof(void) || !memberAttribute.ProjectionType.IsAssignableFrom(projectionType))
                    {
                        throw new InvalidOperationException();
                    }

                    projectionType = memberAttribute.ProjectionType;
                }

                if (memberAttribute.MultipleResults != null)
                {
                    if (!multipleResults && (bool)memberAttribute.MultipleResults)
                    {
                        throw new InvalidOperationException();
                    }

                    if (multipleResults && !(bool)memberAttribute.MultipleResults)
                    {
                        projectionType  = multipleResultsType;
                        multipleResults = false;
                    }
                }

                projectNonExisting = memberAttribute.ProjectNonExisting;
            }

            descriptor = new ProjectionDescriptor(sourceType, projectionType, multipleResults, projectNonExisting, member);
            return(true);
        }
Esempio n. 3
0
 public Provider(Type type, ProjectionDescriptor projectionDescriptor)
 {
     _type = type;
     _projectionDescriptor = projectionDescriptor;
 }