示例#1
0
        public static IDirectiveBuilder UseDirective(this IDirectiveBuilder builder, [DynamicallyAccessedMembers(DirectiveAccessibility)] Type directive, params object[] args)
        {
            var applicationServices = builder.ApplicationServices;

            return(builder.Use(next => {
                var methods = directive.GetMethods(BindingFlags.Instance | BindingFlags.Public);
                var invokeMethods = methods.Where(m =>
                                                  string.Equals(m.Name, InvokeMethodName, StringComparison.Ordinal) ||
                                                  string.Equals(m.Name, InvokeAsyncMethodName, StringComparison.Ordinal)
                                                  ).ToArray();

                if (invokeMethods.Length > 1)
                {
                    throw new InvalidOperationException($"Multiple public '{InvokeMethodName}' or '{InvokeAsyncMethodName}' methods are available.");
                }

                if (invokeMethods.Length == 0)
                {
                    throw new InvalidOperationException($"No public '{InvokeMethodName}' or '{InvokeAsyncMethodName}' method found for directive of type '{directive}'.");
                }

                var methodInfo = invokeMethods[0];
                if (!typeof(Task).IsAssignableFrom(methodInfo.ReturnType))
                {
                    throw new InvalidOperationException($"'{InvokeMethodName}' or '{InvokeAsyncMethodName}' does not return an object of type '{nameof(Task)}'.");
                }

                var parameters = methodInfo.GetParameters();
                if (parameters.Length == 0 || parameters[0].ParameterType != typeof(HtcHttpContext))
                {
                    throw new InvalidOperationException($"The '{InvokeMethodName}' or '{InvokeAsyncMethodName}' method's first argument must be of type '{nameof(HtcHttpContext)}'.");
                }

                var ctorArgs = new object[args.Length + 1];
                ctorArgs[0] = next;
                Array.Copy(args, 0, ctorArgs, 1, args.Length);
                var instance = ActivatorUtilities.CreateInstance(builder.ApplicationServices, directive, ctorArgs);
                if (parameters.Length == 1)
                {
                    return (DirectiveDelegate)methodInfo.CreateDelegate(typeof(DirectiveDelegate), instance);
                }

                var factory = Compile <object>(methodInfo, parameters);

                return context => {
                    var serviceProvider = context.RequestServices ?? applicationServices;
                    if (serviceProvider == null)
                    {
                        throw new InvalidOperationException($"'{nameof(IServiceProvider)}' is not available.");
                    }

                    return factory(instance, context, serviceProvider);
                };
            }));
        }
示例#2
0
 public static IDirectiveBuilder UseDirective <[DynamicallyAccessedMembers(DirectiveAccessibility)] TDirective>(this IDirectiveBuilder builder, params object[] args)
 {
     return(builder.UseDirective(typeof(TDirective), args));
 }