public override bool TryInvokeMember(InvokeMemberBinder binder, object?[]?args, out object?result) { var argumentTypes = binder.Reflect().GetPropertyValue <Type[]>("TypeArguments") !; var parameterTypes = args?.Where(a => a != null).Select(a => a !.GetType()).ToArray() ?? new Type[0]; var methods = typeof(T).GetMethods().ToList(); methods = methods.WithName(binder.Name).ToList(); methods = methods.Where(m => m.HasGenericArgumentsLengthOf(argumentTypes.Length)).ToList(); //methods = methods.WithParametersLengthOf(parameterTypes.Length).ToList(); var methodsList = methods.ToList(); var methodCount = methodsList.Count(); if (methodCount == 0) { throw new Exception($"No matching Methods with Name '{binder.Name}' found!"); } if (methodCount > 1) { throw new Exception($"Multiple matching Methods with Name '{binder.Name}' found!"); } var methodInfo = methods.First(); var methodName = $"{typeof(T).FullName}|{methodInfo.Name}"; var isVoid = methodInfo.ReturnType == typeof(void); var isTask = methodInfo.ReturnType == typeof(Task); var isTaskOfT = methodInfo.ReturnType.IsGenericTypeOf(typeof(Task <>)); var methodParameters = methodInfo.GetParameters().WithoutAttribute("FromServicesAttribute"); var cancellationToken = args?.Where(a => a is CancellationToken).Cast <CancellationToken>().FirstOrDefault() ?? default; var isStreamingMethod = IsStreamingType(methodInfo.ReturnType); var genericArguments = argumentTypes.Select(arg => arg.FullName !).ToArray(); if (isVoid) { _classCreatorHelper.Send(methodName, args !, genericArguments, cancellationToken); result = null; return(true); } else if (isTask) { result = _classCreatorHelper.SendAsync(methodName, args !, genericArguments, cancellationToken); return(true); } else if (isStreamingMethod.IsStreamingType) { var stream = _classCreatorHelper.StreamAsync <T>(methodName, args !, genericArguments, cancellationToken); switch (isStreamingMethod.StreamingType) { case StreamingType.ChannelReader: { result = _classCreatorHelper.ToChannelReader(stream, cancellationToken); return(true); } case StreamingType.AsyncEnumerable: { result = stream; return(true); } case StreamingType.Observable: { result = AsyncEnumerable.ToObservable(stream); return(true); } } } else { if (isTaskOfT) { var returnType = methodInfo.ReturnType.GetGenericArguments()[0]; var genericInvokeMethodInfo = _classCreatorHelper.GetType().GetMethod("InvokeAsync") !.MakeGenericMethod(returnType); var task = (Task)genericInvokeMethodInfo.Invoke(_classCreatorHelper, new object[] { methodName, args !, genericArguments, cancellationToken });