示例#1
0
 public NetStitchMiddleware(RequestDelegate next, Assembly[] assemblies, NetStitchOption option)
 {
     server = new NetStitchServer(assemblies, option);
     if (!Servers.TryAdd(option.ServerID, server))
     {
         throw new InvalidOperationException($"Duplicate Server ID : {option.ServerID}");
     }
 }
示例#2
0
        public NetStitchServer(Assembly[] assemblies, NetStitchOption option)
        {
            this.Option = option;
            this.Option.Logger.ServerSetupStart();

            var tm = System.Diagnostics.Stopwatch.StartNew();

            var types = assemblies
                        .SelectMany(x =>
            {
                try
                {
                    return(x.GetTypes());
                }
                catch (ReflectionTypeLoadException ex)
                {
                    return(ex.Types.Where(t => t != null));
                }
            });

            var seq = types
                      .Where(x => x.GetInterfaces().Any(t => t == typeof(INetStitchContract)))
                      .Select(x =>
            {
                try
                {
                    return(new
                    {
                        interfaceType = x,
                        targetType = types.Where(t => t.GetInterfaces().Any(t2 => t2 == x)).SingleOrDefault()
                    });
                }
                catch (InvalidOperationException)
                {
                    throw;
                }
            })
                      .Where(x => x.targetType != null)
                      .Where(x => x.targetType.GetTypeInfo().IsAbstract == false)
                      .Select(x => x.targetType.GetTypeInfo().GetRuntimeInterfaceMap(x.interfaceType))
                      .SelectMany(
                x => x.TargetMethods.Zip(x.InterfaceMethods, (targetMethod, interfaceMethod) => new { targetMethod, interfaceMethod }),
                (x, methods) =>
            {
                return(new
                {
                    x.TargetType,
                    x.InterfaceType,
                    methods.targetMethod,
                    methods.interfaceMethod,
                });
            });

            foreach (var element in seq)
            {
                var op = new OperationController(element.TargetType, element.InterfaceType, element.targetMethod, element.interfaceMethod, option);
                OperationMap.Add(op.OperationID, op);
            }

            this.Option.Logger.ServerSetupCompleted(tm.Elapsed);
        }
示例#3
0
 public NetStitchMiddleware(RequestDelegate next, Type type, NetStitchOption option)
     : this(next, new[] { type.GetTypeInfo().Assembly }, option)
 {
 }
 public static IApplicationBuilder UseNetStitch(this IApplicationBuilder builder, Assembly[] assemblies, NetStitchOption option)
 {
     return builder.UseMiddleware<NetStitchMiddleware>(assemblies, option);
 }
 public static IApplicationBuilder UseNetStitch(this IApplicationBuilder builder, Type type, NetStitchOption option)
 {
     return builder.UseMiddleware<NetStitchMiddleware>(type, option);
 }
示例#6
0
        public OperationController(Type targetType, Type interfaceType, MethodInfo targetMethodInfo, MethodInfo interfaceMethodInfo, NetStitchOption option)
        {
            ParameterInfo[] parameterInfos = targetMethodInfo.GetParameters();

            this.ClassType     = targetType;
            this.InterfaceType = interfaceType;
            this.MethodInfo    = targetMethodInfo;
            this.ParameterType = parameterInfos.Length == 0 ? null :
                                 parameterInfos.Length == 1 ? parameterInfos[0].ParameterType :
                                 CreateParameterSturctType(interfaceType, targetMethodInfo);

            this.OperationID = $"/{InterfaceType.Name}/{MethodInfo.Name}";

            bool requiresOperationContext = targetType.GetInterfaces().Any(x => x == typeof(IOperationContext));

            bool operationIsAsyncType = typeof(ValueTask <>).IsAssignableFrom(targetMethodInfo.ReturnType);

            bool operationIsAsyncFunction = operationIsAsyncType && targetMethodInfo.ReturnType.GenericTypeArguments.Length != 0;

            Type asyncRetunType = targetMethodInfo.ReturnType.GenericTypeArguments.FirstOrDefault();

            // new Class() or new Class() { Context = Context }
            var newClass = requiresOperationContext ?
                           Expression.MemberInit(Expression.New(targetType), bindContext) :
                           Expression.MemberInit(Expression.New(targetType));

            Expression callOperation;

            if (parameterInfos.Length == 0)
            {
                callOperation = Expression.Call(newClass, targetMethodInfo);
            }
            else if (parameterInfos.Length == 1)
            {
                MethodInfo deserializeMethod = callDeserializer.MakeGenericMethod(new Type[] { this.ParameterType });
                // ParameterType obj = LZ4MessagePackSerializer.Deserialize<ParameterStructType>(HttpContext.Request.Body, FormatterResolver);
                var deserializedObj = Expression.Call(null, deserializeMethod, httpRequestBody, resolverProperty);
                callOperation = Expression.Call(newClass, targetMethodInfo, deserializedObj);
            }
            else
            {
                MethodInfo deserializeMethod = callDeserializer.MakeGenericMethod(new Type[] { this.ParameterType });

                // ParameterStructType obj = LZ4MessagePackSerializer.Deserialize<ParameterStructType>(HttpContext.Request.Body, FormatterResolver);
                var deserialize = Expression.Call(null, deserializeMethod, httpRequestBody, resolverProperty);
                var obj         = Expression.Parameter(ParameterType, "obj");
                var assign      = Expression.Assign(obj, deserialize);

                // obj.field1, obj.field2, ...
                var args = targetMethodInfo.GetParameters().Select(x => Expression.Field(obj, x.Name)).ToArray();

                // new Class().Method(obj.field1, obj.field2, ...)
                var callMethod = Expression.Call(newClass, targetMethodInfo, args);

                // ParameterStructType obj = LZ4MessagePackSerializer.Deserialize<ParameterStructType>(HttpContext.Request.Body, FormatterResolver);
                // new Class().Method(obj.field1, obj.field2, ...)
                callOperation = Expression.Block(new[] { obj }, assign, callMethod);
            }

            // ParameterStructType obj = LZ4MessagePackSerializer.Deserialize<ParameterStructType>(HttpContext.Request.Body, FormatterResolver);
            // AsyncExecute(new Class().Method(obj.field1, obj.field2, ...))
            var asyncExecuteMethodInfo = asyncRetunType != null ?
                                         typeof(OperationController).GetMethod(nameof(OperationController.AsyncFunction)).MakeGenericMethod(asyncRetunType) :
                                         typeof(OperationController).GetMethod(nameof(OperationController.AsyncAction));

            var taskExecute = Expression.Call(null, asyncExecuteMethodInfo, operationContext, callOperation);
            var lambda      = Expression.Lambda <Func <OperationContext, Task> >(taskExecute, operationContext);

            this.OperationAsync = lambda.Compile();

            this.filters = option.GlobalFilters
                           .Concat(targetType.GetTypeInfo().GetCustomAttributes <NetStitchFilterAttribute>(true))
                           .Concat(targetMethodInfo.GetCustomAttributes <NetStitchFilterAttribute>(true))
                           .OrderBy(x => x.Order)
                           .ToArray();

            this.OperationAsync = SetFilter(this.OperationAsync);
        }
示例#7
0
 public OperationContext(HttpContext httpContext, OperationController operationController, NetStitchOption option)
 {
     this.httpcontext         = httpContext;
     this.operationController = operationController;
     this.option = option;
 }