MyDependency 클래스의 인스턴스를 만들어 클래스에서 WriteMessage 메서드를 사용할 수 있게 할 수 있습니다.An instance of the MyDependency class can be created to make the WriteMessage method available to a class.MyDependency 클래스는 IndexModel 클래스의 종속성입니다.The MyDependency class is a dependency of the IndexModel class:

서비스가 사용되는 클래스의 생성자에 주입됨.Injection of the service into the constructor of the class where it's used.프레임워크가 종속성의 인스턴스를 만들고 더 이상 필요하지 않으면 삭제하는 작업을 담당합니다.The framework takes on the responsibility of creating an instance of the dependency and disposing of it when it's no longer needed.

샘플 앱에서 IMyDependency 인터페이스는 서비스가 앱에 제공하는 메서드를 정의합니다.In the sample app, the IMyDependency interface defines a method that the service provides to the app:

IMyDependency 및 ILogger<TCategoryName>는 서비스 컨테이너에 등록되어야 합니다.IMyDependency and ILogger<TCategoryName> must be registered in the service container.IMyDependency는 Startup.ConfigureServices에서 등록됩니다.IMyDependency is registered in Startup.ConfigureServices.ILogger<TCategoryName>은 로깅 추상화 인프라에서 등록하므로, 프레임워크에서 기본적으로 등록한 프레임워크 제공 서비스입니다.ILogger<TCategoryName> is registered by the logging abstractions infrastructure, so it's a framework-provided service registered by default by the framework.

샘플 앱에서 IMyDependency 서비스는 구체적인 형식 MyDependency로 등록됩니다.In the sample app, the IMyDependency service is registered with the concrete type MyDependency.이 등록은 서비스 수명을 단일 요청의 수명으로 지정합니다.The registration scopes the service lifetime to the lifetime of a single request.서비스 수명에 대해서는 이 항목의 뒷부분에서 설명합니다.Service lifetimes are described later in this topic.

서비스의 인스턴스는 서비스가 사용되는 클래스의 생성자를 통해 요청되고 전용 필드에 할당됩니다.An instance of the service is requested via the constructor of a class where the service is used and assigned to a private field.이 필드는 클래스 전체에서 필요에 따라 서비스에 액세스하는 데 사용됩니다.The field is used to access the service as necessary throughout the class.

서비스 컬렉션 확장 메서드를 사용하여 서비스(및 필요한 경우 해당 종속 서비스)를 등록할 수 있는 경우 단일 Add{SERVICE_NAME} 확장 메서드를 사용하여 해당 서비스에 필요한 모든 서비스를 등록하는 것이 규칙입니다.When a service collection extension method is available to register a service (and its dependent services, if required), the convention is to use a single Add{SERVICE_NAME} extension method to register all of the services required by that service.다음 코드는 확장 메서드 AddDbContext<TContext> 및 AddIdentityCore를 사용하여 컨테이너에 서비스를 추가하는 방법을 보여 주는 예제입니다.The following code is an example of how to add additional services to the container using the extension methods AddDbContext<TContext> and AddIdentityCore:

ScopedScoped

미들웨어에서 범위가 지정된 서비스를 사용하는 경우 Invoke 또는 InvokeAsync 메서드에 서비스를 삽입합니다.When using a scoped service in a middleware, inject the service into the Invoke or InvokeAsync method.생성자 삽입은 서비스가 singleton처럼 작동하게 하므로 이러한 방법으로 삽입하지 마세요.Don't inject via constructor injection because it forces the service to behave like a singleton.자세한 내용은 <xref:fundamentals/middleware/write#per-request-middleware-dependencies>를 참조하세요.For more information, see <xref:fundamentals/middleware/write#per-request-middleware-dependencies>.

범위가 지정된 서비스를 싱글톤에서 해결하면 위험합니다.It's dangerous to resolve a scoped service from a singleton.이 경우 후속 요청을 처리할 때 서비스가 잘못된 상태일 수 있습니다.It may cause the service to have incorrect state when processing subsequent requests.

수명 및 등록 옵션Lifetime and registration options

이러한 수명 및 등록 옵션 간의 차이점을 살펴보려면 작업을 고유한 ID인 OperationId가 부여된 작업으로 나타내는 다음 인터페이스들을 고려해 보세요.To demonstrate the difference between the lifetime and registration options, consider the following interfaces that represent tasks as an operation with a unique identifier, OperationId.다음 인터페이스들에 대해 작업 서비스의 수명을 구성하는 방법에 따라 컨테이너는 클래스에서 요청할 때 서비스의 같은 인스턴스나 다른 인스턴스를 제공합니다.Depending on how the lifetime of an operations service is configured for the following interfaces, the container provides either the same or a different instance of the service when requested by a class:

OperationService는 각각 다른 Operation 형식에 종속되어 등록됩니다.An OperationService is registered that depends on each of the other Operation types.종속성 주입을 통해 OperationService를 요청하면 종속 서비스의 수명에 따라 각 서비스의 새 인스턴스나 기존 인스턴스를 받습니다.When OperationService is requested via dependency injection, it receives either a new instance of each service or an existing instance based on the lifetime of the dependent service.

컨테이너에서 요청할 때 임시 서비스가 생성되면 IOperationTransient 서비스의 OperationId는 OperationService의 OperationId와 다릅니다.When transient services are created when requested from the container, the OperationId of the IOperationTransient service is different than the OperationId of the OperationService.OperationService는 IOperationTransient 클래스의 새 인스턴스를 받습니다.OperationService receives a new instance of the IOperationTransient class.새 인스턴스는 다른 OperationId를 생성합니다.The new instance yields a different OperationId.

클라이언트 요청에 따라 범위가 지정된 서비스가 생성되면 IOperationScoped 서비스의 OperationId는 클라이언트 요청 내의 OperationService와 같습니다.When scoped services are created per client request, the OperationId of the IOperationScoped service is the same as that of OperationService within a client request.전체 클라이언트 요청에서 두 서비스는 다른 OperationId 값을 공유합니다.Across client requests, both services share a different OperationId value.

싱글톤 및 싱글톤 인스턴스 서비스가 한 번 생성되어 모든 클라이언트 요청 및 모든 서비스에서 사용될 경우 OperationId는 모든 서비스 요청에서 동일합니다.When singleton and singleton-instance services are created once and used across all client requests and all services, the OperationId is constant across all service requests.

IOperationSingletonInstance 서비스는 알려진 ID가 Guid.Empty인 특정 인스턴스를 사용 중입니다.The IOperationSingletonInstance service is using a specific instance with a known ID of Guid.Empty.이 형식이 사용 중임을 명확하게 알 수 있습니다(이 인스턴스의 GUID는 모두 0입니다).It's clear when this type is in use (its GUID is all zeroes).

DI는 정적/전역 개체 액세스 패턴의 ‘대안’입니다.DI is an alternative to static/global object access patterns.고정 개체 액세스와 함께 사용할 경우 DI의 장점을 실현할 수 없습니다.You may not be able to realize the benefits of DI if you mix it with static object access.

MyDependency 클래스의 인스턴스를 만들어 클래스에서 WriteMessage 메서드를 사용할 수 있게 할 수 있습니다.An instance of the MyDependency class can be created to make the WriteMessage method available to a class.MyDependency 클래스는 IndexModel 클래스의 종속성입니다.The MyDependency class is a dependency of the IndexModel class:

서비스가 사용되는 클래스의 생성자에 주입됨.Injection of the service into the constructor of the class where it's used.프레임워크가 종속성의 인스턴스를 만들고 더 이상 필요하지 않으면 삭제하는 작업을 담당합니다.The framework takes on the responsibility of creating an instance of the dependency and disposing of it when it's no longer needed.

샘플 앱에서 IMyDependency 인터페이스는 서비스가 앱에 제공하는 메서드를 정의합니다.In the sample app, the IMyDependency interface defines a method that the service provides to the app:

IMyDependency 및 ILogger<TCategoryName>는 서비스 컨테이너에 등록되어야 합니다.IMyDependency and ILogger<TCategoryName> must be registered in the service container.IMyDependency는 Startup.ConfigureServices에서 등록됩니다.IMyDependency is registered in Startup.ConfigureServices.ILogger<TCategoryName>은 로깅 추상화 인프라에서 등록하므로, 프레임워크에서 기본적으로 등록한 프레임워크 제공 서비스입니다.ILogger<TCategoryName> is registered by the logging abstractions infrastructure, so it's a framework-provided service registered by default by the framework.

샘플 앱에서 IMyDependency 서비스는 구체적인 형식 MyDependency로 등록됩니다.In the sample app, the IMyDependency service is registered with the concrete type MyDependency.이 등록은 서비스 수명을 단일 요청의 수명으로 지정합니다.The registration scopes the service lifetime to the lifetime of a single request.서비스 수명에 대해서는 이 항목의 뒷부분에서 설명합니다.Service lifetimes are described later in this topic.

서비스의 인스턴스는 서비스가 사용되는 클래스의 생성자를 통해 요청되고 전용 필드에 할당됩니다.An instance of the service is requested via the constructor of a class where the service is used and assigned to a private field.이 필드는 클래스 전체에서 필요에 따라 서비스에 액세스하는 데 사용됩니다.The field is used to access the service as necessary throughout the class.

서비스 컬렉션 확장 메서드를 사용하여 서비스(및 필요한 경우 해당 종속 서비스)를 등록할 수 있는 경우 단일 Add{SERVICE_NAME} 확장 메서드를 사용하여 해당 서비스에 필요한 모든 서비스를 등록하는 것이 규칙입니다.When a service collection extension method is available to register a service (and its dependent services, if required), the convention is to use a single Add{SERVICE_NAME} extension method to register all of the services required by that service.다음 코드는 확장 메서드 AddDbContext<TContext> 및 AddIdentityCore를 사용하여 컨테이너에 서비스를 추가하는 방법을 보여 주는 예제입니다.The following code is an example of how to add additional services to the container using the extension methods AddDbContext<TContext> and AddIdentityCore:

ScopedScoped

미들웨어에서 범위가 지정된 서비스를 사용하는 경우 Invoke 또는 InvokeAsync 메서드에 서비스를 삽입합니다.When using a scoped service in a middleware, inject the service into the Invoke or InvokeAsync method.생성자 삽입은 서비스가 singleton처럼 작동하게 하므로 이러한 방법으로 삽입하지 마세요.Don't inject via constructor injection because it forces the service to behave like a singleton.자세한 내용은 <xref:fundamentals/middleware/write#per-request-middleware-dependencies>를 참조하세요.For more information, see <xref:fundamentals/middleware/write#per-request-middleware-dependencies>.

범위가 지정된 서비스를 싱글톤에서 해결하면 위험합니다.It's dangerous to resolve a scoped service from a singleton.이 경우 후속 요청을 처리할 때 서비스가 잘못된 상태일 수 있습니다.It may cause the service to have incorrect state when processing subsequent requests.

수명 및 등록 옵션Lifetime and registration options

이러한 수명 및 등록 옵션 간의 차이점을 살펴보려면 작업을 고유한 ID인 OperationId가 부여된 작업으로 나타내는 다음 인터페이스들을 고려해 보세요.To demonstrate the difference between the lifetime and registration options, consider the following interfaces that represent tasks as an operation with a unique identifier, OperationId.다음 인터페이스들에 대해 작업 서비스의 수명을 구성하는 방법에 따라 컨테이너는 클래스에서 요청할 때 서비스의 같은 인스턴스나 다른 인스턴스를 제공합니다.Depending on how the lifetime of an operations service is configured for the following interfaces, the container provides either the same or a different instance of the service when requested by a class:

OperationService는 각각 다른 Operation 형식에 종속되어 등록됩니다.An OperationService is registered that depends on each of the other Operation types.종속성 주입을 통해 OperationService를 요청하면 종속 서비스의 수명에 따라 각 서비스의 새 인스턴스나 기존 인스턴스를 받습니다.When OperationService is requested via dependency injection, it receives either a new instance of each service or an existing instance based on the lifetime of the dependent service.

컨테이너에서 요청할 때 임시 서비스가 생성되면 IOperationTransient 서비스의 OperationId는 OperationService의 OperationId와 다릅니다.When transient services are created when requested from the container, the OperationId of the IOperationTransient service is different than the OperationId of the OperationService.OperationService는 IOperationTransient 클래스의 새 인스턴스를 받습니다.OperationService receives a new instance of the IOperationTransient class.새 인스턴스는 다른 OperationId를 생성합니다.The new instance yields a different OperationId.

클라이언트 요청에 따라 범위가 지정된 서비스가 생성되면 IOperationScoped 서비스의 OperationId는 클라이언트 요청 내의 OperationService와 같습니다.When scoped services are created per client request, the OperationId of the IOperationScoped service is the same as that of OperationService within a client request.전체 클라이언트 요청에서 두 서비스는 다른 OperationId 값을 공유합니다.Across client requests, both services share a different OperationId value.

싱글톤 및 싱글톤 인스턴스 서비스가 한 번 생성되어 모든 클라이언트 요청 및 모든 서비스에서 사용될 경우 OperationId는 모든 서비스 요청에서 동일합니다.When singleton and singleton-instance services are created once and used across all client requests and all services, the OperationId is constant across all service requests.

IOperationSingletonInstance 서비스는 알려진 ID가 Guid.Empty인 특정 인스턴스를 사용 중입니다.The IOperationSingletonInstance service is using a specific instance with a known ID of Guid.Empty.이 형식이 사용 중임을 명확하게 알 수 있습니다(이 인스턴스의 GUID는 모두 0입니다).It's clear when this type is in use (its GUID is all zeroes).

DI는 정적/전역 개체 액세스 패턴의 ‘대안’입니다.DI is an alternative to static/global object access patterns.고정 개체 액세스와 함께 사용할 경우 DI의 장점을 실현할 수 없습니다.You may not be able to realize the benefits of DI if you mix it with static object access.