AddTransient、AddScoped、AddSingletonサービスの違い 質問する

AddTransient、AddScoped、AddSingletonサービスの違い 質問する

実装したい依存性注入(DI) を ASP.NET Core で実行します。このコードをConfigureServicesメソッドに追加すると、両方の方法が機能します。

ASP.NET Core のメソッドservices.AddTransientとメソッドの違いは何ですか?service.AddScoped

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddScoped<IEmailSender, AuthMessageSender>();
}

ベストアンサー1

要約

一時オブジェクトは常に異なります。すべてのコントローラーとすべてのサービスに新しいインスタンスが提供されます。

スコープ付きオブジェクトはリクエスト内では同じですが、リクエストごとに異なります。

シングルトン オブジェクトは、すべてのオブジェクトおよびすべてのリクエストに対して同じです。

さらに詳しく説明するために、.NET ドキュメント違いを示します:

これらの有効期間と登録オプションの違いを示すために、1 つ以上のタスクを一意の識別子を持つ操作として表す単純なインターフェイスを考えてみましょう。OperationIdこのサービスの有効期間をどのように構成するかに応じて、コンテナーは要求クラスにサービスの同じインスタンスまたは異なるインスタンスを提供します。要求されている有効期間を明確にするために、有効期間オプションごとに 1 つの型を作成します。

using System;

namespace DependencyInjectionSample.Interfaces
{
    public interface IOperation
    {
        Guid OperationId { get; }
    }

    public interface IOperationTransient : IOperation
    {
    }

    public interface IOperationScoped : IOperation
    {
    }

    public interface IOperationSingleton : IOperation
    {
    }

    public interface IOperationSingletonInstance : IOperation
    {
    }
}

Operationこれらのインターフェースは、コンストラクターで GUID を受け入れるか、提供されていない場合は新しい GUID を使用する単一のクラスを使用して実装します。

using System;
using DependencyInjectionSample.Interfaces;
namespace DependencyInjectionSample.Classes
{
    public class Operation : IOperationTransient, IOperationScoped, IOperationSingleton, IOperationSingletonInstance
    {
        Guid _guid;
        public Operation() : this(Guid.NewGuid())
        {

        }

        public Operation(Guid guid)
        {
            _guid = guid;
        }

        public Guid OperationId => _guid;
    }
}

次に、 ではConfigureServices、各タイプが、その名前付き有効期間に従ってコンテナーに追加されます。

services.AddTransient<IOperationTransient, Operation>();
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
services.AddTransient<OperationService, OperationService>();

サービスIOperationSingletonInstanceは という既知の ID を持つ特定のインスタンスを使用しているためGuid.Empty、このタイプが使用されているかどうかは明らかです。また、OperationService他の各Operationタイプに依存する も登録されているため、リクエスト内で、このサービスが各操作タイプに対してコントローラと同じインスタンスを取得するのか、新しいインスタンスを取得するのかが明らかになります。このサービスが行うことは、依存関係をプロパティとして公開することだけであり、これにより、依存関係がビューに表示できるようになります。

using DependencyInjectionSample.Interfaces;

namespace DependencyInjectionSample.Services
{
    public class OperationService
    {
        public IOperationTransient TransientOperation { get; }
        public IOperationScoped ScopedOperation { get; }
        public IOperationSingleton SingletonOperation { get; }
        public IOperationSingletonInstance SingletonInstanceOperation { get; }

        public OperationService(IOperationTransient transientOperation,
            IOperationScoped scopedOperation,
            IOperationSingleton singletonOperation,
            IOperationSingletonInstance instanceOperation)
        {
            TransientOperation = transientOperation;
            ScopedOperation = scopedOperation;
            SingletonOperation = singletonOperation;
            SingletonInstanceOperation = instanceOperation;
        }
    }
}

アプリケーションへの個別のリクエスト内およびリクエスト間のオブジェクトの有効期間を示すために、サンプルにはOperationsController、各種類のタイプを要求する とが含まれていますIOperation次に、アクションはコントローラとサービスのすべての値を表示します。OperationServiceIndexOperationId

using DependencyInjectionSample.Interfaces;
using DependencyInjectionSample.Services;
using Microsoft.AspNetCore.Mvc;

namespace DependencyInjectionSample.Controllers
{
    public class OperationsController : Controller
    {
        private readonly OperationService _operationService;
        private readonly IOperationTransient _transientOperation;
        private readonly IOperationScoped _scopedOperation;
        private readonly IOperationSingleton _singletonOperation;
        private readonly IOperationSingletonInstance _singletonInstanceOperation;

        public OperationsController(OperationService operationService,
            IOperationTransient transientOperation,
            IOperationScoped scopedOperation,
            IOperationSingleton singletonOperation,
            IOperationSingletonInstance singletonInstanceOperation)
        {
            _operationService = operationService;
            _transientOperation = transientOperation;
            _scopedOperation = scopedOperation;
            _singletonOperation = singletonOperation;
            _singletonInstanceOperation = singletonInstanceOperation;
        }

        public IActionResult Index()
        {
            // ViewBag contains controller-requested services
            ViewBag.Transient = _transientOperation;
            ViewBag.Scoped = _scopedOperation;
            ViewBag.Singleton = _singletonOperation;
            ViewBag.SingletonInstance = _singletonInstanceOperation;

            // Operation service has its own requested services
            ViewBag.Service = _operationService;
            return View();
        }
    }
}

ここで、このコントローラー アクションに対して 2 つの個別のリクエストが行われます。

最初のリクエスト

二つ目の要求

OperationIdリクエスト内およびリクエスト間でどの値が変化するかを確認します。

  • 一時オブジェクトは常に異なります。すべてのコントローラーとすべてのサービスに新しいインスタンスが提供されます。

  • スコープ付きオブジェクトはリクエスト内では同じですが、リクエストごとに異なります。

  • シングルトンオブジェクトは、すべてのオブジェクトとすべてのリクエストに対して同じです(インスタンスが提供されているかどうかに関係なくConfigureServices

おすすめ記事