internal static IServiceCollection AddServicesForFunctionTarget()

in src/Google.Cloud.Functions.Hosting/HostingInternals.cs [160:212]


        internal static IServiceCollection AddServicesForFunctionTarget(IServiceCollection services, Type functionType)
        {
            // Make sure we can determine the actual function type later on.
            services.AddSingleton(new FunctionTypeProvider(functionType));

            if (typeof(IHttpFunction).IsAssignableFrom(functionType))
            {
                services.AddScoped(typeof(IHttpFunction), functionType);
            }
            else if (typeof(ICloudEventFunction).IsAssignableFrom(functionType))
            {
                services
                    .AddScoped<IHttpFunction, CloudEventAdapter>()
                    .AddSingleton<CloudEventFormatter>(new JsonEventFormatter())
                    .AddScoped(typeof(ICloudEventFunction), functionType);
            }
            else if (GetGenericInterfaceImplementationTypeArguments(functionType, typeof(ITypedFunction<,>)) is Type[] signatureTypes)
            {
                Type requestType = signatureTypes[0];
                Type responseType = signatureTypes[1];

                services
                    .AddScoped(typeof(IHttpFunction), typeof(TypedFunctionAdapter<,>).MakeGenericType(signatureTypes))
                    .AddScoped(typeof(ITypedFunction<,>).MakeGenericType(signatureTypes), functionType);

                // Provide JSON reader/writer implementations using System.Text.Json by default.
                // If the user provides a reader (or writer) in the startup class, that will take priority.
                Type jsonReaderType = typeof(JsonHttpRequestReader<>).MakeGenericType(requestType);
                Type jsonWriterType = typeof(JsonHttpResponseWriter<>).MakeGenericType(responseType);
                services.AddSingleton(typeof(IHttpRequestReader<>).MakeGenericType(requestType), jsonReaderType);
                services.AddSingleton(typeof(IHttpResponseWriter<>).MakeGenericType(responseType), jsonWriterType);
            }
            else if (GetGenericInterfaceImplementationTypeArgument(functionType, typeof(ICloudEventFunction<>)) is Type payloadType)
            {
                services
                    .AddScoped(typeof(IHttpFunction), typeof(CloudEventAdapter<>).MakeGenericType(payloadType))
                    .AddScoped(typeof(ICloudEventFunction<>).MakeGenericType(payloadType), functionType);

                var formatter = CloudEventFormatterAttribute.CreateFormatter(payloadType);
                // Only add the formatter here if we have one. Even if we have one, it can be overridden by a function
                // startup class adding its own. If no formatter is available, CloudEventAdapter<TData> will fail
                // with a helpful error message in the constructor.
                if (formatter is not null)
                {
                    services.AddSingleton(formatter);
                }
            }
            else
            {
                throw new InvalidOperationException($"Function type '{functionType.FullName}' doesn't support any known function interfaces.");
            }
            return services;
        }