< Summary

Information
Class: NexusLabs.Needlr.Generators.Export.RegistrationManifestSerializer
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/Export/RegistrationManifestSerializer.cs
Line coverage
96%
Covered lines: 621
Uncovered lines: 23
Coverable lines: 644
Total lines: 966
Line coverage: 96.4%
Branch coverage
74%
Covered branches: 95
Total branches: 127
Branch coverage: 74.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/Export/RegistrationManifestSerializer.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6using NexusLabs.Needlr.Generators.Models;
 7
 8namespace NexusLabs.Needlr.Generators.Export;
 9
 10/// <summary>
 11/// Serializes the normalized source-generated registration plan for compiler tooling.
 12/// </summary>
 13internal static class RegistrationManifestSerializer
 14{
 15    internal const string SchemaVersion = "1.0";
 16
 17    internal static string Serialize(GeneratedRegistrationPlan plan)
 18    {
 1219        var builder = new StringBuilder();
 1220        var discovery = plan.DiscoveryResult;
 1221        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(
 1222            plan.AssemblyName);
 23
 1224        builder.Append('{');
 1225        AppendStringProperty(builder, "schemaVersion", SchemaVersion);
 1226        builder.Append(',');
 1227        AppendStringProperty(builder, "assemblyName", plan.AssemblyName);
 1228        builder.Append(',');
 1229        AppendBooleanProperty(builder, "isAotProject", plan.IsAotProject);
 1230        builder.Append(',');
 1231        AppendServiceCatalogRegistration(
 1232            builder,
 1233            plan.RegistersServiceCatalog,
 1234            safeAssemblyName);
 1235        builder.Append(',');
 1236        AppendStringArrayProperty(
 1237            builder,
 1238            "referencedRegistryAssemblies",
 1239            plan.ReferencedRegistryAssemblies);
 1240        builder.Append(',');
 1241        AppendInjectableTypes(builder, discovery.InjectableTypes);
 1242        builder.Append(',');
 1243        AppendDecorators(builder, discovery.Decorators);
 1244        builder.Append(',');
 1245        AppendHostedServices(builder, discovery.HostedServices);
 1246        builder.Append(',');
 1247        AppendInterceptedServices(
 1248            builder,
 1249            discovery.InterceptedServices,
 1250            safeAssemblyName);
 1251        builder.Append(',');
 1252        AppendFactories(builder, plan.EmittedFactories, safeAssemblyName);
 1253        builder.Append(',');
 1254        AppendProviders(builder, plan.EmittedProviders, safeAssemblyName);
 1255        builder.Append(',');
 1256        AppendOptions(
 1257            builder,
 1258            discovery.Options,
 1259            safeAssemblyName,
 1260            plan.IsAotProject);
 1261        builder.Append(',');
 1262        AppendHttpClients(builder, discovery.HttpClients);
 1263        builder.Append(',');
 1264        AppendComposedRegistrations(
 1265            builder,
 1266            discovery.ComposedRegistrations);
 1267        builder.Append(',');
 1268        AppendPlugins(builder, discovery.PluginTypes);
 1269        builder.Append('}');
 70
 1271        return builder.ToString();
 72    }
 73
 74    private static void AppendServiceCatalogRegistration(
 75        StringBuilder builder,
 76        bool registersServiceCatalog,
 77        string safeAssemblyName)
 78    {
 1279        AppendPropertyName(builder, "serviceCatalogRegistration");
 1280        if (!registersServiceCatalog)
 81        {
 182            builder.Append("null");
 183            return;
 84        }
 85
 1186        builder.Append('{');
 1187        AppendStringProperty(
 1188            builder,
 1189            "serviceType",
 1190            "global::NexusLabs.Needlr.Catalog.IServiceCatalog");
 1191        builder.Append(',');
 1192        AppendStringProperty(
 1193            builder,
 1194            "implementationType",
 1195            $"global::{safeAssemblyName}.Generated.ServiceCatalog");
 1196        builder.Append(',');
 1197        AppendStringProperty(builder, "lifetime", "Singleton");
 1198        builder.Append('}');
 1199    }
 100
 101    private static void AppendInjectableTypes(
 102        StringBuilder builder,
 103        IReadOnlyList<DiscoveredType> injectableTypes)
 104    {
 12105        AppendPropertyName(builder, "injectableTypes");
 12106        builder.Append('[');
 107
 12108        var orderedTypes = injectableTypes
 1108109            .OrderBy(type => type.AssemblyName, StringComparer.Ordinal)
 1108110            .ThenBy(type => type.TypeName, StringComparer.Ordinal)
 12111            .ToArray();
 112
 2250113        for (var index = 0; index < orderedTypes.Length; index++)
 114        {
 1113115            if (index > 0)
 116            {
 1103117                builder.Append(',');
 118            }
 119
 1113120            var type = orderedTypes[index];
 1113121            builder.Append('{');
 1113122            AppendStringProperty(
 1113123                builder,
 1113124                "implementationType",
 1113125                type.TypeName);
 1113126            builder.Append(',');
 1113127            AppendStringProperty(builder, "assemblyName", type.AssemblyName);
 1113128            builder.Append(',');
 1113129            AppendStringProperty(
 1113130                builder,
 1113131                "lifetime",
 1113132                type.Lifetime.ToString());
 1113133            builder.Append(',');
 1113134            AppendServiceTypesProperty(
 1113135                builder,
 1113136                type.TypeName,
 1113137                type.InterfaceNames);
 1113138            builder.Append(',');
 1113139            AppendSortedStringArrayProperty(
 1113140                builder,
 1113141                "serviceKeys",
 1113142                type.ServiceKeys);
 1113143            builder.Append(',');
 1113144            AppendConstructorParameters(
 1113145                builder,
 1113146                "constructorParameters",
 1113147                type.ConstructorParameters);
 1113148            builder.Append('}');
 149        }
 150
 12151        builder.Append(']');
 12152    }
 153
 154    private static void AppendDecorators(
 155        StringBuilder builder,
 156        IReadOnlyList<DiscoveredDecorator> decorators)
 157    {
 12158        AppendPropertyName(builder, "decorators");
 12159        builder.Append('[');
 160
 12161        var orderedDecorators = decorators
 1162            .GroupBy(decorator => decorator.ServiceTypeName)
 1163            .OrderBy(group => group.Key, StringComparer.Ordinal)
 2164            .SelectMany(group => group.OrderBy(decorator => decorator.Order))
 12165            .ToArray();
 166
 26167        for (var index = 0; index < orderedDecorators.Length; index++)
 168        {
 1169            if (index > 0)
 170            {
 0171                builder.Append(',');
 172            }
 173
 1174            var decorator = orderedDecorators[index];
 1175            builder.Append('{');
 1176            AppendStringProperty(
 1177                builder,
 1178                "serviceType",
 1179                decorator.ServiceTypeName);
 1180            builder.Append(',');
 1181            AppendStringProperty(
 1182                builder,
 1183                "decoratorType",
 1184                decorator.DecoratorTypeName);
 1185            builder.Append(',');
 1186            AppendNumberProperty(builder, "order", decorator.Order);
 1187            builder.Append(',');
 1188            AppendStringProperty(
 1189                builder,
 1190                "assemblyName",
 1191                decorator.AssemblyName);
 1192            builder.Append('}');
 193        }
 194
 12195        builder.Append(']');
 12196    }
 197
 198    private static void AppendHostedServices(
 199        StringBuilder builder,
 200        IReadOnlyList<DiscoveredHostedService> hostedServices)
 201    {
 12202        AppendPropertyName(builder, "hostedServices");
 12203        builder.Append('[');
 204
 26205        for (var index = 0; index < hostedServices.Count; index++)
 206        {
 1207            if (index > 0)
 208            {
 0209                builder.Append(',');
 210            }
 211
 1212            var service = hostedServices[index];
 1213            builder.Append('{');
 1214            AppendStringProperty(
 1215                builder,
 1216                "implementationType",
 1217                service.TypeName);
 1218            builder.Append(',');
 1219            AppendStringProperty(
 1220                builder,
 1221                "assemblyName",
 1222                service.AssemblyName);
 1223            builder.Append(',');
 1224            AppendStringProperty(
 1225                builder,
 1226                "lifetime",
 1227                service.Lifetime.ToString());
 1228            builder.Append(',');
 1229            AppendConstructorParameters(
 1230                builder,
 1231                "constructorParameters",
 1232                service.ConstructorParameters);
 1233            builder.Append('}');
 234        }
 235
 12236        builder.Append(']');
 12237    }
 238
 239    private static void AppendInterceptedServices(
 240        StringBuilder builder,
 241        IReadOnlyList<DiscoveredInterceptedService> interceptedServices,
 242        string safeAssemblyName)
 243    {
 12244        AppendPropertyName(builder, "interceptedServices");
 12245        builder.Append('[');
 246
 26247        for (var index = 0; index < interceptedServices.Count; index++)
 248        {
 1249            if (index > 0)
 250            {
 0251                builder.Append(',');
 252            }
 253
 1254            var service = interceptedServices[index];
 1255            builder.Append('{');
 1256            AppendStringProperty(
 1257                builder,
 1258                "implementationType",
 1259                service.TypeName);
 1260            builder.Append(',');
 1261            AppendStringProperty(
 1262                builder,
 1263                "proxyType",
 1264                $"global::{safeAssemblyName}.Generated." +
 1265                    GeneratorHelpers.GetProxyTypeName(service.TypeName));
 1266            builder.Append(',');
 1267            AppendStringProperty(
 1268                builder,
 1269                "assemblyName",
 1270                service.AssemblyName);
 1271            builder.Append(',');
 1272            AppendStringProperty(
 1273                builder,
 1274                "lifetime",
 1275                service.Lifetime.ToString());
 1276            builder.Append(',');
 1277            AppendSortedStringArrayProperty(
 1278                builder,
 1279                "serviceTypes",
 1280                service.InterfaceNames);
 1281            builder.Append(',');
 1282            AppendSortedStringArrayProperty(
 1283                builder,
 1284                "interceptorTypes",
 1285                service.AllInterceptorTypeNames);
 1286            builder.Append('}');
 287        }
 288
 12289        builder.Append(']');
 12290    }
 291
 292    private static void AppendFactories(
 293        StringBuilder builder,
 294        IReadOnlyList<DiscoveredFactory> factories,
 295        string safeAssemblyName)
 296    {
 12297        AppendPropertyName(builder, "factories");
 12298        builder.Append('[');
 299
 26300        for (var index = 0; index < factories.Count; index++)
 301        {
 1302            if (index > 0)
 303            {
 0304                builder.Append(',');
 305            }
 306
 1307            var factory = factories[index];
 1308            builder.Append('{');
 1309            AppendStringProperty(builder, "targetType", factory.TypeName);
 1310            builder.Append(',');
 1311            AppendStringProperty(
 1312                builder,
 1313                "returnType",
 1314                factory.ReturnTypeName);
 1315            builder.Append(',');
 1316            AppendStringProperty(
 1317                builder,
 1318                "assemblyName",
 1319                factory.AssemblyName);
 1320            builder.Append(',');
 1321            AppendBooleanProperty(
 1322                builder,
 1323                "generatesFunc",
 1324                factory.GenerateFunc);
 1325            builder.Append(',');
 1326            AppendBooleanProperty(
 1327                builder,
 1328                "generatesInterface",
 1329                factory.GenerateInterface);
 1330            builder.Append(',');
 1331            AppendNullableStringProperty(
 1332                builder,
 1333                "generatedFactoryServiceType",
 1334                factory.GenerateInterface
 1335                    ? $"global::{safeAssemblyName}.Generated.I" +
 1336                        $"{factory.SimpleTypeName}Factory"
 1337                    : null);
 1338            builder.Append(',');
 1339            AppendNullableStringProperty(
 1340                builder,
 1341                "generatedFactoryImplementationType",
 1342                factory.GenerateInterface
 1343                    ? $"global::{safeAssemblyName}.Generated." +
 1344                        $"{factory.SimpleTypeName}Factory"
 1345                    : null);
 1346            builder.Append(',');
 1347            AppendFactoryConstructors(builder, factory.Constructors);
 1348            builder.Append('}');
 349        }
 350
 12351        builder.Append(']');
 12352    }
 353
 354    private static void AppendFactoryConstructors(
 355        StringBuilder builder,
 356        IReadOnlyList<FactoryDiscoveryHelper.FactoryConstructorInfo> constructors)
 357    {
 1358        AppendPropertyName(builder, "constructors");
 1359        builder.Append('[');
 360
 4361        for (var index = 0; index < constructors.Count; index++)
 362        {
 1363            if (index > 0)
 364            {
 0365                builder.Append(',');
 366            }
 367
 1368            var constructor = constructors[index];
 1369            builder.Append('{');
 1370            AppendConstructorParameters(
 1371                builder,
 1372                "injectableParameters",
 1373                constructor.InjectableParameters);
 1374            builder.Append(',');
 1375            AppendConstructorParameters(
 1376                builder,
 1377                "runtimeParameters",
 1378                constructor.RuntimeParameters);
 1379            builder.Append('}');
 380        }
 381
 1382        builder.Append(']');
 1383    }
 384
 385    private static void AppendProviders(
 386        StringBuilder builder,
 387        IReadOnlyList<DiscoveredProvider> providers,
 388        string safeAssemblyName)
 389    {
 12390        AppendPropertyName(builder, "providers");
 12391        builder.Append('[');
 392
 26393        for (var index = 0; index < providers.Count; index++)
 394        {
 1395            if (index > 0)
 396            {
 0397                builder.Append(',');
 398            }
 399
 1400            var provider = providers[index];
 1401            var providerNamespace =
 1402                GeneratorHelpers.GetNamespaceFromTypeName(provider.TypeName);
 1403            var serviceType = provider.IsInterface
 1404                ? provider.TypeName
 1405                : $"global::{providerNamespace}.{provider.InterfaceTypeName}";
 1406            var implementationType = provider.IsInterface
 1407                ? $"global::{safeAssemblyName}.Generated." +
 1408                    provider.ImplementationTypeName
 1409                : provider.TypeName;
 410
 1411            builder.Append('{');
 1412            AppendStringProperty(builder, "sourceType", provider.TypeName);
 1413            builder.Append(',');
 1414            AppendStringProperty(
 1415                builder,
 1416                "assemblyName",
 1417                provider.AssemblyName);
 1418            builder.Append(',');
 1419            AppendStringProperty(
 1420                builder,
 1421                "mode",
 1422                provider.IsInterface ? "interface" : "shorthand");
 1423            builder.Append(',');
 1424            AppendStringProperty(builder, "serviceType", serviceType);
 1425            builder.Append(',');
 1426            AppendStringProperty(
 1427                builder,
 1428                "implementationType",
 1429                implementationType);
 1430            builder.Append(',');
 1431            AppendProviderProperties(builder, provider.Properties);
 1432            builder.Append('}');
 433        }
 434
 12435        builder.Append(']');
 12436    }
 437
 438    private static void AppendProviderProperties(
 439        StringBuilder builder,
 440        IReadOnlyList<ProviderPropertyInfo> properties)
 441    {
 1442        AppendPropertyName(builder, "properties");
 1443        builder.Append('[');
 444
 4445        for (var index = 0; index < properties.Count; index++)
 446        {
 1447            if (index > 0)
 448            {
 0449                builder.Append(',');
 450            }
 451
 1452            var property = properties[index];
 1453            builder.Append('{');
 1454            AppendStringProperty(builder, "name", property.PropertyName);
 1455            builder.Append(',');
 1456            AppendStringProperty(
 1457                builder,
 1458                "serviceType",
 1459                property.ServiceTypeName);
 1460            builder.Append(',');
 1461            AppendStringProperty(
 1462                builder,
 1463                "resolutionKind",
 1464                property.Kind.ToString());
 1465            builder.Append('}');
 466        }
 467
 1468        builder.Append(']');
 1469    }
 470
 471    private static void AppendOptions(
 472        StringBuilder builder,
 473        IReadOnlyList<DiscoveredOptions> options,
 474        string safeAssemblyName,
 475        bool isAotProject)
 476    {
 12477        AppendPropertyName(builder, "options");
 12478        builder.Append('[');
 479
 28480        for (var index = 0; index < options.Count; index++)
 481        {
 2482            if (index > 0)
 483            {
 0484                builder.Append(',');
 485            }
 486
 2487            var option = options[index];
 2488            var shortTypeName =
 2489                GeneratorHelpers.GetShortTypeName(option.TypeName);
 2490            var registersGeneratedValidator =
 2491                option.ValidateOnStart && option.HasValidatorMethod;
 2492            var registersDataAnnotationsValidator =
 2493                option.HasDataAnnotations &&
 2494                (isAotProject
 2495                    ? !option.RequiresFactoryPattern ||
 2496                        option.ValidateOnStart
 2497                    : option.ValidateOnStart);
 498
 2499            builder.Append('{');
 2500            AppendStringProperty(builder, "optionsType", option.TypeName);
 2501            builder.Append(',');
 2502            AppendStringProperty(
 2503                builder,
 2504                "assemblyName",
 2505                option.AssemblyName);
 2506            builder.Append(',');
 2507            AppendStringProperty(
 2508                builder,
 2509                "sectionName",
 2510                option.SectionName);
 2511            builder.Append(',');
 2512            AppendNullableStringProperty(builder, "name", option.Name);
 2513            builder.Append(',');
 2514            AppendStringProperty(
 2515                builder,
 2516                "bindingMode",
 2517                GetOptionsBindingMode(option, isAotProject));
 2518            builder.Append(',');
 2519            AppendBooleanProperty(
 2520                builder,
 2521                "validateOnStart",
 2522                option.ValidateOnStart);
 2523            builder.Append(',');
 2524            AppendNullableStringProperty(
 2525                builder,
 2526                "generatedValidatorType",
 2527                registersGeneratedValidator
 2528                    ? $"global::{safeAssemblyName}.Generated." +
 2529                        $"{shortTypeName}Validator"
 2530                    : null);
 2531            builder.Append(',');
 2532            AppendNullableStringProperty(
 2533                builder,
 2534                "generatedDataAnnotationsValidatorType",
 2535                registersDataAnnotationsValidator
 2536                    ? $"global::{safeAssemblyName}.Generated." +
 2537                        $"{shortTypeName}DataAnnotationsValidator"
 2538                    : null);
 2539            builder.Append(',');
 2540            AppendNullableStringProperty(
 2541                builder,
 2542                "externalValidatorType",
 2543                registersGeneratedValidator &&
 2544                    option.HasExternalValidator &&
 2545                    option.ValidatorMethod is { IsStatic: false }
 2546                    ? option.ValidatorTypeName
 2547                    : null);
 2548            builder.Append('}');
 549        }
 550
 12551        builder.Append(']');
 12552    }
 553
 554    private static string GetOptionsBindingMode(
 555        DiscoveredOptions options,
 556        bool isAotProject)
 557    {
 2558        if (!isAotProject)
 559        {
 1560            return "reflection";
 561        }
 562
 1563        if (options.IsPositionalRecord)
 564        {
 0565            return "aot-positional-record";
 566        }
 567
 1568        return options.HasInitOnlyProperties
 1569            ? "aot-init-only"
 1570            : "aot-configure";
 571    }
 572
 573    private static void AppendHttpClients(
 574        StringBuilder builder,
 575        IReadOnlyList<DiscoveredHttpClient> httpClients)
 576    {
 12577        AppendPropertyName(builder, "httpClients");
 12578        builder.Append('[');
 579
 26580        for (var index = 0; index < httpClients.Count; index++)
 581        {
 1582            if (index > 0)
 583            {
 0584                builder.Append(',');
 585            }
 586
 1587            var client = httpClients[index];
 1588            builder.Append('{');
 1589            AppendStringProperty(
 1590                builder,
 1591                "optionsType",
 1592                client.TypeName);
 1593            builder.Append(',');
 1594            AppendStringProperty(
 1595                builder,
 1596                "assemblyName",
 1597                client.AssemblyName);
 1598            builder.Append(',');
 1599            AppendStringProperty(
 1600                builder,
 1601                "clientName",
 1602                client.ClientName);
 1603            builder.Append(',');
 1604            AppendStringProperty(
 1605                builder,
 1606                "sectionName",
 1607                client.SectionName);
 1608            builder.Append(',');
 1609            AppendHttpClientCapabilities(builder, client.Capabilities);
 1610            builder.Append('}');
 611        }
 612
 12613        builder.Append(']');
 12614    }
 615
 616    private static void AppendHttpClientCapabilities(
 617        StringBuilder builder,
 618        HttpClientCapabilities capabilities)
 619    {
 1620        AppendPropertyName(builder, "capabilities");
 1621        builder.Append('[');
 622
 1623        var separator = false;
 1624        AppendCapability(
 1625            builder,
 1626            capabilities,
 1627            HttpClientCapabilities.Timeout,
 1628            "Timeout",
 1629            ref separator);
 1630        AppendCapability(
 1631            builder,
 1632            capabilities,
 1633            HttpClientCapabilities.UserAgent,
 1634            "UserAgent",
 1635            ref separator);
 1636        AppendCapability(
 1637            builder,
 1638            capabilities,
 1639            HttpClientCapabilities.BaseAddress,
 1640            "BaseAddress",
 1641            ref separator);
 1642        AppendCapability(
 1643            builder,
 1644            capabilities,
 1645            HttpClientCapabilities.Headers,
 1646            "Headers",
 1647            ref separator);
 648
 1649        builder.Append(']');
 1650    }
 651
 652    private static void AppendCapability(
 653        StringBuilder builder,
 654        HttpClientCapabilities capabilities,
 655        HttpClientCapabilities capability,
 656        string name,
 657        ref bool separator)
 658    {
 4659        if ((capabilities & capability) == 0)
 660        {
 3661            return;
 662        }
 663
 1664        if (separator)
 665        {
 0666            builder.Append(',');
 667        }
 668
 1669        AppendString(builder, name);
 1670        separator = true;
 1671    }
 672
 673    private static void AppendComposedRegistrations(
 674        StringBuilder builder,
 675        IReadOnlyList<DiscoveredComposedRegistration> registrations)
 676    {
 12677        AppendPropertyName(builder, "composedRegistrations");
 12678        builder.Append('[');
 679
 26680        for (var index = 0; index < registrations.Count; index++)
 681        {
 1682            if (index > 0)
 683            {
 0684                builder.Append(',');
 685            }
 686
 1687            var registration = registrations[index];
 1688            builder.Append('{');
 1689            AppendStringProperty(
 1690                builder,
 1691                "serviceType",
 1692                registration.FacadeTypeName);
 1693            builder.Append(',');
 1694            AppendStringProperty(
 1695                builder,
 1696                "implementationType",
 1697                registration.ClosedCompositionTypeName);
 1698            builder.Append(',');
 1699            AppendStringProperty(
 1700                builder,
 1701                "assemblyName",
 1702                registration.AssemblyName);
 1703            builder.Append(',');
 1704            AppendStringProperty(
 1705                builder,
 1706                "lifetime",
 1707                registration.Lifetime.ToString());
 1708            builder.Append(',');
 1709            AppendStringArrayProperty(
 1710                builder,
 1711                "constructorArguments",
 1712                registration.ConstructorArguments);
 1713            builder.Append('}');
 714        }
 715
 12716        builder.Append(']');
 12717    }
 718
 719    private static void AppendPlugins(
 720        StringBuilder builder,
 721        IReadOnlyList<DiscoveredPlugin> plugins)
 722    {
 12723        AppendPropertyName(builder, "plugins");
 12724        builder.Append('[');
 725
 12726        var orderedPlugins = plugins
 8727            .GroupBy(plugin => plugin.AssemblyName)
 5728            .OrderBy(group => group.Key, StringComparer.Ordinal)
 5729            .SelectMany(group => group
 8730                .OrderBy(plugin => plugin.Order)
 13731                .ThenBy(plugin => plugin.TypeName, StringComparer.Ordinal))
 12732            .ToArray();
 733
 40734        for (var index = 0; index < orderedPlugins.Length; index++)
 735        {
 8736            if (index > 0)
 737            {
 3738                builder.Append(',');
 739            }
 740
 8741            var plugin = orderedPlugins[index];
 8742            builder.Append('{');
 8743            AppendStringProperty(builder, "pluginType", plugin.TypeName);
 8744            builder.Append(',');
 8745            AppendStringProperty(
 8746                builder,
 8747                "assemblyName",
 8748                plugin.AssemblyName);
 8749            builder.Append(',');
 8750            AppendNumberProperty(builder, "order", plugin.Order);
 8751            builder.Append(',');
 8752            AppendSortedStringArrayProperty(
 8753                builder,
 8754                "pluginInterfaces",
 8755                plugin.InterfaceNames);
 8756            builder.Append(',');
 8757            AppendSortedStringArrayProperty(
 8758                builder,
 8759                "attributeTypes",
 8760                plugin.AttributeNames);
 8761            builder.Append('}');
 762        }
 763
 12764        builder.Append(']');
 12765    }
 766
 767    private static void AppendServiceTypesProperty(
 768        StringBuilder builder,
 769        string implementationType,
 770        IReadOnlyList<string> interfaceTypes)
 771    {
 1113772        AppendPropertyName(builder, "serviceTypes");
 1113773        builder.Append('[');
 1113774        AppendString(builder, implementationType);
 775
 4438776        foreach (var interfaceType in interfaceTypes.OrderBy(
 1106777            value => value,
 1113778            StringComparer.Ordinal))
 779        {
 1106780            builder.Append(',');
 1106781            AppendString(builder, interfaceType);
 782        }
 783
 1113784        builder.Append(']');
 1113785    }
 786
 787    private static void AppendConstructorParameters(
 788        StringBuilder builder,
 789        string propertyName,
 790        IReadOnlyList<TypeDiscoveryHelper.ConstructorParameterInfo> parameters)
 791    {
 1116792        AppendPropertyName(builder, propertyName);
 1116793        builder.Append('[');
 794
 2240795        for (var index = 0; index < parameters.Count; index++)
 796        {
 4797            if (index > 0)
 798            {
 0799                builder.Append(',');
 800            }
 801
 4802            var parameter = parameters[index];
 4803            builder.Append('{');
 4804            AppendNullableStringProperty(
 4805                builder,
 4806                "name",
 4807                parameter.ParameterName);
 4808            builder.Append(',');
 4809            AppendStringProperty(builder, "type", parameter.TypeName);
 4810            builder.Append(',');
 4811            AppendNullableStringProperty(
 4812                builder,
 4813                "serviceKey",
 4814                parameter.ServiceKey);
 4815            builder.Append('}');
 816        }
 817
 1116818        builder.Append(']');
 1116819    }
 820
 821    private static void AppendStringArrayProperty(
 822        StringBuilder builder,
 823        string propertyName,
 824        IReadOnlyList<string> values)
 825    {
 1144826        AppendPropertyName(builder, propertyName);
 1144827        builder.Append('[');
 828
 2328829        for (var index = 0; index < values.Count; index++)
 830        {
 20831            if (index > 0)
 832            {
 4833                builder.Append(',');
 834            }
 835
 20836            AppendString(builder, values[index]);
 837        }
 838
 1144839        builder.Append(']');
 1144840    }
 841
 842    private static void AppendSortedStringArrayProperty(
 843        StringBuilder builder,
 844        string propertyName,
 845        IEnumerable<string> values)
 846    {
 1131847        AppendStringArrayProperty(
 1131848            builder,
 1131849            propertyName,
 1131850            values.OrderBy(
 7851                value => value,
 1131852                StringComparer.Ordinal)
 1131853                .ToArray());
 1131854    }
 855
 856    private static void AppendStringProperty(
 857        StringBuilder builder,
 858        string propertyName,
 859        string value)
 860    {
 3453861        AppendPropertyName(builder, propertyName);
 3453862        AppendString(builder, value);
 3453863    }
 864
 865    private static void AppendNullableStringProperty(
 866        StringBuilder builder,
 867        string propertyName,
 868        string? value)
 869    {
 18870        AppendPropertyName(builder, propertyName);
 18871        if (value is null)
 872        {
 12873            builder.Append("null");
 12874            return;
 875        }
 876
 6877        AppendString(builder, value);
 6878    }
 879
 880    private static void AppendBooleanProperty(
 881        StringBuilder builder,
 882        string propertyName,
 883        bool value)
 884    {
 16885        AppendPropertyName(builder, propertyName);
 16886        builder.Append(value ? "true" : "false");
 16887    }
 888
 889    private static void AppendNumberProperty(
 890        StringBuilder builder,
 891        string propertyName,
 892        int value)
 893    {
 9894        AppendPropertyName(builder, propertyName);
 9895        builder.Append(GeneratorHelpers.Literal(value));
 9896    }
 897
 898    private static void AppendPropertyName(
 899        StringBuilder builder,
 900        string propertyName)
 901    {
 7004902        AppendString(builder, propertyName);
 7004903        builder.Append(':');
 7004904    }
 905
 906    private static void AppendString(StringBuilder builder, string value)
 907    {
 908        const string Hex = "0123456789abcdef";
 909
 12703910        builder.Append('"');
 459176911        foreach (var character in value)
 912        {
 913            switch (character)
 914            {
 915                case '"':
 1916                    builder.Append("\\\"");
 1917                    break;
 918                case '\\':
 0919                    builder.Append("\\\\");
 0920                    break;
 921                case '\b':
 0922                    builder.Append("\\b");
 0923                    break;
 924                case '\f':
 0925                    builder.Append("\\f");
 0926                    break;
 927                case '\n':
 1928                    builder.Append("\\n");
 1929                    break;
 930                case '\r':
 0931                    builder.Append("\\r");
 0932                    break;
 933                case '\t':
 0934                    builder.Append("\\t");
 0935                    break;
 936                default:
 216883937                    if (character < ' ' ||
 216883938                        char.IsSurrogate(character) ||
 216883939                        character == '\u0085' ||
 216883940                        character == '\u2028' ||
 216883941                        character == '\u2029')
 942                    {
 1943                        AppendUnicodeEscape(builder, character, Hex);
 944                    }
 945                    else
 946                    {
 216882947                        builder.Append(character);
 948                    }
 949                    break;
 950            }
 951        }
 12703952        builder.Append('"');
 12703953    }
 954
 955    private static void AppendUnicodeEscape(
 956        StringBuilder builder,
 957        char character,
 958        string hex)
 959    {
 1960        builder.Append("\\u");
 1961        builder.Append(hex[(character >> 12) & 0x0f]);
 1962        builder.Append(hex[(character >> 8) & 0x0f]);
 1963        builder.Append(hex[(character >> 4) & 0x0f]);
 1964        builder.Append(hex[character & 0x0f]);
 1965    }
 966}

Methods/Properties

Serialize(NexusLabs.Needlr.Generators.Models.GeneratedRegistrationPlan)
AppendServiceCatalogRegistration(System.Text.StringBuilder,System.Boolean,System.String)
AppendInjectableTypes(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredType>)
AppendDecorators(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredDecorator>)
AppendHostedServices(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredHostedService>)
AppendInterceptedServices(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredInterceptedService>,System.String)
AppendFactories(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredFactory>,System.String)
AppendFactoryConstructors(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.FactoryDiscoveryHelper/FactoryConstructorInfo>)
AppendProviders(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredProvider>,System.String)
AppendProviderProperties(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.ProviderPropertyInfo>)
AppendOptions(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredOptions>,System.String,System.Boolean)
GetOptionsBindingMode(NexusLabs.Needlr.Generators.Models.DiscoveredOptions,System.Boolean)
AppendHttpClients(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredHttpClient>)
AppendHttpClientCapabilities(System.Text.StringBuilder,NexusLabs.Needlr.Generators.Models.HttpClientCapabilities)
AppendCapability(System.Text.StringBuilder,NexusLabs.Needlr.Generators.Models.HttpClientCapabilities,NexusLabs.Needlr.Generators.Models.HttpClientCapabilities,System.String,System.Boolean&)
AppendComposedRegistrations(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredComposedRegistration>)
AppendPlugins(System.Text.StringBuilder,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.Models.DiscoveredPlugin>)
AppendServiceTypesProperty(System.Text.StringBuilder,System.String,System.Collections.Generic.IReadOnlyList`1<System.String>)
AppendConstructorParameters(System.Text.StringBuilder,System.String,System.Collections.Generic.IReadOnlyList`1<NexusLabs.Needlr.Generators.TypeDiscoveryHelper/ConstructorParameterInfo>)
AppendStringArrayProperty(System.Text.StringBuilder,System.String,System.Collections.Generic.IReadOnlyList`1<System.String>)
AppendSortedStringArrayProperty(System.Text.StringBuilder,System.String,System.Collections.Generic.IEnumerable`1<System.String>)
AppendStringProperty(System.Text.StringBuilder,System.String,System.String)
AppendNullableStringProperty(System.Text.StringBuilder,System.String,System.String)
AppendBooleanProperty(System.Text.StringBuilder,System.String,System.Boolean)
AppendNumberProperty(System.Text.StringBuilder,System.String,System.Int32)
AppendPropertyName(System.Text.StringBuilder,System.String)
AppendString(System.Text.StringBuilder,System.String)
AppendUnicodeEscape(System.Text.StringBuilder,System.Char,System.String)