public virtual Expression Build(ServiceGateway serviceGateway)
        {
            var methodDefinitions = serviceGateway.Methods.Select(this.Build).ToList();

            var attributes = new Dictionary<string, string>()
            {
                { "Hostname", serviceGateway.Hostname }
            };

            return new TypeDefinitionExpression(new FickleType(serviceGateway.Name), null, methodDefinitions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide), false, new ReadOnlyDictionary<string, string>(attributes), null);
        }
示例#2
0
        protected virtual ServiceGateway ProcessGateway()
        {
            this.ReadNextToken();

            this.Expect(FicklefileToken.Identifier);

            var retval = new ServiceGateway
            {
                Name = this.tokenizer.CurrentIdentifier,
                Methods = new List<ServiceMethod>()
            };

            this.ReadNextToken();
            this.Expect(FicklefileToken.Indent);
            this.ReadNextToken();

            while (true)
            {
                if (this.tokenizer.CurrentToken == FicklefileToken.Identifier)
                {
                    var method = this.ProcessMethod();

                    retval.Methods.Add(method);
                }
                else if (this.tokenizer.CurrentToken == FicklefileToken.Annotation)
                {
                    var annotation = this.ProcessAnnotation();

                    this.SetAnnotation(retval, annotation);
                }
                else
                {
                    break;
                }
            }

            this.Expect(FicklefileToken.Dedent);
            this.ReadNextToken();

            return retval;
        }
        public override ServiceModel Reflect()
        {
            var descriptions = configuration.Services.GetApiExplorer().ApiDescriptions.AsEnumerable()
                .Where(c => !c.ActionDescriptor.GetCustomAttributes<FickleExcludeAttribute>().Any())
                .ToList();

            if (this.options.ControllersTypesToIgnore != null)
            {
                descriptions = descriptions.Where(x => !this.options.ControllersTypesToIgnore.Contains(x.ActionDescriptor.ControllerDescriptor.ControllerType)).ToList();
            }

            bool secureByDefault = false;

            var enums = new List<ServiceEnum>();
            var classes = new List<ServiceClass>();
            var gateways = new List<ServiceGateway>();

            var referencedTypes = GetReferencedTypes(descriptions).ToList();
            var controllers = descriptions.Select(c => c.ActionDescriptor.ControllerDescriptor).ToHashSet();

            var serviceModelInfo = new ServiceModelInfo();

            foreach (var enumType in referencedTypes.Where(c => c.BaseType == typeof(Enum)))
            {
                var serviceEnum = new ServiceEnum
                {
                    Name = GetTypeName(enumType),
                    Values = Enum.GetNames(enumType).Select(c => new ServiceEnumValue { Name = c, Value = Convert.ToInt64(Enum.Parse(enumType, c)) }).ToList()
                };

                enums.Add(serviceEnum);
            }

            foreach (var type in referencedTypes
                .Where(TypeSystem.IsNotPrimitiveType)
                .Where(c => c.BaseType != typeof(Enum))
                .Where(c => !c.IsInterface)
                .Where(c => !typeof(IList<>).IsAssignableFromIgnoreGenericParameters(c)))
            {
                var baseTypeName = GetTypeName(type.BaseType);
                var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
                    .Where(c => !c.GetCustomAttributes<FickleExcludeAttribute>().Any())
                    .Select(c => new ServiceProperty
                    {
                        Name = c.Name,
                        TypeName = GetTypeName(c.PropertyType)
                    }).ToList();

                var serviceClass = new ServiceClass
                {
                    Name = GetTypeName(type),
                    BaseTypeName = baseTypeName,
                    Properties = properties
                };

                classes.Add(serviceClass);
            }

            var allowedMethods = new HashSet<string>(new[] { "GET", "POST" }, StringComparer.InvariantCultureIgnoreCase);

            foreach (var controller in controllers)
            {
                var methods = new List<ServiceMethod>();

                secureByDefault = this.referencingAssembly.GetCustomAttributes<FickleSecureAttribute>()?.FirstOrDefault()?.Secure ?? false;

                var controllerSecureByDefault = controller.GetCustomAttributes<FickleSecureAttribute>(true)?.FirstOrDefault()?.Secure ?? secureByDefault;

                var serviceNameSuffix = "Service";
                var attribute = this.referencingAssembly.GetCustomAttribute<FickleSdkInfoAttribute>();

                if (attribute != null)
                {
                    serviceNameSuffix = attribute.ServiceNameSuffix ?? serviceNameSuffix;
                    serviceModelInfo.Name = attribute.Name ?? serviceModelInfo.Name;
                    serviceModelInfo.Summary = attribute.Summary ?? serviceModelInfo.Summary;
                    serviceModelInfo.Author = attribute.Author ?? serviceModelInfo.Author;
                    serviceModelInfo.Version = attribute.Version ?? serviceModelInfo.Version;
                }

                foreach (var api in descriptions
                    .Where(c => c.ActionDescriptor.ControllerDescriptor == controller &&
                                allowedMethods.Contains(c.HttpMethod.Method)))
                {
                    var formatters = api.ActionDescriptor.ControllerDescriptor.Configuration.Formatters;
                    var returnType = api.ResponseDescription.ResponseType ?? api.ResponseDescription.DeclaredType;

                    if (!formatters.Any(c => c is JsonMediaTypeFormatter))
                    {
                        returnType = typeof(string);
                    }

                    var parameters = api.ParameterDescriptions.Select(d => new ServiceParameter
                    {
                        Name = d.ParameterDescriptor.ParameterName,
                        TypeName = GetTypeName(d.ParameterDescriptor.ParameterType)
                    }).ToList();

                    ServiceParameter contentServiceParameter = null;
                    var contentParameter = api.ParameterDescriptions.SingleOrDefault(c => c.Source == ApiParameterSource.FromBody);

                    var uniqueNameMaker = new UniqueNameMaker(c => api.ParameterDescriptions.Any(d => d.Name.EqualsIgnoreCase(c)));

                    if (contentParameter == null
                        && api.HttpMethod.Method.EqualsIgnoreCaseInvariant("POST")
                        && api.ActionDescriptor.GetCustomAttributes<NoBodyAttribute>().Count == 0)
                    {
                        contentServiceParameter = new ServiceParameter { Name = uniqueNameMaker.Make("content"), TypeName = GetTypeName(typeof(byte[])) };

                        parameters.Add(contentServiceParameter);
                    }
                    else if (contentParameter != null)
                    {
                        contentServiceParameter = new ServiceParameter { Name = contentParameter.Name, TypeName = GetTypeName(contentParameter.ParameterDescriptor.ParameterType) };
                    }

                    var serviceMethod = new ServiceMethod
                    {
                        Authenticated = api.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>(true).Count > 0,
                        Secure = api.ActionDescriptor.GetCustomAttributes<FickleSecureAttribute>(true)?.FirstOrDefault()?.Secure ?? controllerSecureByDefault,
                        Name = api.ActionDescriptor.ActionName,
                        Path = StringUriUtils.Combine(this.configuration.VirtualPathRoot, api.RelativePath),
                        Returns = GetTypeName(returnType),
                        ReturnFormat = "json",
                        Method = api.HttpMethod.Method.ToLower(),
                        Parameters = parameters
                    };

                    if (contentServiceParameter != null)
                    {
                        serviceMethod.Content = contentServiceParameter.Name;
                        serviceMethod.ContentServiceParameter = contentServiceParameter;
                    }

                    methods.Add(serviceMethod);
                }

                var serviceGateway = new ServiceGateway
                {
                    BaseTypeName = null,
                    Name = controller.ControllerName + serviceNameSuffix,
                    Hostname = hostname,
                    Methods = methods
                };

                gateways.Add(serviceGateway);
            }

            return new ServiceModel(serviceModelInfo, enums, classes, gateways);
        }