Autofac 제어 범위와 수명 주기에 대해 배우기에 좋은 글입니다. 라이프사이클 범위는 애플리케이션 내 작업 단위와 동등하며, 작업 단위는 처음부터 라이프사이클 범위를 시작하고, 그 작업 단위를 요구하는 서비스들은 라이프사이클 범위에서 분리됩니다.
평생 스코프스
라이프트미 스코프 만들기
스코프를 수동으로 만들고 폐기하세요. Lifetime 스코프는 일회용이며 부품 폐기를 추적하므로 항상 "Dispose()"라고 부르거나 "useing" 문구로 감싸도록 하세요.
라벨 라이프타임 스코프
때로는 작업 단위 내에서 일부 서비스를 공유해야 할 수도 있지만, 싱글턴 모드와 같은 글로벌 공유 편의는 사용하고 싶지 않을 것입니다. 예를 들어, 웹 애플리케이션의 요청당 라이프사이클을 기준으로 InstancePerMatchingLifetimeScope를 사용하여 라이프사이클과 서비스를 식별할 수 있습니다.
예를 들어, 메일을 보내는 컴포넌트가 있고, 트랜잭션 로직이 메시지를 여러 번 보내야 하므로 메일 서비스는 각 논리 트랜잭션 슬라이스에서 공유할 수 있습니다. 이메일 컴포넌트가 글로벌 싱글톤이 되길 원하지 않는다면, 다음과 같이 설정할 수 있습니다.
평생 범위에 등록 추가하기
Autofac은 라이프사이클을 만들 때 '즉석에서' 추가할 수 있게 해줍니다. 이 기능은 일종의 '스팟 용접' 제한 등록 오버라이드가 필요할 때나, 전역적으로 등록하고 싶지 않은 추가 요소가 필요할 때 도움이 될 수 있습니다. 이 작업은 ContainerBuilder를 받아 등록을 추가하는 람다를 BeginLifetimeScope()에 전달함으로써 가능합니다. (라이프사이클을 생성할 때 글로벌 등록 없이 추가 서비스를 등록하세요)
인스턴스 범위
인스턴스 범위는 요청 간 인스턴스 공유 방식을 결정합니다. 서비스를 요청할 때, autofac은 단일 인스턴스 범위, 의존성 범위당 새 인스턴스, 또는 스레드나 수명 범위당 HTTP 요청과 같은 맥락의 싱글턴을 반환할 수 있습니다. 이는 명시적인 Resolve() 호출에서 반환된 인스턴스뿐만 아니라, 컨테이너가 내부적으로 생성하여 다른 컴포넌트의 의존성을 만족하는 인스턴스에도 적용됩니다.
- 종속 인스턴스별
- 단일 인스턴스
- 평생 범위당 인스턴스
- 매칭 수명 범위별 인스턴스
- 요청당 인스턴스
- 소유 수당 인스턴스
- 스레드 범위
종속 인스턴스별
다른 컨테이너에서는 'transient' 또는 'factory'라고도 불리며, 서비스가 요청될 때마다 고유한 인스턴스를 반환합니다. 라이프사이클이 지정되어 있지 않다면, 이것이 기본 동작입니다.
각 Resolve 의존성은 새로운 컴포넌트를 반환합니다.
단일 인스턴스
동일한 인스턴스가 모든 요청과 중첩된 범위에서 반환됩니다.
평생 범위당 인스턴스
이 스코프는 중첩된 스코프에도 적용할 수 있습니다. 수명당 스코프 구성 요소는 중첩된 스코프 내에 최대 하나의 인스턴스를 가집니다. 이는 단일 작업 단위에 특화된 객체가 추가적인 논리 작업 단위를 중첩해야 할 때 유용합니다. 각 중첩된 수명 범위는 등록된 의존성의 새로운 인스턴스를 받게 됩니다.
수명별 스코프 인스턴스 구성 요소를 파싱하면, 중첩된 스코프에는 인스턴스가 하나만 존재합니다(예: 작업 단위 단위).
매칭 수명 범위별 인스턴스
이는 Instance Per Lifetime Scope와 유사하지만, 더 정밀한 인스턴스와 제어를 공유할 수 있습니다. 중첩된 라이프사이클을 만들 때는 라벨을 붙이거나 이름을 붙일 수 있습니다. 매칭 수명 범위를 가진 컴포넌트는 중첩된 수명 범위당 최대 하나의 인스턴스만 존재하며, 그 인스턴스는 주어진 이름과 일치합니다. 이로 인해 스코프가 적용된 싱글톤을 생성할 수 있어, 중첩된 사이클이 전역 인스턴스를 생성하지 않고도 컴포넌트를 공유할 수 있습니다.
http 요청과 같이 중첩된 라이프사이클로 생성된 단일 작업 단위에 유용합니다. 만약 HTTP 요청마다 중첩된 수명이 생성된다면, 수명 범위가 있는 모든 컴포넌트는 HTTP 요청당 인스턴스를 갖게 됩니다. (요청당 평생 범위에 대해서는 아래에서 더 자세히 설명합니다.)
대부분의 응용 분야에서는 작업 단위를 나타내기 위해 계층적 컨테이너 중첩 하나만 필요합니다. 여러 중첩 레벨이 필요할 경우(예: global->request->transaction), 특정 수준에서 태그를 통해 공유할 수 있는 컴포넌트를 생성할 수 있습니다.
중첩된 라이프사이클이 시작되면 태그가 그 라이프사이클에 연관됩니다. 정확한 명칭의 수명 범위가 없을 때 매칭 수명 범위 구성 요소를 해결하려고 하면 예외가 발생합니다. (저장되지 않은 태그의 수명 주기가 구식되면 예외가 발생합니다.)
요청당 인스턴스
일부 애플리케이션 유형은 MVC와 같이 자연스럽게 "요청" 유형의 의미론을 가집니다 ASP.NET. 이러한 애플리케이션 유형 중에서, "요청당 단일 통" 형태를 갖추는 것이 도움이 됩니다. 요청당 인스턴스는 잘 알려진 수명 범위 태그, 등록 편의 방법, 그리고 공통 적용을 위한 통합을 통해 인스턴스별 매칭 수명 범위를 기반으로 합니다 유형(요청당 하나의 인스턴스는 잘 알려진 수명 태그, 등록 편의 방법, 그리고 일반적인 애플리케이션 유형에 대한 통합을 제공하여 매칭 수명 범위 위에 구축됩니다). 본질적으로, 매칭 수명 범위별 기준입니다.
즉, 현재 요청이 없고, 인스턴스별 요청 단위로 등록된 컴포넌트를 파싱하면 예외가 발생합니다. 요청당 수명을 다루는 자세한 FAQ가 있습니다.
하이퍼링크 로그인이 보입니다.
소유 수당 인스턴스
소유된 암묵적 관계 유형, 새로운 중첩된 라이프사이클을 만듭니다. 의존성은 인스턴스별 소유 인스턴스에 등록함으로써 호스트 인스턴스로 제한할 수 있습니다.
이 예시에서 ServiceForHandler 서비스는 소유된 MessageHandler 인스턴스의 수명까지 범위가 설정됩니다.
스레드 범위
참고해 보세요
하이퍼링크 로그인이 보입니다.
실제 전투
저는 Instance Per Lifetime Scope 모드를 사용하고 있습니다.
winform에서는 호출이 실행될 때마다 데이터베이스 컨텍스트를 사용하며, 아래 그림과 같이 다음과 같습니다:
_dbContext.GetHashCode();
13583655 _dbContext.GetHashCode();
13583655 _dbContext.GetHashCode();
13583655 멀티스레딩과 동시성의 경우, 동일한 데이터베이스 컨텍스트를 사용하면 데이터베이스를 추가, 삭제, 수정, 검사할 때 예외가 발생합니다.
autofac이 버튼을 클릭할 때마다 새로운 객체를 반환하게 하고 싶습니다. 코드는 다음과 같습니다:
아래에 나와 있습니다:
(끝) |