ServiceAnnotations를 사용하여dotnet에서 DI 용기를 설정하는 간단한 방법

10116 단어 dotnetcsharp
DI는 좋지만 관리 의존 항목 등록표는 아닐 수도 있습니다.
프로젝트가 증가함에 따라 DI 등록표를 유지하는 것은 갈수록 어려워진다.
수동으로 등록표를 유지하는 것은 번거로운 일이 아니다.
  • 지속적인 시간 낭비
  • 이것은 흔히 볼 수 있는 버그 출처
  • 새로운 반을 창설하는 것은 동력을 낮추는 좋은 방법이지만,'내가 여기에 놓을게'라는 방법
  • 을 사용한다.
    모듈 방법 - 어떤 형식으로든 프레임워크에 특정한 모듈, 예를 들어 Autofac.모듈,
    Microsoft의 확장 방법(예: AddLogging, AddMvc)과 같은 정적 방법을 사용하거나
    문제를 해결할 수 없다.
    이것은 허황된 구조를 제공함으로써 문제를 숨기려는 시도이며 모든 문제가 여전히 존재한다.
    그 밖에 공유 구성 요소와의 논리적 충돌도 있었다.
    마지막으로, "모듈식"의 유일한 이점
    -- 더 큰 코드 더미를 구축하는 데 도움이 되며 지속적인 수동 유지보수가 필요하다.

    Don't get me wrong here. There is nothing wrong with the modular approach for distributing cross-cutting components,
    like the same logging or MVC mentioned above.
    I'm talking specifically about services within a single application.


    또 다른 유행하는 방법인'전통'도 있다.
    익숙하지 않으면 반사 스캐닝 구성 요소를 사용합니다
    그리고 이름 규약을 바탕으로 프로그래밍 방식으로 서비스를 등록합니다.
    이렇게 하면 수동 문제가 해결됩니다. 하지만 이것은 사실입니다.
  • 유연성이 부족합니다.
    그렇습니다. 보통 상당한 비율의 등록을 덮어쓰고 있습니다.
    그러나 그것은 많은 세부 사항을 빠뜨렸다. 우리가 알고 있는 바와 같이'마귀는 세부 사항 속에 숨어있다'
  • 강제명명 모델은 의미를 손상시킬 수 있다. 처음에 그렇지 않으면 의미도 손상시킬 수 있다
  • 공약은 여전히 인공적으로 처리해야 하는 일

  • 서비스 설명
    이것은 내가 몇 년 전에 제기한 방법이며, 각종 항목에서 검증을 받았다.
    마지막으로, 나는 그것을 포장하여 GithubNuGet에 발표했다.
    이것은 매우 간단한 API를 가지고 있지만 상술한 모든 문제를 해결하기에 충분하다.
    그것은 IServiceCollection를 위해 설계되었기 때문에 모든 현대 국제올림픽위원회의 틀이 그것을 지지한다.
    이것은 프로그램 집합 스캔을 기반으로 하지만, 명명 약정과 코드가 아닌 속성을 사용하여 특수한 상황을 처리합니다.

    서비스 속성
    전형적인 프로젝트에서 이 속성은 대부분의 등록을 처리한다.
    클래스 단계에서 어떻게 등록해야 하는지를 정의합니다.
    생존 기간을 지정해야 한다.
    클래스가 등록해야 할 유형을 지정할 수도 있습니다. 지정하지 않으면 기본적으로 클래스 자체입니다.
    서비스 속성 사용법의 예:
    [Service(ServiceLifetime.Transient)]
    public class MyService: IMyService { }
    
    // will be registered with Transient lifetime
    // will be registered as MyService
    // equivalent to: services.AddTransient<MyService>();
    
    [Service(ServiceLifetime.Singleton, typeof(IMySerivce))]
    public class MyService: IMyService {}
    
    // will be registered with Singleton lifetime
    // will be registered as IMyService
    // equivalent to: services.AddSingleton<IMySerivce, MyService>();
    
    [Service(ServiceLifetime.Scoped, typeof(MyService), typeof(IMySerivce))]
    public class MyService: IMyService { }
    
    // will be registered with Scoped lifetime
    // will be registered as MyService and as IMyService
    // equivalent to: services.AddScoped<MyService>()
    //    .AddScoped<IMySerivce>(serviceProvider => serviceProvider.GetService<MyService>());
    

    서비스 속성 구성
    지금까지 정적 부분을 보았지만 사용자 정의 해상도가 필요합니다.
    심지어 설정이나 상하문 데이터에 접근할 수 있습니다.
    따라서 Configure Services 속성이 있습니다.
    이 속성들은 지정한 정적 방법을 호출합니다IServiceCollection 실례를 매개 변수로 방법에 전달한다.
    다른 이름을 지정하지 않은 경우 "Configure Services"라는 메서드를 찾습니다.
    ConfigureServices 속성 사용 예:
    [Service(ServiceLifetime.Transient), ConfigureServices(nameof(RegisterHttpClient))]
    public class MyService {
      readonly HttpClient _httpContext;
    
      public MyService(HttpClient httpContext) => _httpClient = httpClient;
    
      static void RegisterHttpClient(IServiceCollection serviceCollection, IConfiguration configuration) {
        serviceCollection.AddHttpClient<MyService>(httpClient => {
          httpClient.BaseAddress = new Uri(configuration.GetConnectionString("myServiceEndpoint"));
        });
      }
    }
    
    // the Service attribute
    // will be register service with Transient lifetime
    // will be register service as MyService
    
    // the ConfigureService attribute
    // will invoke RegisterHttpClient method
    
    ConfigureServices 등록 정보는 서비스 등록 정보 없이도 사용할 수 있습니다.
    모든 범주에 적용할 수 있으며 고유한 요구 사항은 다음과 같습니다.
  • 이 방법(이 속성에서 인용)은 정적이어야 하며 다시 불러오지 않아야 한다.
  • 스캔 컨텍스트에 전달할 매개변수의 객체로 지정합니다.(아래 설정 및 구성 참조)

  • 설정 및 구성
    먼저 NuGet 패키지를 설치합니다.
    dotnet add package ServiceAnnotations
    
    ServiceAnnotations 네임스페이스를 가져오면 AddAnnotatedServices 인터페이스에 확장 방법IServiceCollection이 추가됩니다.그것은 두 개의 매개 변수가 있는데 모두 선택할 수 있는 것이다.
  • 검색할 구성 요소입니다.기본값은 호출 프로그램 집합이기 때문에 보통 지정할 필요가 없습니다.
  • 스캔 컨텍스트에 대한 작업을 구성합니다.
    거기서 저희가 쓸 수 있는 대상을 전달할 수 있어요.
    ConfigureServices 속성 참조 메서드의 매개 변수입니다.
    위의 예에서 보듯이 우리는 IConfiguration를 매개 변수로 BaseAddressHttpClient를 얻었다.
    명시적으로 추가할 필요 없음IServiceCollection 기본적으로 사용 가능
  • ...
    using ServiceAnnotations;
    
    public class Startup {
      readonly IConfiguration _configuration;
    
      public Startup(IConfiguration configuration) => _configuration = configuration;
    
      public void ConfigureServices(IServiceCollection services) {
        services.AddAnnotatedServices(context =>
          context.Add<IConfiguration>(_configuration));
      }
    
      ...
    }
    

    ps
    나는 그것이 네가 코드의 정결을 유지하는 것을 도울 수 있기를 바란다.
    주저하지 말고 화제를 열고 의견을 발표하세요on Github.

    좋은 웹페이지 즐겨찾기