예제 #1
0
        public override void DoInit(IContainer container)
        {
            if (_options != null)
            {
                var logger = container.Resolve <ILogger>();
                logger.Info($"[config]use jose.jwt for Auth");

                //while (!container.IsRegistered<IServer>() || !container.IsRegistered<IServiceDiscovery>())
                //{
                //    Thread.Sleep(200);
                //}
                var server = container.Resolve <IServer>();
                server.UseMiddleware <JwtAuthorizationMiddleware>(_options, container);

                if (string.IsNullOrEmpty(_options.TokenEndpointPath))
                {
                    return;
                }
                var discovery  = container.Resolve <IServiceDiscovery>();
                var addr       = new JimuAddress(_options.ServiceInvokeIp, Convert.ToInt32(_options.ServiceInvokePort), _options.Protocol);
                var tokenRoute =
                    new JimuServiceRoute
                {
                    Address = new List <JimuAddress> {
                        addr
                    },
                    ServiceDescriptor = new JimuServiceDesc
                    {
                        Id         = _options.GetServiceId(),
                        RoutePath  = JimuServiceRoute.ParseRoutePath("", "", _options.TokenEndpointPath, new[] { "username", "password" }, false),
                        Parameters = JimuHelper.Serialize <string>(new List <JimuServiceParameterDesc> {
                            new JimuServiceParameterDesc
                            {
                                Comment = "username",
                                Format  = "System.String",
                                Name    = "username",
                                Type    = "object"
                            },
                            new JimuServiceParameterDesc
                            {
                                Comment = "password",
                                Format  = "System.String",
                                Name    = "password",
                                Type    = "object"
                            },
                        }),
                        ReturnDesc = JimuHelper.Serialize <string>(new JimuServiceReturnDesc
                        {
                            Comment      = "Token",
                            ReturnType   = "object",
                            ReturnFormat = "{\"access_token\":\"System.String | token\", \"expired_in\":\"System.Int32 | expired timestamp which is the number of seconds between 1970-01-01 and expired datetime\"}"
                        })
                    }
                };
                //discovery.ClearServiceAsync(tokenRoute.First().ServiceDescriptor.Id).Wait();
                ////discovery.SetRoutesAsync(tokenRoute);
                //discovery.AddRouteAsync(tokenRoute).Wait();
                discovery.OnBeforeSetRoutes += (routes) =>
                {
                    routes.Add(tokenRoute);
                };
            }

            base.DoInit(container);
        }
예제 #2
0
파일: NLogger.cs 프로젝트: zhangbo27/jimu
        public NLogger(JimuLog4netOptions options = null)
        {
            options = options ?? new JimuLog4netOptions {
                EnableConsoleLog = true
            };
            var config = new NLog.Config.LoggingConfiguration();
            var ip     = JimuHelper.GetLocalIPAddress();

            if (options.EnableFileLog)
            {
                var fileConf = new NLog.Targets.FileTarget("jimuLogFile")
                {
                    FileName         = "./log/${level:lowercase=true}/${shortdate}.log",
                    ArchiveAboveSize = 10000000,
                    Layout           = @"${date:format=yyyy-MM-dd HH\:mm\:ss.fff} ${level:uppercase=true} [" + ip + "] ${message}"
                };
                if (options.FileLogPath != null)
                {
                    fileConf.FileName = options.FileLogPath + "/${level:lowercase=true}/${shortdate}.log";
                }
                if ((options.FileLogLevel & LogLevel.Error) == LogLevel.Error)
                {
                    config.AddRuleForOneLevel(NLog.LogLevel.Error, fileConf);
                }
                if ((options.FileLogLevel & LogLevel.Warn) == LogLevel.Warn)
                {
                    //config.AddRuleForOneLevel(NLog.LogLevel.Warn, fileConf);
                    config.AddRule(NLog.LogLevel.Warn, NLog.LogLevel.Error, fileConf);
                }
                if ((options.FileLogLevel & LogLevel.Info) == LogLevel.Info)
                {
                    config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Error, fileConf);
                    //config.AddRuleForOneLevel(NLog.LogLevel.Info, fileConf);
                }
                if ((options.FileLogLevel & LogLevel.Debug) == LogLevel.Debug)
                {
                    config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Error, fileConf);
                    //config.AddRuleForOneLevel(NLog.LogLevel.Debug, fileConf);
                }
            }

            if (options.EnableConsoleLog)
            {
                var consoleLog = new NLog.Targets.ConsoleTarget("jimuLogconsole")
                {
                    Layout = @"${date:format=yyyy-MM-dd HH\:mm\:ss.fff} ${level:uppercase=true} [" + ip + "] ${message}"
                };
                if ((options.ConsoleLogLevel & LogLevel.Error) == LogLevel.Error)
                {
                    config.AddRuleForOneLevel(NLog.LogLevel.Error, consoleLog);
                }
                if ((options.ConsoleLogLevel & LogLevel.Warn) == LogLevel.Warn)
                {
                    config.AddRule(NLog.LogLevel.Warn, NLog.LogLevel.Error, consoleLog);
                    //config.AddRuleForOneLevel(NLog.LogLevel.Warn, consoleLog);
                }
                if ((options.ConsoleLogLevel & LogLevel.Info) == LogLevel.Info)
                {
                    config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Error, consoleLog);
                    //config.AddRuleForOneLevel(NLog.LogLevel.Info, consoleLog);
                }
                if ((options.ConsoleLogLevel & LogLevel.Debug) == LogLevel.Debug)
                {
                    config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Error, consoleLog);
                    //config.AddRuleForOneLevel(NLog.LogLevel.Debug, consoleLog);
                }
            }
            NLog.LogManager.Configuration = config;
            _logger = NLog.LogManager.GetLogger("jimuLogger");
        }
예제 #3
0
 public ConsoleLogger()
 {
     _ip = JimuHelper.GetLocalIPAddress();
 }
        public override void DoInit(IContainer container)
        {
            if (_options != null && _options.Enable)
            {
                var loggerFactory = container.Resolve <ILoggerFactory>();
                var logger        = loggerFactory.Create(this.GetType());
                logger.Info($"[config]use consul for services discovery, consul ip: {_options.Ip}:{_options.Port}, service category: {_options.ServiceGroups}");

                var clientDiscovery = container.Resolve <IClientServiceDiscovery>();
                clientDiscovery.AddRoutesGetter(async() =>
                {
                    var consul = new ConsulClient(config => { config.Address = new Uri($"http://{_options.Ip}:{_options.Port}"); });
                    HashSet <string> keyset = new HashSet <string>();
                    foreach (var group in _options.ServiceGroups.Split(','))
                    {
                        if (string.IsNullOrEmpty(group))
                        {
                            continue;
                        }
                        var queryResult = await consul.KV.Keys(group);
                        if (queryResult == null || queryResult.Response == null)
                        {
                            continue;
                        }

                        foreach (var key in queryResult.Response)
                        {
                            keyset.Add(key);
                        }
                    }
                    if (!keyset.Any())
                    {
                        return(null);
                    }

                    var routes = new List <JimuServiceRoute>();
                    foreach (var key in keyset)
                    {
                        var data = (await consul.KV.Get(key)).Response?.Value;
                        if (data == null)
                        {
                            continue;
                        }

                        var descriptors = JimuHelper.Deserialize <byte[], List <JimuServiceRouteDesc> >(data);
                        if (descriptors != null && descriptors.Any())
                        {
                            foreach (var descriptor in descriptors)
                            {
                                List <JimuAddress> addresses =
                                    new List <JimuAddress>(descriptor.AddressDescriptors.ToArray().Count());
                                foreach (var addDesc in descriptor.AddressDescriptors)
                                {
                                    //var addrType = Type.GetType(addDesc.Type);
                                    addresses.Add(JimuHelper.Deserialize(addDesc.Value, typeof(JimuAddress)) as JimuAddress);
                                }

                                routes.Add(new JimuServiceRoute
                                {
                                    Address           = addresses,
                                    ServiceDescriptor = descriptor.ServiceDescriptor
                                });
                            }
                        }
                    }

                    return(routes);
                });
            }
            base.DoInit(container);
        }
예제 #5
0
        public override void DoInit(IContainer container)
        {
            if (_options != null)
            {
                var logger = container.Resolve <ILogger>();
                logger.Info($"[config]use jose.jwt for Auth");

                while (!container.IsRegistered <IRemoteServiceCaller>() || !container.IsRegistered <IClientServiceDiscovery>())
                {
                    Thread.Sleep(100);
                }

                var caller = container.Resolve <IRemoteServiceCaller>();
                caller.UseMiddleware <JwtAuthorizationMiddleware>(_options);

                if (string.IsNullOrEmpty(_options.TokenEndpointPath))
                {
                    return;
                }
                var discovery  = container.Resolve <IClientServiceDiscovery>();
                var addr       = new JimuAddress(_options.ServerIp, _options.ServerPort, _options.Protocol);
                var tokenRoute = new List <JimuServiceRoute> {
                    new JimuServiceRoute
                    {
                        Address = new List <JimuAddress> {
                            addr
                        },
                        ServiceDescriptor = new JimuServiceDesc
                        {
                            Id         = _options.GetServiceId(),
                            RoutePath  = JimuServiceRoute.ParseRoutePath("", "", _options.TokenEndpointPath, new[] { "username", "password" }, false),
                            Parameters = JimuHelper.Serialize <string>(new List <JimuServiceParameterDesc> {
                                new JimuServiceParameterDesc
                                {
                                    Comment = "username",
                                    Format  = "System.String",
                                    Name    = "username",
                                    Type    = "object"
                                },
                                new JimuServiceParameterDesc
                                {
                                    Comment = "password",
                                    Format  = "System.String",
                                    Name    = "password",
                                    Type    = "object"
                                },
                            }),
                            ReturnDesc = JimuHelper.Serialize <string>(new JimuServiceReturnDesc {
                                Comment      = "Token",
                                ReturnType   = "object",
                                ReturnFormat = "{\"access_token\":\"System.String | token\", \"expired_in\":\"System.Int32 | expired timestamp which is the number of seconds between 1970-01-01 and expired datetime\"}"
                            })
                        }
                    }
                };
                discovery.AddRoutesGetter(() =>
                {
                    return(Task.FromResult(tokenRoute));
                });
            }

            base.DoInit(container);
        }
예제 #6
0
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            var serviceDiscovery = JimuClient.Host.Container.Resolve <IClientServiceDiscovery>();
            var routes           = serviceDiscovery.GetRoutesAsync().GetAwaiter().GetResult();

            (from route in routes select route.ServiceDescriptor).OrderBy(x => x.RoutePath).ToList().ForEach(x =>
            {
                var subsIndex = x.RoutePath.IndexOf('?');
                subsIndex     = subsIndex < 0 ? x.RoutePath.Length : subsIndex;
                var route     = x.RoutePath.Substring(0, subsIndex);
                route         = route.StartsWith('/') ? route : "/" + route;

                var paras = new List <IParameter>();
                if (!string.IsNullOrEmpty(x.Parameters))
                {
                    var parameters = JimuHelper.Deserialize(TypeHelper.ReplaceTypeToJsType(x.Parameters), typeof(List <JimuServiceParameterDesc>)) as List <JimuServiceParameterDesc>;
                    paras          = GetParameters(parameters, x.HttpMethod);
                }

                if (x.GetMetadata <bool>("EnableAuthorization"))
                {
                    paras.Add(new NonBodyParameter
                    {
                        Name        = "Authorization",
                        Type        = "string",
                        In          = "header",
                        Description = "Token",
                        Required    = true,
                        Default     = "Bearer "
                    });
                }

                var response = new Dictionary <string, Response>();
                response.Add("200", GetResponse(x.ReturnDesc));

                if (x.HttpMethod == "GET")
                {
                    swaggerDoc.Paths.Add(route, new PathItem
                    {
                        Get = new Operation
                        {
                            Consumes = new List <string> {
                                "application/json"
                            },
                            OperationId = x.RoutePath,
                            Parameters  = paras,
                            Produces    = new List <string> {
                                "application/json"
                            },
                            Responses   = response,
                            Description = x.Comment
                        }
                    });
                }
                else
                {
                    swaggerDoc.Paths.Add(route, new PathItem
                    {
                        Post = new Operation
                        {
                            Consumes = new List <string> {
                                "application/json"
                            },
                            OperationId = x.RoutePath,
                            Parameters  = paras,
                            Produces    = new List <string> {
                                "application/json"
                            },
                            Responses   = response,
                            Description = x.Comment
                        }
                    });
                }
            });
        }
예제 #7
0
        void UseCodeConfig(Hierarchy repository, LogLevel logLevel)
        {
            var ip = JimuHelper.GetLocalIPAddress();

            if (_options.EnableFileLog && (_options.FileLogLevel & logLevel) == logLevel)
            {
                PatternLayout layout = new PatternLayout
                {
                    ConversionPattern = "%date{yyyy-MM-dd HH:mm:ss.fff} %-5p [" + ip + "] %m%n"
                };
                layout.ActivateOptions();

                RollingFileAppender roller = new RollingFileAppender
                {
                    AppendToFile = true
                };
                var path = _options.EnableFileLog ? _options.FileLogPath : "log";
                roller.File = $@"{path}/{logLevel.ToString().ToLower()}/";
                roller.PreserveLogFileNameExtension = true;
                roller.StaticLogFileName            = false;
                roller.MaxSizeRollBackups           = 0;
                roller.DatePattern  = $@"yyyyMMdd"".log""";
                roller.RollingStyle = RollingFileAppender.RollingMode.Date;
                roller.Layout       = layout;
                roller.MaxFileSize  = 10000000;
                switch (logLevel)
                {
                case LogLevel.Debug:
                    roller.Threshold = Level.Debug;
                    break;

                case LogLevel.Info:
                    roller.Threshold = Level.Info;
                    break;

                case LogLevel.Warn:
                    roller.Threshold = Level.Warn;
                    break;

                case LogLevel.Error:
                    roller.Threshold = Level.Error;
                    break;
                }
                roller.ActivateOptions();
                repository.Root.AddAppender(roller);
            }

            if (_options.EnableConsoleLog && (_options.ConsoleLogLevel & logLevel) == logLevel)
            {
                ManagedColoredConsoleAppender console = new ManagedColoredConsoleAppender();
                PatternLayout layoutConsole           = new PatternLayout
                {
                    ConversionPattern = "%n%date{yyyy-MM-dd HH:mm:ss.fff} %-5level [" + ip + "] %m",
                };
                switch (logLevel)
                {
                case LogLevel.Debug:
                    console.AddFilter(new LevelRangeFilter()
                    {
                        LevelMax = Level.Debug, LevelMin = Level.Debug
                    });
                    break;

                case LogLevel.Info:
                    console.AddFilter(new LevelRangeFilter()
                    {
                        LevelMax = Level.Info, LevelMin = Level.Info
                    });
                    break;

                case LogLevel.Warn:
                    console.AddFilter(new LevelRangeFilter()
                    {
                        LevelMax = Level.Warn, LevelMin = Level.Warn
                    });
                    break;

                case LogLevel.Error:
                    console.AddFilter(new LevelRangeFilter()
                    {
                        LevelMax = Level.Error, LevelMin = Level.Error
                    });
                    break;
                }
                console.AddMapping(
                    new ManagedColoredConsoleAppender.LevelColors {
                    Level = Level.Error, ForeColor = ConsoleColor.DarkRed
                });
                console.AddMapping(
                    new ManagedColoredConsoleAppender.LevelColors {
                    Level = Level.Warn, ForeColor = ConsoleColor.DarkYellow
                });

                layoutConsole.ActivateOptions();
                console.Layout = layoutConsole;
                console.ActivateOptions();
                repository.Root.AddAppender(console);
            }

            repository.Configured = true;
        }
예제 #8
0
        public Task <JimuRemoteCallResultData> InvokeAsync(RemoteCallerContext context)
        {
            // get jwt token
            if (!string.IsNullOrEmpty(_options.TokenEndpointPath) &&
                context.Service.ServiceDescriptor.Id == _options.GetServiceId())
            {
                if (_options.CheckCredential == null)
                {
                    throw new Exception("JwtAuthorizationOptions.CheckCredential must be provided");
                }
                JwtAuthorizationContext jwtAuthorizationContext = new JwtAuthorizationContext(_options, context);

                _options.CheckCredential(jwtAuthorizationContext);
                if (jwtAuthorizationContext.IsRejected)
                {
                    return(Task.FromResult(new JimuRemoteCallResultData()
                    {
                        ErrorMsg = $"{jwtAuthorizationContext.Error}, {jwtAuthorizationContext.ErrorDescription}",
                        ErrorCode = "400"
                    }));
                }

                var payload = jwtAuthorizationContext.GetPayload();
                var token   = JWT.Encode(payload, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);

                var result = new ExpandoObject() as IDictionary <string, object>;
                result["access_token"] = token;
                if (_options.ValidateLifetime)
                {
                    result["expired_in"] = payload["exp"];
                }

                return(Task.FromResult(new JimuRemoteCallResultData()
                {
                    Result = result
                }));
            }
            // jwt authentication, alse authentication the role

            if (context.Service != null && context.Service.ServiceDescriptor.EnableAuthorization)
            {
                try
                {
                    var pureToken = context.Token;
                    if (pureToken != null && pureToken.Trim().StartsWith("Bearer "))
                    {
                        pureToken = pureToken.Trim().Substring(6).Trim();
                    }
                    var payload    = JWT.Decode(pureToken, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);
                    var payloadObj = JimuHelper.Deserialize(payload, typeof(IDictionary <string, object>)) as IDictionary <string, object>;
                    if (_options.ValidateLifetime)
                    {
                        //var exp = payloadObj["exp"];
                        if (payloadObj == null || ((Int64)payloadObj["exp"]).ToDate() < DateTime.Now)
                        {
                            var result = new JimuRemoteCallResultData
                            {
                                ErrorMsg  = "Token is Expired",
                                ErrorCode = "401"
                            };
                            return(Task.FromResult(result));
                        }
                    }
                    var serviceRoles = context.Service.ServiceDescriptor.Roles;
                    if (!string.IsNullOrEmpty(serviceRoles))
                    {
                        var serviceRoleArr = serviceRoles.Split(',');
                        var roles          = payloadObj != null && payloadObj.ContainsKey("roles") ? payloadObj["roles"] + "" : "";
                        var authorize      = roles.Split(',').Any(role => serviceRoleArr.Any(x => x.Equals(role, StringComparison.InvariantCultureIgnoreCase)));
                        if (!authorize)
                        {
                            var result = new JimuRemoteCallResultData
                            {
                                ErrorMsg  = "Unauthorized",
                                ErrorCode = "401"
                            };
                            return(Task.FromResult(result));
                        }
                    }
                    context.PayLoad = new JimuPayload {
                        Items = payloadObj
                    };
                }
                catch (Exception ex)
                {
                    var result = new JimuRemoteCallResultData
                    {
                        ErrorMsg  = $"Token is incorrect, exception is { ex.Message}",
                        ErrorCode = "401"
                    };
                    return(Task.FromResult(result));
                }
                return(_next(context));
            }
            // service can be annoymouse request

            return(_next(context));
        }
예제 #9
0
        private MemberDeclarationSyntax GenerateMethodDeclaration(MethodInfo method)
        {
            var serviceId         = JimuHelper.GenerateServiceId(method);
            var returnDeclaration = GetTypeSyntax(method.ReturnType);

            var parameterList            = new List <SyntaxNodeOrToken>();
            var parameterDeclarationList = new List <SyntaxNodeOrToken>();

            foreach (var parameter in method.GetParameters())
            {
                if (parameter.ParameterType.IsGenericType)
                {
                    parameterDeclarationList.Add(SyntaxFactory.Parameter(
                                                     SyntaxFactory.Identifier(parameter.Name))
                                                 .WithType(GetTypeSyntax(parameter.ParameterType)));
                }
                else
                {
                    parameterDeclarationList.Add(SyntaxFactory.Parameter(
                                                     SyntaxFactory.Identifier(parameter.Name))
                                                 .WithType(GetQualifiedNameSyntax(parameter.ParameterType)));
                }
                parameterDeclarationList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken));

                parameterList.Add(SyntaxFactory.InitializerExpression(
                                      SyntaxKind.ComplexElementInitializerExpression,
                                      SyntaxFactory.SeparatedList <ExpressionSyntax>(
                                          new SyntaxNodeOrToken[] {
                    SyntaxFactory.LiteralExpression(
                        SyntaxKind.StringLiteralExpression,
                        SyntaxFactory.Literal(parameter.Name)),
                    SyntaxFactory.Token(SyntaxKind.CommaToken),
                    SyntaxFactory.IdentifierName(parameter.Name)
                })));
                parameterList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken));
            }
            if (parameterList.Any())
            {
                parameterList.RemoveAt(parameterList.Count - 1);
                parameterDeclarationList.RemoveAt(parameterDeclarationList.Count - 1);
            }

            MethodDeclarationSyntax declaration;

            if (method.ReturnType == typeof(void))
            {
                declaration = SyntaxFactory.MethodDeclaration(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)), SyntaxFactory.Identifier(method.Name));
            }
            else
            {
                declaration = SyntaxFactory.MethodDeclaration(
                    returnDeclaration,
                    SyntaxFactory.Identifier(method.Name));
            }

            if (method.ReturnType.Namespace == typeof(Task).Namespace)
            {
                declaration = declaration.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.AsyncKeyword)));
            }
            else
            {
                declaration = declaration.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)));
            }

            declaration = declaration.WithParameterList(SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList <ParameterSyntax>(parameterDeclarationList)));

            ExpressionSyntax expressionSyntax;
            StatementSyntax  statementSyntax;

            if (method.ReturnType.Namespace != typeof(Task).Namespace)
            {
                if (method.ReturnType == typeof(void))
                {
                    expressionSyntax = SyntaxFactory.IdentifierName("InvokeVoid");
                }
                else
                {
                    expressionSyntax = SyntaxFactory.GenericName(
                        SyntaxFactory.Identifier("Invoke"))
                                       //.WithTypeArgumentList(((GenericNameSyntax)returnDeclaration).TypeArgumentList);
                                       .WithTypeArgumentList(SyntaxFactory.TypeArgumentList(SyntaxFactory.SingletonSeparatedList(returnDeclaration)))
                    ;
                }
                expressionSyntax =
                    SyntaxFactory.InvocationExpression(expressionSyntax)
                    .WithArgumentList(
                        SyntaxFactory.ArgumentList(
                            SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                new SyntaxNodeOrToken[]
                                { SyntaxFactory.Argument(
                                      SyntaxFactory.LiteralExpression(
                                          SyntaxKind.StringLiteralExpression,
                                          SyntaxFactory.Literal(serviceId))),
                                  SyntaxFactory.Token(SyntaxKind.CommaToken),
                                  SyntaxFactory.Argument(
                                      SyntaxFactory.ObjectCreationExpression(
                                          SyntaxFactory.GenericName(
                                              SyntaxFactory.Identifier("Dictionary"))
                                          .WithTypeArgumentList(
                                              SyntaxFactory.TypeArgumentList(
                                                  SyntaxFactory.SeparatedList <TypeSyntax>(
                                                      new SyntaxNodeOrToken[]
                    {
                        SyntaxFactory.PredefinedType(
                            SyntaxFactory.Token(SyntaxKind.StringKeyword)),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.PredefinedType(
                            SyntaxFactory.Token(SyntaxKind.ObjectKeyword))
                    }))))
                                      .WithInitializer(
                                          SyntaxFactory.InitializerExpression(
                                              SyntaxKind.CollectionInitializerExpression,
                                              SyntaxFactory.SeparatedList <ExpressionSyntax>(
                                                  parameterList)))) })));
                //expressionSyntax = SyntaxFactory.express
            }
            else
            {
                if (method.ReturnType == typeof(Task))
                {
                    expressionSyntax = SyntaxFactory.IdentifierName("InvokeVoidAsync");
                }
                else
                {
                    expressionSyntax = SyntaxFactory.GenericName(
                        SyntaxFactory.Identifier("InvokeAsync"))
                                       .WithTypeArgumentList(((GenericNameSyntax)returnDeclaration).TypeArgumentList);
                    //.WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(returnDeclaration)))
                }
                expressionSyntax = SyntaxFactory.AwaitExpression(
                    SyntaxFactory.InvocationExpression(expressionSyntax)
                    .WithArgumentList(
                        SyntaxFactory.ArgumentList(
                            SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                new SyntaxNodeOrToken[]
                                { SyntaxFactory.Argument(
                                      SyntaxFactory.LiteralExpression(
                                          SyntaxKind.StringLiteralExpression,
                                          SyntaxFactory.Literal(serviceId))),
                                  SyntaxFactory.Token(SyntaxKind.CommaToken),
                                  SyntaxFactory.Argument(
                                      SyntaxFactory.ObjectCreationExpression(
                                          SyntaxFactory.GenericName(
                                              SyntaxFactory.Identifier("Dictionary"))
                                          .WithTypeArgumentList(
                                              SyntaxFactory.TypeArgumentList(
                                                  SyntaxFactory.SeparatedList <TypeSyntax>(
                                                      new SyntaxNodeOrToken[]
                    {
                        SyntaxFactory.PredefinedType(
                            SyntaxFactory.Token(SyntaxKind.StringKeyword)),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.PredefinedType(
                            SyntaxFactory.Token(SyntaxKind.ObjectKeyword))
                    }))))
                                      .WithInitializer(
                                          SyntaxFactory.InitializerExpression(
                                              SyntaxKind.CollectionInitializerExpression,
                                              SyntaxFactory.SeparatedList <ExpressionSyntax>(
                                                  parameterList)))) }))));
            }

            if (method.ReturnType != typeof(Task) && method.ReturnType != typeof(void))
            {
                statementSyntax = SyntaxFactory.ReturnStatement(expressionSyntax);
            }
            else
            {
                statementSyntax = SyntaxFactory.ExpressionStatement(expressionSyntax);
            }

            declaration = declaration.WithBody(
                SyntaxFactory.Block(
                    SyntaxFactory.SingletonList(statementSyntax)));

            return(declaration);
        }