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); }
public Provider(Type type, ProjectionDescriptor projectionDescriptor) { _type = type; _projectionDescriptor = projectionDescriptor; }