public ConfigureFubuMVC()
        {
            // This line turns on the basic diagnostics and request tracing
            IncludeDiagnostics(true);

            Actions
                .IncludeTypesNamed(x => x.EndsWith("Projection"))
                .IncludeTypesNamed(x => x.EndsWith("CommandHandler"));

            var httpVerbs = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase) { "GET", "POST", "DELETE", "PUT" };
            httpVerbs.Each(verb => Routes.ConstrainToHttpMethod(action => action.Method.Name.Equals(verb, StringComparison.InvariantCultureIgnoreCase), verb));
            httpVerbs.Each(verb => Routes.IgnoreMethodsNamed(verb));

            Routes
                .IgnoreMethodSuffix("Html")
                .RootAtAssemblyNamespace()
                .UrlPolicy<ProjectionUrlPolicy>()
                .UrlPolicy<CommandHandlerUrlPolicy>()
                .HomeIs<CreateFormProjection>(x => x.Get());

            this.UseRazor();

            // Match views to action methods by matching
            // on model type, view name, and namespace
            Views.TryToAttachWithDefaultConventions();
        }
        public PolyphonyFubuRegistry()
        {
            IncludeDiagnostics(true);

            Applies
                .ToThisAssembly();

            var httpVerbs = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase) { "GET", "POST", "PUT", "HEAD" };

            Actions
                .IncludeTypes(t => t.Namespace.StartsWith(typeof (EndpointUrlPolicy).Namespace) && t.Name.EndsWith("Endpoint"))
                .IncludeMethods(action => httpVerbs.Contains(action.Method.Name));

            httpVerbs
                .Each(verb => Routes.ConstrainToHttpMethod(action => action.Method.Name.Equals(verb, StringComparison.InvariantCultureIgnoreCase), verb));

            Views
                .TryToAttach(findViews => findViews.by_ViewModel());

            Routes
                .UrlPolicy<EndpointUrlPolicy>();

            Output
                .ToJson
                .WhenCallMatches(c => c.OutputType().Name.StartsWith("Ajax"));

            this.UseDefaultHtmlConventions();
        }
        public SimpleWebsiteFubuRegistry()
        {
            IncludeDiagnostics(true);

            Applies.ToThisAssembly();

            var httpVerbs = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
                {"GET", "POST", "PUT", "HEAD"};

            Actions
                .IncludeTypes(t => t.Namespace.StartsWith(typeof(EndPointUrlPolicy).Namespace) && t.Name.EndsWith("Endpoint"))
                .IncludeMethods(action => httpVerbs.Contains(action.Method.Name));

            httpVerbs.Each(verb => Routes.ConstrainToHttpMethod(action => action.Method.Name.Equals(verb, StringComparison.InvariantCultureIgnoreCase), verb));

            Routes.UrlPolicy<EndPointUrlPolicy>();

            Output.ToJson.WhenCallMatches(action => action.Returns<AjaxResponse>());

            Views.TryToAttach(findViews => findViews.by_ViewModel_and_Namespace());

            // Note: Outside of a sample application, you would only configure services that Fubu requires within your FubuRegistry
            // Non-Fubu services should be configured through your container in the usual way (StructureMap Registry, etc)
            Services(s => s.AddService<IRepository, FakeRepository>());
        }
Example #4
0
        public CoolCodeFubuRegistry()
        {
            IncludeDiagnostics(true);

            Applies.ToThisAssembly();

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

            Actions
                .IncludeTypes(t =>
                                    !string.IsNullOrEmpty(t.Namespace) &&
                                    t.Namespace.StartsWith(typeof(EndpointMarker).Namespace) &&
                                    t.Name.EndsWith(EndpointUrlPolicy.EndpointString)
                              )
                .IncludeMethods(a => httpVerbs.Contains(a.Method.Name));

            httpVerbs
               .Each(verb => Routes.ConstrainToHttpMethod(action => action.Method.Name.Equals(verb, StringComparison.InvariantCultureIgnoreCase), verb));

            Views.TryToAttach(findViews => findViews.by_ViewModel_and_Namespace());

            Routes
                .UrlPolicy<EndpointUrlPolicy>();

            HtmlConvention<CoolCodeHtmlConventions>();
        }
        public ConfigureFubuMVC()
        {
            var httpVerbs = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase){"GET", "POST", "PUT", "HEAD"};

            Applies.ToThisAssembly().ToAllPackageAssemblies();

            // This line turns on the basic diagnostics and request tracing
            IncludeDiagnostics(true);

            // All public methods from concrete classes ending in "Action"
            // in this assembly are assumed to be action methods
            Actions
                .IncludeTypes(t => t.Namespace.StartsWith(typeof(ActionUrlPolicy).Namespace) && t.Name.EndsWith("Action"))
                .IncludeMethods(action => httpVerbs.Contains(action.Method.Name));

            httpVerbs.Each(verb => Routes.ConstrainToHttpMethod(action =>
                action.Method.Name.EqualsIgnoreCase(verb), verb));

            // Policies
            Routes
                .HomeIs<HomeAction>(x => x.Get())
                .IgnoreControllerNamesEntirely()
                .IgnoreMethodSuffix("Html")
                .RootAtAssemblyNamespace()
                .UrlPolicy<ActionUrlPolicy>();

            // Match views to action methods by matching
            // on model type, view name, and namespace
            Views.TryToAttachWithDefaultConventions();
            Import<WebFormsEngine>();
        }
Example #6
0
        public HelloWorldFubuRegistry()
        {
            IncludeDiagnostics(true);

            Applies
                .ToThisAssembly();

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

            Actions
                .IncludeTypes(t => t.Namespace.StartsWith(typeof (EndpointMarker).Namespace) && t.Name.EndsWith("Endpoint"))
                .IncludeMethods(action => httpVerbs.Contains(action.Method.Name))
                .FindWith<FindActionsSource>();

            httpVerbs
                .Each(verb => Routes.ConstrainToHttpMethod(action => action.Method.Name.Equals(verb, StringComparison.InvariantCultureIgnoreCase), verb));

            Views
                .TryToAttach(findViews => findViews.by_ViewModel());

            ApplyConvention<CrudErrorWrapperConvention>();
            ApplyConvention<CrudValidationConvention>();

            Routes
                .UrlPolicy<EndpointUrlPolicy>();

            Models
                .BindModelsWith<ComplexJsonBinder>();

            Services(r => r.SetServiceIfNone<IJsonService>(new JsonService()));

            Output
                .ToJson
                .WhenCallMatches(c => c.OutputType().Name.StartsWith("Ajax"));

            this.HtmlConvention(new HelloWorldHtmlConventions(Validator.ValidationGraph));
        }
Example #7
0
        private List<ITypeWriter> WriteMethods(StringBuilder sb)
        {
            List<ITypeWriter> extendedTypes = new List<ITypeWriter>();
            var methodSignatures = new HashSet<string>();
            foreach (var method in TypeDefinition.Methods)
            {
                var methodSb = new StringBuilder();

                var methodName = method.Name;

                // ignore special event handler methods
                if (method.HasParameters &&
                    method.Parameters[0].Name.StartsWith("__param0") &&
                    (methodName.StartsWith("add_") || methodName.StartsWith("remove_")))
                    continue;

                if (method.IsSpecialName && !method.IsConstructor)
                    continue;

                // already handled properties
                if (method.IsGetter || method.IsSetter)
                    continue;

                // translate the constructor function
                if (method.IsConstructor)
                {
                    methodName = "constructor";
                }

                // Lowercase first char of the method
                methodName = methodName.ToTypeScriptName();

                Indent(methodSb); Indent(methodSb);
                if (method.IsStatic)
                {
                    methodSb.Append("static ");
                }
                methodSb.Append(methodName);

                var outTypes = new List<ParameterDefinition>();

                methodSb.Append("(");
                method.Parameters.Where(w => w.IsOut).Each(e => outTypes.Add(e));
                method.Parameters.Where(w => !w.IsOut).For((parameter, i, isLast) =>
                {
                    methodSb.AppendFormat("{0}{1}: {2}{3}",
                        (i == 0 ? "" : " "),                            // spacer
                        parameter.Name,                                 // argument name
                        parameter.ParameterType.ToTypeScriptType(),     // type
                        (isLast ? "" : ","));                           // last one gets a comma
                });
                methodSb.Append(")");

                // constructors don't have return types.
                if (!method.IsConstructor)
                {
                    string returnType;
                    if (outTypes.Any())
                    {
                        var outWriter = new OutParameterReturnTypeWriter(Config, IndentCount, TypeDefinition, methodName, method.ReturnType, outTypes);
                        extendedTypes.Add(outWriter);
                        //TypeCollection.Add(TypeDefinition.Namespace, outWriter.TypeName, outWriter);
                        returnType = outWriter.TypeName;
                    }
                    else
                    {
                        returnType = method.ReturnType.ToTypeScriptType();
                    }

                    methodSb.AppendFormat(": {0}", returnType);
                }
                methodSb.AppendLine(";");

                var renderedMethod = methodSb.ToString();
                if (!methodSignatures.Contains(renderedMethod))
                    methodSignatures.Add(renderedMethod);
            }

            // HACK: This not a sustainable approach (but working for now)
            //       The IWebSocket inherits from IClosable and the websocket's close 
            //       conflicts with the closable close so we have to hack this method
            //       onto the websocket interface.
            if (TypeDefinition.FullName == "Windows.Networking.Sockets.IWebSocket")
            {
                methodSignatures.Add(IndentValue + IndentValue + "close(): void;" + Environment.NewLine);
            }

            methodSignatures.Each(method => sb.Append(method));

            return extendedTypes;
        }
Example #8
0
        private List<ITypeWriter> WriteMethods(StringBuilder sb)
        {
            List<ITypeWriter> extendedTypes = new List<ITypeWriter>();
            var methodSignatures = new HashSet<string>();
            foreach (var method in TypeDefinition.Methods)
            {
                var methodSb = new StringBuilder();

                var methodName = method.Name;

                // ignore special event handler methods
                if (method.HasParameters &&
                    method.Parameters[0].Name.StartsWith("__param0") &&
                    (methodName.StartsWith("add_") || methodName.StartsWith("remove_")))
                    continue;

                // already handled properties
                if (method.IsGetter || method.IsSetter)
                    continue;

                // translate the constructor function
                if (method.IsConstructor)
                {
                    continue;
                }

                // Lowercase first char of the method
                methodName = methodName.ToTypeScriptName();

                Indent(methodSb); Indent(methodSb);
                if (method.IsStatic)
                {
                    methodSb.Append("static ");
                }
                methodSb.Append(methodName);

                var outTypes = new List<ParameterDefinition>();

                methodSb.Append("(");
                method.Parameters.Where(w => w.IsOut).Each(e => outTypes.Add(e));
                method.Parameters.Where(w => !w.IsOut).For((parameter, i, isLast) =>
                {
                    methodSb.AppendFormat("{0}{1}: {2}{3}",
                        (i == 0 ? "" : " "),                            // spacer
                        parameter.Name,                                 // argument name
                        parameter.ParameterType.ToTypeScriptType(),     // type
                        (isLast ? "" : ","));                           // last one gets a comma
                });
                methodSb.Append(")");

                // constructors don't have return types.
                if (!method.IsConstructor)
                {
                    string returnType;
                    if (outTypes.Any())
                    {
                        var outWriter = new OutParameterReturnTypeWriter(Config, IndentCount, TypeDefinition, methodName, method.ReturnType, outTypes);
                        extendedTypes.Add(outWriter);
                        returnType = outWriter.TypeName;
                    }
                    else
                    {
                        returnType = method.ReturnType.ToTypeScriptType();
                    }

                    methodSb.AppendFormat(": {0}", returnType);
                }
                methodSb.AppendLine(";");

                var renderedMethod = methodSb.ToString();
                if (!methodSignatures.Contains(renderedMethod))
                    methodSignatures.Add(renderedMethod);
            }

            methodSignatures.Each(method => sb.Append(method));

            return extendedTypes;
        }
Example #9
0
        public string GetCode(MetadataTypes metadata)
        {
            var namespaces = new HashSet<string>();
            Config.DefaultNamespaces.Each(x => namespaces.Add(x));
            metadata.Types.Each(x => namespaces.Add(x.Namespace));
            metadata.Operations.Each(x => namespaces.Add(x.Request.Namespace));

            var sb = new StringBuilderWrapper(new StringBuilder());
            sb.AppendLine("/* Options:");
            sb.AppendLine("Version: {0}".Fmt(Version));
            sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl));
            sb.AppendLine();
            sb.AppendLine("ServerVersion: {0}".Fmt(metadata.Version));
            sb.AppendLine("MakePartial: {0}".Fmt(Config.MakePartial));
            sb.AppendLine("MakeVirtual: {0}".Fmt(Config.MakeVirtual));
            sb.AppendLine("MakeDataContractsExtensible: {0}".Fmt(Config.MakeDataContractsExtensible));
            sb.AppendLine("AddReturnMarker: {0}".Fmt(Config.AddReturnMarker));
            sb.AppendLine("AddDescriptionAsComments: {0}".Fmt(Config.AddDescriptionAsComments));
            sb.AppendLine("AddDataContractAttributes: {0}".Fmt(Config.AddDataContractAttributes));
            sb.AppendLine("AddDataAnnotationAttributes: {0}".Fmt(Config.AddDataAnnotationAttributes));
            sb.AppendLine("AddDefaultXmlNamespace: {0}".Fmt(Config.AddDefaultXmlNamespace));
            sb.AppendLine("AddIndexesToDataMembers: {0}".Fmt(Config.AddIndexesToDataMembers));
            sb.AppendLine("AddResponseStatus: {0}".Fmt(Config.AddResponseStatus));
            sb.AppendLine("AddImplicitVersion: {0}".Fmt(Config.AddImplicitVersion));
            sb.AppendLine("InitializeCollections: {0}".Fmt(Config.InitializeCollections));
            sb.AppendLine("DefaultNamespaces: {0}".Fmt(Config.DefaultNamespaces.ToArray().Join(", ")));
            sb.AppendLine("*/");
            sb.AppendLine();

            namespaces.Each(x => sb.AppendLine("using {0};".Fmt(x)));

            if (Config.AddDataContractAttributes
                && Config.AddDefaultXmlNamespace != null)
            {
                sb.AppendLine();

                namespaces.Where(x => !Config.DefaultNamespaces.Contains(x)).ToList()
                    .ForEach(x =>
                        sb.AppendLine("[assembly: ContractNamespace(\"{0}\", ClrNamespace=\"{1}\")]"
                            .Fmt(Config.AddDefaultXmlNamespace, x)));
            }

            sb.AppendLine();

            string lastNS = null;

            sb.AppendLine("#region Operations");
            sb.AppendLine();
            foreach (var operation in metadata.Operations
                .OrderBy(x => x.Request.Namespace)
                .OrderBy(x => x.Request.Name))
            {
                var request = operation.Request;
                var response = operation.Response;
                lastNS = AppendType(ref sb, request, lastNS,
                    new CreateTypeOptions {
                        ImplementsFn = () => {
                            if (!Config.AddReturnMarker
                                && !request.ReturnVoidMarker
                                && request.ReturnMarkerTypeName == null)
                                return null;

                            if (request.ReturnVoidMarker)
                                return "IReturnVoid";
                            if (request.ReturnMarkerTypeName != null)
                                return Type("IReturn`1", new[] { Type(request.ReturnMarkerTypeName) });
                            return response != null
                                ? Type("IReturn`1", new[] { Type(response.Name, response.GenericArgs) })
                                : null;
                        },
                        IsRequest = true,
                    });
                lastNS = AppendType(ref sb, operation.Response, lastNS,
                    new CreateTypeOptions {
                        IsResponse = true,
                    });
            }
            if (lastNS != null)
                sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("#endregion");

            sb.AppendLine();
            sb.AppendLine();

            lastNS = null;
            sb.AppendLine("#region Types");
            sb.AppendLine();
            foreach (var type in metadata.Types
                .OrderBy(x => x.Namespace)
                .ThenBy(x => x.Name))
            {
                lastNS = AppendType(ref sb, type, lastNS,
                    new CreateTypeOptions { IsType = true });
            }
            if (lastNS != null)
                sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("#endregion");

            return sb.ToString();
        }
Example #10
0
        public string GetCode(MetadataTypes metadata)
        {
            var namespaces = new HashSet<string>();
            Config.DefaultNamespaces.Each(x => namespaces.Add(x));
            metadata.Types.Each(x => namespaces.Add(x.Namespace));
            metadata.Operations.Each(x => namespaces.Add(x.Request.Namespace));

            var sb = new StringBuilderWrapper(new StringBuilder());
            sb.AppendLine("/* Options:");
            sb.AppendLine("Version: {0}".Fmt(Version));
            sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl));
            sb.AppendLine();
            sb.AppendLine("ServerVersion: {0}".Fmt(metadata.Version));
            sb.AppendLine("MakePartial: {0}".Fmt(Config.MakePartial));
            sb.AppendLine("MakeVirtual: {0}".Fmt(Config.MakeVirtual));
            sb.AppendLine("MakeDataContractsExtensible: {0}".Fmt(Config.MakeDataContractsExtensible));
            sb.AppendLine("AddReturnMarker: {0}".Fmt(Config.AddReturnMarker));
            sb.AppendLine("AddDescriptionAsComments: {0}".Fmt(Config.AddDescriptionAsComments));
            sb.AppendLine("AddDataContractAttributes: {0}".Fmt(Config.AddDataContractAttributes));
            sb.AppendLine("AddDataAnnotationAttributes: {0}".Fmt(Config.AddDataAnnotationAttributes));
            sb.AppendLine("AddIndexesToDataMembers: {0}".Fmt(Config.AddIndexesToDataMembers));
            sb.AppendLine("AddResponseStatus: {0}".Fmt(Config.AddResponseStatus));
            sb.AppendLine("AddImplicitVersion: {0}".Fmt(Config.AddImplicitVersion));
            sb.AppendLine("InitializeCollections: {0}".Fmt(Config.InitializeCollections));
            sb.AppendLine("AddDefaultXmlNamespace: {0}".Fmt(Config.AddDefaultXmlNamespace));
            //sb.AppendLine("DefaultNamespaces: {0}".Fmt(Config.DefaultNamespaces.ToArray().Join(", ")));
            sb.AppendLine("*/");
            sb.AppendLine();

            namespaces.Each(x => sb.AppendLine("using {0};".Fmt(x)));

            if (Config.AddDataContractAttributes
                && Config.AddDefaultXmlNamespace != null)
            {
                sb.AppendLine();

                namespaces.Where(x => !Config.DefaultNamespaces.Contains(x)).ToList()
                    .ForEach(x =>
                        sb.AppendLine("[assembly: ContractNamespace(\"{0}\", ClrNamespace=\"{1}\")]"
                            .Fmt(Config.AddDefaultXmlNamespace, x)));
            }

            sb.AppendLine();

            string lastNS = null;

            var existingOps = new HashSet<string>();

            var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet();
            var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request);
            var responseTypes = metadata.Operations
                .Where(x => x.Response != null)
                .Select(x => x.Response).ToHashSet();
            var types = metadata.Types.ToHashSet();

            var allTypes = new List<MetadataType>();
            allTypes.AddRange(requestTypes);
            allTypes.AddRange(responseTypes);
            allTypes.AddRange(types);
            var orderedTypes = allTypes
                .OrderBy(x => x.Namespace)
                .ThenBy(x => x.Name);

            foreach (var type in orderedTypes)
            {
                var fullTypeName = type.GetFullName();
                if (requestTypes.Contains(type))
                {
                    if (!existingOps.Contains(fullTypeName))
                    {
                        MetadataType response = null;
                        MetadataOperationType operation;
                        if (requestTypesMap.TryGetValue(type, out operation))
                        {
                            response = operation.Response;
                        }

                        lastNS = AppendType(ref sb, type, lastNS,
                            new CreateTypeOptions
                            {
                                ImplementsFn = () =>
                                {
                                    if (!Config.AddReturnMarker
                                        && !type.ReturnVoidMarker
                                        && type.ReturnMarkerTypeName == null)
                                        return null;

                                    if (type.ReturnVoidMarker)
                                        return "IReturnVoid";
                                    if (type.ReturnMarkerTypeName != null)
                                        return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) });
                                    return response != null
                                        ? Type("IReturn`1", new[] { Type(type.Name, type.GenericArgs) })
                                        : null;
                                },
                                IsRequest = true,
                            });

                        existingOps.Add(fullTypeName);
                    }
                }
                else if (responseTypes.Contains(type))
                {
                    if (!existingOps.Contains(fullTypeName)
                        && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace))
                    {
                        lastNS = AppendType(ref sb, type, lastNS,
                            new CreateTypeOptions
                            {
                                IsResponse = true,
                            });

                        existingOps.Add(fullTypeName);
                    }
                }
                else if (types.Contains(type) && !existingOps.Contains(fullTypeName))
                {
                    lastNS = AppendType(ref sb, type, lastNS,
                        new CreateTypeOptions { IsType = true });
                }
            }

            if (lastNS != null)
                sb.AppendLine("}");
            sb.AppendLine();

            return sb.ToString();
        }
Example #11
0
        public virtual void EnqueueEmailToBeSent(string fromAddress, HashSet<Recipient> recipients, string subject)
        {
            Guard.Hope(State.CanSend, "cannot enqeue email in the current state: " + State.Name);
            Guard.Hope(_emailRecipients.Count == 0, "recipients must be empty");
            State = EmailState.ToBeSent;
            FromAddress = fromAddress;
            Subject = subject;

            recipients.Each(r => _emailRecipients.Add(new EmailRecipient(this, r)));

            DomainEvents.RaiseEvent(new EmailEnqueuedToBeSentEvent
                                        {
                                            EmailId = Id
                                        });
        }
 /// <summary>Validates the properties.</summary>
 /// <returns></returns>
 public bool ValidateProperties()
 {
     var propertyNames = new HashSet<string>();
     _validatableEntity
         .GetType()
         .GetRuntimeProperties().Where(x => x.GetCustomAttributes<ValidationAttribute>().Any())
         .ToArray()
         .Each(propertyInfo =>
         {
             var propertyErrors = new List<string>();
             TryValidateProperty(propertyInfo, propertyErrors);
             var errorsChanged = SetPropertyErrors(propertyInfo.Name, propertyErrors);
             if (errorsChanged)
                 propertyNames.Add(propertyInfo.Name);
         });
     propertyNames.Each(RaiseHandlers);
     return !_errors.Values.Any();
 }
        public string GetCode(MetadataTypes metadata, IRequest request)
        {
            var namespaces = new HashSet<string>();
            Config.DefaultNamespaces.Each(x => namespaces.Add(x));
            metadata.Types.Each(x => namespaces.Add(x.Namespace));
            metadata.Operations.Each(x => namespaces.Add(x.Request.Namespace));

            Func<string, string> defaultValue = k =>
                request.QueryString[k].IsNullOrEmpty() ? "'''" : "'";

            var sb = new StringBuilderWrapper(new StringBuilder());
            sb.AppendLine("' Options:");
            sb.AppendLine("'Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T", " ")));
            sb.AppendLine("'Version: {0}".Fmt(metadata.Version));
            sb.AppendLine("'BaseUrl: {0}".Fmt(Config.BaseUrl));
            sb.AppendLine("'");
            sb.AppendLine("{0}MakePartial: {1}".Fmt(defaultValue("MakePartial"), Config.MakePartial));
            sb.AppendLine("{0}MakeVirtual: {1}".Fmt(defaultValue("MakeVirtual"), Config.MakeVirtual));
            sb.AppendLine("{0}MakeDataContractsExtensible: {1}".Fmt(defaultValue("MakeDataContractsExtensible"), Config.MakeDataContractsExtensible));
            sb.AppendLine("{0}AddReturnMarker: {1}".Fmt(defaultValue("AddReturnMarker"), Config.AddReturnMarker));
            sb.AppendLine("{0}AddDescriptionAsComments: {1}".Fmt(defaultValue("AddDescriptionAsComments"), Config.AddDescriptionAsComments));
            sb.AppendLine("{0}AddDataContractAttributes: {1}".Fmt(defaultValue("AddDataContractAttributes"), Config.AddDataContractAttributes));
            sb.AppendLine("{0}AddIndexesToDataMembers: {1}".Fmt(defaultValue("AddIndexesToDataMembers"), Config.AddIndexesToDataMembers));
            sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus));
            sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion));
            sb.AppendLine("{0}InitializeCollections: {1}".Fmt(defaultValue("InitializeCollections"), Config.InitializeCollections));
            sb.AppendLine("{0}AddDefaultXmlNamespace: {1}".Fmt(defaultValue("AddDefaultXmlNamespace"), Config.AddDefaultXmlNamespace));
            //sb.AppendLine("{0}DefaultNamespaces: {1}".Fmt(defaultValue("DefaultNamespaces"), Config.DefaultNamespaces.ToArray().Join(", ")));
            sb.AppendLine();

            namespaces.Each(x => sb.AppendLine("Imports {0}".Fmt(x)));

            if (Config.AddDataContractAttributes
                && Config.AddDefaultXmlNamespace != null)
            {
                sb.AppendLine();

                namespaces.Where(x => !Config.DefaultNamespaces.Contains(x)).ToList()
                    .ForEach(x =>
                        sb.AppendLine("<Assembly: ContractNamespace(\"{0}\", ClrNamespace:=\"{1}\")>"
                            .Fmt(Config.AddDefaultXmlNamespace, x)));
            }

            sb.AppendLine();

            sb.AppendLine("Namespace Global");
            sb = sb.Indent();

            string lastNS = null;

            var existingOps = new HashSet<string>();

            var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet();
            var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request);
            var responseTypes = metadata.Operations
                .Where(x => x.Response != null)
                .Select(x => x.Response).ToHashSet();
            var types = metadata.Types.ToHashSet();

            var allTypes = new List<MetadataType>();
            allTypes.AddRange(requestTypes);
            allTypes.AddRange(responseTypes);
            allTypes.AddRange(types);
            var orderedTypes = allTypes
                .OrderBy(x => x.Namespace)
                .ThenBy(x => x.Name);

            foreach (var type in orderedTypes)
            {
                var fullTypeName = type.GetFullName();
                if (requestTypes.Contains(type))
                {
                    if (!existingOps.Contains(fullTypeName))
                    {
                        MetadataType response = null;
                        MetadataOperationType operation;
                        if (requestTypesMap.TryGetValue(type, out operation))
                        {
                            response = operation.Response;
                        }

                        lastNS = AppendType(ref sb, type, lastNS, allTypes,
                            new CreateTypeOptions
                            {
                                ImplementsFn = () =>
                                {
                                    if (!Config.AddReturnMarker
                                        && !type.ReturnVoidMarker
                                        && type.ReturnMarkerTypeName == null)
                                        return null;

                                    if (type.ReturnVoidMarker)
                                        return "IReturnVoid";
                                    if (type.ReturnMarkerTypeName != null)
                                        return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) });
                                    return response != null
                                                ? Type("IReturn`1", new[] { Type(type.Name, type.GenericArgs) })
                                                : null;
                                },
                                IsRequest = true,
                            });

                        existingOps.Add(fullTypeName);
                    }
                }
                else if (responseTypes.Contains(type))
                {
                    if (!existingOps.Contains(fullTypeName)
                        && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace))
                    {
                        lastNS = AppendType(ref sb, type, lastNS, allTypes,
                            new CreateTypeOptions { IsResponse = true, });

                        existingOps.Add(fullTypeName);
                    }
                }
                else if (types.Contains(type) && !existingOps.Contains(fullTypeName))
                {
                    lastNS = AppendType(ref sb, type, lastNS, allTypes,
                        new CreateTypeOptions { IsType = true });
                }
            }

            if (lastNS != null)
                sb.AppendLine("End Namespace");

            sb = sb.UnIndent();
            sb.AppendLine("End Namespace");

            sb.AppendLine();

            return sb.ToString();
        }