Ejemplo n.º 1
0
 public RedisGroupRepository(IFormatterResolver resolver, ConnectionMultiplexer connection, IMagicOnionLogger logger)
 {
     this.resolver   = resolver;
     this.logger     = logger;
     this.factory    = CreateGroup;
     this.connection = connection;
 }
Ejemplo n.º 2
0
 public DuplexStreamingContext(ServiceContext context)
 {
     this.context     = context;
     this.innerReader = context.RequestStream !;
     this.innerWriter = context.ResponseStream !;
     this.logger      = context.MagicOnionLogger;
 }
Ejemplo n.º 3
0
        public ServiceContext(
            Type serviceType,
            MethodInfo methodInfo,
            ILookup <Type, Attribute> attributeLookup,
            MethodType methodType,
            ServerCallContext context,
            MessagePackSerializerOptions serializerOptions,
            IMagicOnionLogger logger,
            MethodHandler methodHandler,
            IServiceProvider serviceProvider
            )
        {
            this.ContextId         = Guid.NewGuid();
            this.ServiceType       = serviceType;
            this.MethodInfo        = methodInfo;
            this.AttributeLookup   = attributeLookup;
            this.MethodType        = methodType;
            this.CallContext       = context;
            this.Timestamp         = DateTime.UtcNow;
            this.SerializerOptions = serializerOptions;
            this.MagicOnionLogger  = logger;
            this.MethodHandler     = methodHandler;
            this.ServiceProvider   = serviceProvider;

            // streaming hub
            if (methodType == MethodType.DuplexStreaming)
            {
                this.streamingResponseWriter = new Lazy <QueuedResponseWriter>(new Func <QueuedResponseWriter>(CreateQueuedResponseWriter));
            }
            else
            {
                this.streamingResponseWriter = null !;
            }
        }
 public ImmutableArrayGroup(string groupName, IGroupRepository parent, MessagePackSerializerOptions serializerOptions, IMagicOnionLogger logger)
 {
     this.GroupName         = groupName;
     this.parent            = parent;
     this.serializerOptions = serializerOptions;
     this.logger            = logger;
     this.members           = ImmutableArray <ServiceContext> .Empty;
 }
Ejemplo n.º 5
0
 public RedisGroupRepository(MessagePackSerializerOptions serializerOptions, RedisGroupOptions redisGroupOptions, IMagicOnionLogger logger)
 {
     this.serializerOptions = serializerOptions;
     this.logger            = logger;
     this.factory           = CreateGroup;
     this.connection        = redisGroupOptions.ConnectionMultiplexer ?? throw new InvalidOperationException("RedisGroup requires add ConnectionMultiplexer to MagicOnionOptions.ServiceLocator before create it. Please try new MagicOnionOptions{DefaultServiceLocator.Register(new ConnectionMultiplexer)}");
     this.db = redisGroupOptions.Db;
 }
Ejemplo n.º 6
0
 public ConcurrentDictionaryGroup(string groupName, IGroupRepository parent, MessagePackSerializerOptions serializerOptions, IMagicOnionLogger logger)
 {
     this.GroupName         = groupName;
     this.parent            = parent;
     this.serializerOptions = serializerOptions;
     this.logger            = logger;
     this.members           = new ConcurrentDictionary <Guid, ServiceContext>();
 }
Ejemplo n.º 7
0
 public RedisGroupRepository(MessagePackSerializerOptions serializerOptions, RedisGroupOptions redisGroupOptions, IMagicOnionLogger logger)
 {
     this.serializerOptions = serializerOptions;
     this.logger            = logger;
     this.factory           = CreateGroup;
     this.connection        = redisGroupOptions.ConnectionMultiplexer;
     this.db = redisGroupOptions.Db;
 }
 public ConcurrentDictionaryGroup(string groupName, IGroupRepository parent, IFormatterResolver resolver, IMagicOnionLogger logger)
 {
     this.GroupName = groupName;
     this.parent    = parent;
     this.resolver  = resolver;
     this.logger    = logger;
     this.members   = new ConcurrentDictionary <Guid, ServiceContext>();
 }
Ejemplo n.º 9
0
 public ImmutableArrayGroup(string groupName, IGroupRepository parent, IFormatterResolver resolver, IMagicOnionLogger logger)
 {
     this.GroupName = groupName;
     this.parent    = parent;
     this.resolver  = resolver;
     this.logger    = logger;
     this.members   = ImmutableArray <ServiceContext> .Empty;
 }
Ejemplo n.º 10
0
 public ServiceContext(Type serviceType, MethodInfo methodInfo, ILookup <Type, Attribute> attributeLookup, MethodType methodType, ServerCallContext context, IMagicOnionLogger logger)
 {
     this.ServiceType      = serviceType;
     this.MethodInfo       = methodInfo;
     this.AttributeLookup  = attributeLookup;
     this.MethodType       = methodType;
     this.CallContext      = context;
     this.Timestamp        = DateTime.UtcNow;
     this.MagicOnionLogger = logger;
 }
Ejemplo n.º 11
0
 public ServiceContext(
     Type serviceType,
     MethodInfo methodInfo,
     ILookup <Type, Attribute> attributeLookup,
     MethodType methodType,
     ServerCallContext context,
     MessagePackSerializerOptions serializerOptions,
     IMagicOnionLogger logger,
     MethodHandler methodHandler,
     IServiceProvider serviceProvider
     )
 {
     this.ContextId         = Guid.NewGuid();
     this.ServiceType       = serviceType;
     this.MethodInfo        = methodInfo;
     this.AttributeLookup   = attributeLookup;
     this.MethodType        = methodType;
     this.CallContext       = context;
     this.Timestamp         = DateTime.UtcNow;
     this.SerializerOptions = serializerOptions;
     this.MagicOnionLogger  = logger;
     this.MethodHandler     = methodHandler;
     this.ServiceProvider   = serviceProvider;
 }
Ejemplo n.º 12
0
 public ClientStreamingContext(ServiceContext context)
 {
     this.context = context;
     this.inner   = context.RequestStream;
     this.logger  = context.MagicOnionLogger;
 }
Ejemplo n.º 13
0
 public ServiceContext(Type serviceType, MethodInfo methodInfo, ILookup <Type, Attribute> attributeLookup, MethodType methodType, ServerCallContext context, IFormatterResolver resolver, IMagicOnionLogger logger, MethodHandler methodHandler, IServiceLocator serviceLocator)
 {
     this.ContextId         = Guid.NewGuid();
     this.ServiceType       = serviceType;
     this.MethodInfo        = methodInfo;
     this.AttributeLookup   = attributeLookup;
     this.MethodType        = methodType;
     this.CallContext       = context;
     this.Timestamp         = DateTime.UtcNow;
     this.FormatterResolver = resolver;
     this.MagicOnionLogger  = logger;
     this.MethodHandler     = methodHandler;
     this.ServiceLocator    = serviceLocator;
 }
Ejemplo n.º 14
0
        public MethodHandler(MagicOnionOptions options, Type classType, MethodInfo methodInfo)
        {
            this.ServiceType = classType;
            this.ServiceName = classType.GetInterfaces().First(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IService <>)).GetGenericArguments()[0].Name;
            this.MethodInfo  = methodInfo;
            MethodType mt;

            this.UnwrappedResponseType = UnwrapResponseType(methodInfo, out mt, out responseIsTask, out this.RequestType);
            this.MethodType            = mt;
            this.resolver = options.FormatterResolver;

            var parameters = methodInfo.GetParameters();

            if (RequestType == null)
            {
                this.RequestType = MagicOnionMarshallers.CreateRequestTypeAndSetResolver(classType.Name + "/" + methodInfo.Name, parameters, ref resolver);
            }

            this.AttributeLookup = classType.GetCustomAttributes(true)
                                   .Concat(methodInfo.GetCustomAttributes(true))
                                   .Cast <Attribute>()
                                   .ToLookup(x => x.GetType());

            this.filters = options.GlobalFilters
                           .Concat(classType.GetCustomAttributes <MagicOnionFilterAttribute>(true))
                           .Concat(methodInfo.GetCustomAttributes <MagicOnionFilterAttribute>(true))
                           .OrderBy(x => x.Order)
                           .ToArray();

            // options
            this.isReturnExceptionStackTraceInErrorDetail = options.IsReturnExceptionStackTraceInErrorDetail;
            this.logger = options.MagicOnionLogger;

            // prepare lambda parameters
            var contextArg  = Expression.Parameter(typeof(ServiceContext), "context");
            var contextBind = Expression.Bind(classType.GetProperty("Context"), contextArg);
            var instance    = Expression.MemberInit(Expression.New(classType), contextBind);

            switch (MethodType)
            {
            case MethodType.Unary:
            case MethodType.ServerStreaming:
                // (ServiceContext context) =>
                // {
                //      var request = LZ4MessagePackSerializer.Deserialize<T>(context.Request, context.Resolver);
                //      var result = new FooService() { Context = context }.Bar(request.Item1, request.Item2);
                //      return MethodHandlerResultHelper.SerializeUnaryResult(result, context);
                // };
                try
                {
                    var flags       = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
                    var staticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

                    var requestArg  = Expression.Parameter(RequestType, "request");
                    var getResolver = Expression.Property(contextArg, typeof(ServiceContext).GetProperty("FormatterResolver", flags));

                    var contextRequest = Expression.Property(contextArg, typeof(ServiceContext).GetProperty("Request", flags));

                    var callDeserialize = Expression.Call(messagePackDeserialize.MakeGenericMethod(RequestType), contextRequest, getResolver);
                    var assignRequest   = Expression.Assign(requestArg, callDeserialize);

                    Expression[] arguments = new Expression[parameters.Length];
                    if (parameters.Length == 1)
                    {
                        arguments[0] = requestArg;
                    }
                    else
                    {
                        for (int i = 0; i < parameters.Length; i++)
                        {
                            arguments[i] = Expression.Field(requestArg, "Item" + (i + 1));
                        }
                    }

                    var callBody = Expression.Call(instance, methodInfo, arguments);

                    if (MethodType == MethodType.Unary)
                    {
                        var finalMethod = (responseIsTask)
                                ? typeof(MethodHandlerResultHelper).GetMethod("SerializeTaskUnaryResult", staticFlags).MakeGenericMethod(UnwrappedResponseType)
                                : typeof(MethodHandlerResultHelper).GetMethod("SerializeUnaryResult", staticFlags).MakeGenericMethod(UnwrappedResponseType);
                        callBody = Expression.Call(finalMethod, callBody, contextArg);
                    }
                    else
                    {
                        if (!responseIsTask)
                        {
                            callBody = Expression.Call(typeof(Task).GetMethod("FromResult").MakeGenericMethod(MethodInfo.ReturnType), callBody);
                        }
                    }

                    var body         = Expression.Block(new[] { requestArg }, assignRequest, callBody);
                    var compiledBody = Expression.Lambda(body, contextArg).Compile();

                    this.methodBody = BuildMethodBodyWithFilter((Func <ServiceContext, Task>)compiledBody);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException($"Can't create handler. Path:{ToString()}", ex);
                }
                break;

            case MethodType.ClientStreaming:
            case MethodType.DuplexStreaming:
                if (parameters.Length != 0)
                {
                    throw new InvalidOperationException($"{MethodType} does not support method parameters. If you need to send initial parameter, use header instead. Path:{ToString()}");
                }

                // (ServiceContext context) => new FooService() { Context = context }.Bar();
                try
                {
                    var body = Expression.Call(instance, methodInfo);

                    if (MethodType == MethodType.ClientStreaming)
                    {
                        var staticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
                        var finalMethod = (responseIsTask)
                                ? typeof(MethodHandlerResultHelper).GetMethod("SerializeTaskClientStreamingResult", staticFlags).MakeGenericMethod(RequestType, UnwrappedResponseType)
                                : typeof(MethodHandlerResultHelper).GetMethod("SerializeClientStreamingResult", staticFlags).MakeGenericMethod(RequestType, UnwrappedResponseType);
                        body = Expression.Call(finalMethod, body, contextArg);
                    }
                    else
                    {
                        if (!responseIsTask)
                        {
                            body = Expression.Call(typeof(Task).GetMethod("FromResult").MakeGenericMethod(MethodInfo.ReturnType), body);
                        }
                    }

                    var compiledBody = Expression.Lambda(body, contextArg).Compile();

                    this.methodBody = BuildMethodBodyWithFilter((Func <ServiceContext, Task>)compiledBody);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException($"Can't create handler. Path:{ToString()}", ex);
                }
                break;

            default:
                throw new InvalidOperationException("Unknown MethodType:" + MethodType + $"Path:{ToString()}");
            }
        }
 public ConcurrentDictionaryGroupRepository(IFormatterResolver resolver, IMagicOnionLogger logger)
 {
     this.resolver = resolver;
     this.factory  = CreateGroup;
     this.logger   = logger;
 }
Ejemplo n.º 16
0
        public IGroupRepository CreateRepository(MessagePackSerializerOptions serializerOptions, IMagicOnionLogger logger, IServiceLocator serviceLocator)
        {
            var connection = serviceLocator.GetService <ConnectionMultiplexer>();

            if (connection == null)
            {
                throw new InvalidOperationException("RedisGroup requires add ConnectionMultiplexer to MagicOnionOptions.ServiceLocator before create it. Please try new MagicOnionOptions{DefaultServiceLocator.Register(new ConnectionMultiplexer)}");
            }

            return(new RedisGroupRepository(serializerOptions, connection, logger));
        }
Ejemplo n.º 17
0
 public ConcurrentDictionaryGroupRepository(MessagePackSerializerOptions serializerOptions, IMagicOnionLogger logger)
 {
     this.serializerOptions = serializerOptions;
     this.factory           = CreateGroup;
     this.logger            = logger;
 }
Ejemplo n.º 18
0
 public IGroupRepository CreateRepository(MessagePackSerializerOptions serializerOptions, IMagicOnionLogger logger, IServiceLocator serviceLocator)
 {
     return(new ConcurrentDictionaryGroupRepository(serializerOptions, logger));
 }
Ejemplo n.º 19
0
 public ImmutableArrayGroupRepository(IFormatterResolver resolver, IMagicOnionLogger logger)
 {
     this.resolver = resolver;
     this.factory  = CreateGroup;
     this.logger   = logger;
 }
Ejemplo n.º 20
0
        public MethodHandler(MagicOnionOptions options, Type classType, MethodInfo methodInfo)
        {
            this.ServiceType = classType;
            this.ServiceName = classType.GetInterfaces().First(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IService <>)).GetGenericArguments()[0].Name;
            this.MethodInfo  = methodInfo;
            MethodType mt;

            this.UnwrappedResponseType = UnwrapResponseType(methodInfo, out mt, out responseIsTask, out this.RequestType);
            this.MethodType            = mt;

            var parameters = methodInfo.GetParameters();

            if (RequestType == null)
            {
                this.RequestType = MagicOnionMarshallers.CreateRequestTypeAndMarshaller(options.ZeroFormatterTypeResolverType, classType.Name + "/" + methodInfo.Name, parameters, out requestMarshaller);
            }
            else
            {
                this.requestMarshaller = MagicOnionMarshallers.CreateZeroFormattertMarshallerReflection(options.ZeroFormatterTypeResolverType, RequestType);
            }

            this.responseMarshaller = MagicOnionMarshallers.CreateZeroFormattertMarshallerReflection(options.ZeroFormatterTypeResolverType, UnwrappedResponseType);

            this.AttributeLookup = classType.GetCustomAttributes(true)
                                   .Concat(methodInfo.GetCustomAttributes(true))
                                   .Cast <Attribute>()
                                   .ToLookup(x => x.GetType());

            this.filters = options.GlobalFilters
                           .Concat(classType.GetCustomAttributes <MagicOnionFilterAttribute>(true))
                           .Concat(methodInfo.GetCustomAttributes <MagicOnionFilterAttribute>(true))
                           .OrderBy(x => x.Order)
                           .ToArray();

            // options
            this.isReturnExceptionStackTraceInErrorDetail = options.IsReturnExceptionStackTraceInErrorDetail;
            this.logger = options.MagicOnionLogger;

            // prepare lambda parameters
            var contextArg  = Expression.Parameter(typeof(ServiceContext), "context");
            var contextBind = Expression.Bind(classType.GetProperty("Context"), contextArg);
            var instance    = Expression.MemberInit(Expression.New(classType), contextBind);

            switch (MethodType)
            {
            case MethodType.Unary:
            case MethodType.ServerStreaming:
                // (ServiceContext context) =>
                // {
                //      var request = ((Marshaller<TRequest>)context.RequestMarshaller).Deserializer.Invoke(context.Request);
                //      return new FooService() { Context = context }.Bar(request.Item1, request.Item2);
                // };
            {
                var flags          = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
                var marshallerType = typeof(Marshaller <>).MakeGenericType(RequestType);

                var requestArg = Expression.Parameter(RequestType, "request");

                var requestMarshalleExpr = Expression.Convert(Expression.Property(contextArg, typeof(ServiceContext).GetProperty("RequestMarshaller", flags)), marshallerType);
                var deserializer         = Expression.Property(requestMarshalleExpr, "Deserializer");
                var callDeserialize      = Expression.Call(deserializer, typeof(Func <,>).MakeGenericType(typeof(byte[]), RequestType).GetMethod("Invoke"), Expression.Property(contextArg, typeof(ServiceContext).GetProperty("Request", flags)));

                var assignRequest = Expression.Assign(requestArg, callDeserialize);

                Expression[] arguments = new Expression[parameters.Length];
                if (parameters.Length == 1)
                {
                    arguments[0] = requestArg;
                }
                else
                {
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        arguments[i] = Expression.Field(requestArg, "Item" + (i + 1));
                    }
                }

                var callBody = Expression.Call(instance, methodInfo, arguments);
                if (!responseIsTask)
                {
                    callBody = Expression.Call(typeof(Task).GetMethod("FromResult").MakeGenericMethod(MethodInfo.ReturnType), callBody);
                }

                var body         = Expression.Block(new[] { requestArg }, assignRequest, callBody);
                var compiledBody = Expression.Lambda(body, contextArg).Compile();

                this.methodBody = BuildMethodBodyWithFilter((Func <ServiceContext, Task>)compiledBody);
            }
            break;

            case MethodType.ClientStreaming:
            case MethodType.DuplexStreaming:
                if (parameters.Length != 0)
                {
                    throw new InvalidOperationException($"{MethodType} does not support method parameters. If you need to send initial parameter, use header instead.");
                }

                // (ServiceContext context) => new FooService() { Context = context }.Bar();
                {
                    var body = Expression.Call(instance, methodInfo);
                    if (!responseIsTask)
                    {
                        body = Expression.Call(typeof(Task).GetMethod("FromResult").MakeGenericMethod(MethodInfo.ReturnType), body);
                    }

                    var compiledBody = Expression.Lambda(body, contextArg).Compile();

                    this.methodBody = BuildMethodBodyWithFilter((Func <ServiceContext, Task>)compiledBody);
                }
                break;

            default:
                throw new InvalidOperationException("Unknown MethodType:" + MethodType);
            }

            // Utility
            {
                // (object requestMarshaller, object value) => ((Marshaller<TRequest>)requestMarshaller).Serializer.Invoke((TRequest)value);
                var marshallerType       = typeof(Marshaller <>).MakeGenericType(RequestType);
                var requestMarshallerArg = Expression.Parameter(typeof(object), "requestMarshaller");
                var valueArg             = Expression.Parameter(typeof(object), "value");
                var serializer           = Expression.Property(Expression.Convert(requestMarshallerArg, marshallerType), "Serializer");
                var callSerialize        = Expression.Call(serializer, typeof(Func <,>).MakeGenericType(RequestType, typeof(byte[])).GetMethod("Invoke"),
                                                           Expression.Convert(valueArg, RequestType));

                boxedRequestSerialize = Expression.Lambda <Func <object, object, byte[]> >(callSerialize, requestMarshallerArg, valueArg).Compile();
            }
            {
                // (object responseMarshaller, byte[] value) => ((Marshaller<TResponse>)requestMarshaller).Deserializer.Invoke(value);
                var marshallerType        = typeof(Marshaller <>).MakeGenericType(UnwrappedResponseType);
                var responseMarshallerArg = Expression.Parameter(typeof(object), "responseMarshaller");
                var valueArg        = Expression.Parameter(typeof(byte[]), "value");
                var deserializer    = Expression.Property(Expression.Convert(responseMarshallerArg, marshallerType), "Deserializer");
                var callDeserialize = Expression.Convert(Expression.Call(deserializer, typeof(Func <,>).MakeGenericType(typeof(byte[]), UnwrappedResponseType).GetMethod("Invoke"), valueArg), typeof(object));
                boxedResponseDeserialize = Expression.Lambda <Func <object, byte[], object> >(callDeserialize, responseMarshallerArg, valueArg).Compile();
            }
        }
Ejemplo n.º 21
0
 public IGroupRepository CreateRepository(IFormatterResolver formatterResolver, IMagicOnionLogger logger, IServiceLocator serviceLocator)
 {
     return(new ImmutableArrayGroupRepository(formatterResolver, logger));
 }
Ejemplo n.º 22
0
 public ServerStreamingContext(ServiceContext context)
 {
     this.context = context;
     this.inner   = context.ResponseStream;
     this.logger  = context.MagicOnionLogger;
 }
Ejemplo n.º 23
0
 public LoggableStreamWriter(IMagicOnionLogger logger, ServiceContext context, IAsyncStreamWriter <T> writer)
 {
     this.logger  = logger;
     this.context = context;
     this.writer  = writer;
 }
Ejemplo n.º 24
0
 public ImmutableArrayGroupRepository(MessagePackSerializerOptions serializerOptions, IMagicOnionLogger logger)
 {
     this.serializerOptions = serializerOptions;
     this.factory           = CreateGroup;
     this.logger            = logger;
 }
Ejemplo n.º 25
0
 public IGroupRepository CreateRepository(MessagePackSerializerOptions serializerOptions, IMagicOnionLogger logger)
 {
     return(new ImmutableArrayGroupRepository(serializerOptions, logger));
 }
Ejemplo n.º 26
0
 public IGroupRepository CreateRepository(MessagePackSerializerOptions serializerOptions, IMagicOnionLogger logger)
 {
     return(new RedisGroupRepository(serializerOptions, _options, logger));
 }
Ejemplo n.º 27
0
 public IGroupRepository CreateRepository(IFormatterResolver formatterResolver, IMagicOnionLogger logger, IServiceLocator serviceLocator)
 {
     return(new ConcurrentDictionaryGroupRepository(formatterResolver, logger));
 }
Ejemplo n.º 28
0
 public LoggableStreamReader(IMagicOnionLogger logger, ServiceContext context, IAsyncStreamReader <T> reader)
 {
     this.logger  = logger;
     this.context = context;
     this.reader  = reader;
 }