IServiceCollection に対する拡張メソッド一覧


### このドキュメントの内容

Microsoft.Extensions.DependencyInjection / Hosting / Logging / Options で提供されている IServiceCollection に対する拡張メソッドをまとめます。

### Microsoft.Extensions.DependencyInjection.Abstractions

|メソッド|説明|
|:--|:--|
|AddScoped|指定された型をスコープサービスとして追加します。DIで注入したい型を追加するときに使用します。注入されるインスタンスはスコープ内で共有されます。|
|AddSingleton|指定された型またはオブジェクトをシングルトンサービスとして追加します。DIで注入したい型を追加するときに使用します。注入されるインスタンスはアプリケーション内で共有されます。|
|AddTransient|指定された型をサービスとして追加します。DIで注入したい型を追加するときに使用します。注入するたびにインスタンスが生成されます。|

```c#:Microsoft.Extensions.DependencyInjection.Abstractions
namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollectionServiceExtensions
    {
        public static IServiceCollection AddScoped<TService>(
            this IServiceCollection services
        ) where TService : class;

        public static IServiceCollection AddScoped(
            this IServiceCollection services,
            Type serviceType,
            Type implementationType
        );

        public static IServiceCollection AddScoped(
            this IServiceCollection services,
            Type serviceType,
            Func<IServiceProvider, object> implementationFactory
        );

        public static IServiceCollection AddScoped<TService, TImplementation>(
            this IServiceCollection services
        )
        where TService : class
        where TImplementation : class, TService;

        public static IServiceCollection AddScoped(
            this IServiceCollection services,
            Type serviceType
        );

        public static IServiceCollection AddScoped<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory
        ) where TService : class;

        public static IServiceCollection AddScoped<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory
        )
        where TService : class
        where TImplementation : class, TService;

        public static IServiceCollection AddSingleton<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory
        )
        where TService : class
        where TImplementation : class, TService;

        public static IServiceCollection AddSingleton<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory
        ) where TService : class;

        public static IServiceCollection AddSingleton<TService>(
            this IServiceCollection services
        ) where TService : class;

        public static IServiceCollection AddSingleton(
            this IServiceCollection services,
            Type serviceType
        );

        public static IServiceCollection AddSingleton<TService, TImplementation>(
            this IServiceCollection services
        )
        where TService : class
        where TImplementation : class, TService;

        public static IServiceCollection AddSingleton(
            this IServiceCollection services,
            Type serviceType,
            Func<IServiceProvider, object> implementationFactory
        );

        public static IServiceCollection AddSingleton(
            this IServiceCollection services,
            Type serviceType,
            Type implementationType
        );

        public static IServiceCollection AddSingleton<TService>(
            this IServiceCollection services,
            TService implementationInstance
        ) where TService : class;

        public static IServiceCollection AddSingleton(
            this IServiceCollection services,
            Type serviceType,
            object implementationInstance
        );

        public static IServiceCollection AddTransient<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory
        )
        where TService : class
        where TImplementation : class, TService;

        public static IServiceCollection AddTransient<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory
        ) where TService : class;

        public static IServiceCollection AddTransient<TService>(
            this IServiceCollection services
        ) where TService : class;

        public static IServiceCollection AddTransient(
            this IServiceCollection services,
            Type serviceType
        );

        public static IServiceCollection AddTransient<TService, TImplementation>(
            this IServiceCollection services
        )
        where TService : class
        where TImplementation : class, TService;

        public static IServiceCollection AddTransient(
            this IServiceCollection services,
            Type serviceType,
            Func<IServiceProvider, object> implementationFactory
        );

        public static IServiceCollection AddTransient(
            this IServiceCollection services,
            Type serviceType,
            Type implementationType
        );
    }
}
```


### Microsoft.Extensions.DependencyInjection

|メソッド|説明|
|:--|:--|
|BuildServiceProvider|サービスプロバイダを生成します。汎用ホストを利用する場合、このメソッドを直接使用することは少ないかもしれません。|

```c#:Microsoft.Extensions.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollectionContainerBuilderExtensions
    {
        public static ServiceProvider BuildServiceProvider(
            this IServiceCollection services
        );

        public static ServiceProvider BuildServiceProvider(
            this IServiceCollection services,
            bool validateScopes
        );

        public static ServiceProvider BuildServiceProvider(
            this IServiceCollection services,
            ServiceProviderOptions options
        );
    }
}
```

### Microsoft.Extensions.Hosting.Abstractions

|メソッド|説明|
|:--|:--|
|AddHostedService|指定された型をホステッドサービスとして追加します。バックグラウンドで実行する処理を追加するときに使用します。|

```c#:Microsoft.Extensions.Hosting.Abstractions
namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollectionHostedServiceExtensions
    {
        public static IServiceCollection AddHostedService<THostedService>(
            this IServiceCollection services
        ) where THostedService : class, IHostedService;    

        public static IServiceCollection AddHostedService<THostedService>(
            this IServiceCollection services,
            Func<IServiceProvider, THostedService> implementationFactory
        ) where THostedService : class, IHostedService;
    }
}
```

### Microsoft.Extensions.Logging

|メソッド|説明|
|:--|:--|
|AddLogging|ログサービスを追加します。引数 configure に指定するデリゲートの中でログプロバイダを追加する処理などを実装します。|

```c#:Microsoft.Extensions.Logging
namespace Microsoft.Extensions.DependencyInjection
{
    public static class LoggingServiceCollectionExtensions
    {
        public static IServiceCollection AddLogging(
            this IServiceCollection services,
            Action<ILoggingBuilder> configure
        );
    }
}
```

### Microsoft.Extensions.Options

|メソッド|説明|
|:--|:--|
|AddOptions|IOption&lt;T&gt;, IOptionMonitor&lt;T&gt; などのオプションサービスを追加します。|
|AddOptions&lt;T&gt;|指定された型の OptionsBuilder を生成します。OptionsBuilder を使用すると追加だけでなく検証などの後処理を実装することができます。内部で AddOptions メソッドが呼び出されます。|
|Configure|指定された型・名前のオプションを構成するメソッドを追加します。インスタンスが注入されるときに呼び出されます。|
|ConfigureAll|指定された型のオプションを構成するメソッドを追加します。インスタンスが注入されるときに呼び出されます。|
|ConfigureOptions|指定された型が IConfigureOptions&lt;T&gt;, IPostConfigureOptions&lt;T&gt;, IValidateOptions&lt;T&gt; を実装している場合、サービスとして追加します。|
|PostConfigure|指定された型・名前のオプションを構成するメソッドを追加します。インスタンスが注入されるときに呼び出されます。Configure で追加したメソッドの後で呼び出されます。|
|PostConfigureAll|指定された型のオプションを構成するメソッドを追加します。インスタンスが注入されるときに呼び出されます。Configure で追加したメソッドの後で呼び出されます。|

```c#:Microsoft.Extensions.Options
namespace Microsoft.Extensions.DependencyInjection
{
    public static class OptionsServiceCollectionExtensions
    {
        public static IServiceCollection AddOptions(
            this IServiceCollection services
        );

        public static OptionsBuilder<TOptions> AddOptions<TOptions>(
            this IServiceCollection services
        ) where TOptions : class;

        public static OptionsBuilder<TOptions> AddOptions<TOptions>(
            this IServiceCollection services,
            string? name
        ) where TOptions : class;

        public static IServiceCollection Configure<TOptions>(
            this IServiceCollection services,
            Action<TOptions> configureOptions
        ) where TOptions : class;

        public static IServiceCollection Configure<TOptions>(
            this IServiceCollection services, string? name,
            Action<TOptions> configureOptions
        ) where TOptions : class;

        public static IServiceCollection ConfigureAll<TOptions>(
            this IServiceCollection services,
            Action<TOptions> configureOptions
        ) where TOptions : class;

        public static IServiceCollection ConfigureOptions<TConfigureOptions>(
            this IServiceCollection services
        ) where TConfigureOptions : class;

        public static IServiceCollection ConfigureOptions(
            this IServiceCollection services,
            Type configureType
        );

        public static IServiceCollection ConfigureOptions(
            this IServiceCollection services,
            object configureInstance
        );

        public static IServiceCollection PostConfigure<TOptions>(
            this IServiceCollection services,
            Action<TOptions> configureOptions
        ) where TOptions : class;

        public static IServiceCollection PostConfigure<TOptions>(
            this IServiceCollection services,
            string? name,
            Action<TOptions> configureOptions
        ) where TOptions : class;

        public static IServiceCollection PostConfigureAll<TOptions>(
            this IServiceCollection services,
            Action<TOptions> configureOptions
        ) where TOptions : class;
    }
}
```


### Microsoft.Extensions.Options.ConfigurationExtensions

|メソッド|説明|
|:--|:--|
|Configure|指定されたコンフィグを指定された型のオプションにバインドします。IConfiguration.GetSection メソッドで取得したコンフィグをオプションとして追加するときに使用します。|

```c#:Microsoft.Extensions.Options.ConfigurationExtensions
namespace Microsoft.Extensions.DependencyInjection
{
    public static class OptionsConfigurationServiceCollectionExtensions
    {
        public static IServiceCollection Configure<TOptions>(
            this IServiceCollection services,
            IConfiguration config
        ) where TOptions : class;

        public static IServiceCollection Configure<TOptions>(
            this IServiceCollection services,
            string? name,
            IConfiguration config
        ) where TOptions : class;

        public static IServiceCollection Configure<TOptions>(
            this IServiceCollection services,
            IConfiguration config,
            Action<BinderOptions>? configureBinder
        ) where TOptions : class;

        public static IServiceCollection Configure<TOptions>(
            this IServiceCollection services,
            string? name,
            IConfiguration config, Action<BinderOptions>? configureBinder
        ) where TOptions : class;
    }
}
```

### おまけ：オプションの追加をまとめたメソッド

オプション関連の拡張メソッドは名前が似ていたり少々わかりにくいと感じます。次のような拡張メソッドを定義しておくとわかりやすくなると思います。

```c#:BindOptions 拡張メソッド
public static IServiceCollection BindOptions<TOptions>(
    this IServiceCollection services,
    IConfiguration bindingConfig,
    Action<BinderOptions>? binderOptions = null,
    Action<TOptions>? configure = null,
    Func<TOptions, bool>? validation = null
    )
    where TOptions : class
{
    var builder = services.AddOptions<TOptions>().Bind(bindingConfig, binderOptions);
    if (configure != null) { services.Configure(configure); }
    if (validation != null) { builder.Validate(validation); }
    return services;
}

public static IServiceCollection BindOptions<TOptions>(
    this IServiceCollection services,
    string name,
    IConfiguration bindingConfig,
    Action<BinderOptions>? binderOptions = null,
    Action<TOptions>? configure = null,
    Func<TOptions, bool>? validation = null
    )
    where TOptions : class
{
    var builder = services.AddOptions<TOptions>(name).Bind(bindingConfig, binderOptions);
    if (configure != null) { services.Configure(name, configure); }
    if (validation != null) { builder.Validate(validation); }
    return services;
}
```

```c#:使用例
services.BindOptions<MyAppOptions>(
    // バインドするセクションを指定する
    hostContext.Configuration.GetSection("MyApp"),
    // バインダーオプションを設定する
    x => { x.BindNonPublicProperties = true; },
    // 読み込まれたセクションの値を上書きする
    x => { x.OptionValue = "1234"; },
    // 検証する
    x => {
        if (string.IsNullOrEmpty(x.OptionValue)) { return false; }
        return true;
    }
);
```