4

웹 응용 프로그램과 통신하는 각기 다른 API에 대해 HttpClient의 인스턴스를 만듭니다.종속성 주입을 사용하여 HttpClient의 여러 인스턴스 관리

비즈니스 클래스에 HttpClient을 삽입하려면 SimpleInjector으로 종속성 삽입을 사용하고 싶습니다. 예를 들어 ITwitterBusinessIInstagramBusiness이 있고 둘 다 해당 생성자에 HttpClient을 허용합니다.

종속성 삽입을 사용하여 동일한 유형의 여러 개체를 등록 할 때 가장 좋은 방법은 무엇입니까?

나는이 문제의 일부가 내 디자인 일 수 있다고 확신하지만 여기에 몇 가지 아이디어가있다.

내 첫번째 생각은

container.Register<ITwitterBusiness>(() => new TwitterBusiness(httpClientTwitter)); 

은 간단한데 디 등록에 대리자를 사용하는 것입니다,하지만이 방법은 SimpleInjector 느리게 실행함으로써, 예를 들어, 어떤 나쁜 부작용이 있을지 모르겠어요 또는 내가 어떤 디자인 패턴을 깨뜨리고 있다면.

내 두 번째 생각은 나는이 날 특정 클래스에 예를 HttpClient를 특정을 삽입 할 것으로 예상 컨텍스트 기반의 주입을http://simpleinjector.readthedocs.io/en/latest/advanced.html#context-based-injection

을 사용하는 것입니다. 아직도 정확히 어떻게 작동하는지 확실하지 않습니다.

디자인으로 이것을 해결할 수 있는지 궁금합니다. 예를 들어, 더미 클래스를 작성합니다. 난 단지 좋은 예제를 찾지 못했지만 정확하게 이해한다면 HttpClientTwitter 같은 상속받은 더미 클래스를 만들 수 있고 HttpClient을 상속받습니다. 그런 식으로 모호한 등록을 제거 할 수 있습니다.

감사합니다!

답변

3

첫 번째 아이디어는 DI 등록에서 대리인을 사용하는 것입니다. 충분히 간단하지만 SimpleInjector를 느리게 실행하거나 일부 디자인 패턴을 깨는 경우와 같이이 메서드에 나쁜 영향이 있는지 여부는 알 수 없습니다.

유선 연결이 필요한 응용 프로그램 구성 요소가있는 경우 자동 배선 (대리인 등록 반대)을 사용하는 것이 좋습니다. 자동 배선은 등록을 단순화하고 Simple Injector가 객체 그래프를 분석 할 수있게합니다. 두 가지 모두 당신의 경우에는 아무런 관심도없는 것 같습니다. HttpClient은 응용 프로그램 구성 요소가 아니라 인프라 유형입니다. 다른 의존성이없는 것처럼 보이므로 대리인을 등록해도 유지 관리 문제가 발생하지 않습니다.

대리인 등록은 자동 배선 사용에 비해 느리므로 단순 주입기는 대리인을 사용하여 최대한 많이 최적화 할 수 없습니다. 그러나 매우 때, 매우 이렇게하면 성능 차이를 알 수 있습니다. 이것은 당신이 걱정해야 할 것이 아닙니다.

두 번째 아이디어는 컨텍스트 기반 주입을 사용하는 것입니다. 나는 이것이 특정 클래스에 특정 HttpClient 인스턴스를 주입 할 수 있다고 믿는다. 아직도 정확히 어떻게 작동하는지 확실하지 않습니다.

컨텍스트에 따라 고유 한 등록을 만들 수 있습니다.예를 들면 : 당신이 유연성의 잘못된 인식을 얻을 TwitterBusiness 클래스 내로 HttpClient를 주입함으로써 디자인

에 의해 순수하게이 문제를 해결 할 수 있다면

var httpClientTwitterRegistration = Lifestyle.Transient.CreateRegistration<HttpClient>(
    () => new HttpClient("https://twitter"), 
    container); 

container.RegisterConditional(typeof(HttpClient), httpClientTwitterRegistration, 
    c => c.Consumer.ImplementationType == typeof(TwitterBusiness)); 

var httpClientInstagramRegistration = Lifestyle.Transient.CreateRegistration<HttpClient>(
    () => new HttpClient("https://instagram"), 
    container); 

container.RegisterConditional(typeof(HttpClient), httpClientInstagramRegistration, 
    c => c.Consumer.ImplementationType == typeof(InstagramBusiness)); 

나는 매우 궁금 하군요. 당신은 2 개의 스왑 구현을 할 수있는 것처럼 보이지만, HttpClient이 구체적인 유형이기 때문에 구현 변경은 의미가 없습니다. TwitterBusinessHttpClient과 직접 통신하므로 구현 세부 사항을 작성해야합니다. 즉 HttpContext의 생성을 TwitterBusiness 안에 옮깁니다. 구성해야하는 인수 (URL)는 TwitterBusiness에 삽입 할 수 있습니다. 이런 식으로 TwitterBusinessHttpClient의 생성 및 처리를 완전히 제어 할 수 있으며 변경해야 할 유일한 것 (URL)을 삽입합니다.

+1

감사합니다. 스티븐. 모든 HttpClient 인스턴스가 싱글 톤이라는 점을 잊어 버렸습니다. 따라서 Twitter HttpClient 인스턴스가 응용 프로그램의 수명과 함께 재사용됩니다. 저는 항상 정적 변수를 피하는 경향이 있습니다. 그러나 TwitterBusiness 내부의 정적 변수로 사용할 수 있다고 생각합니다. 생성자에서 null 인 경우 한 번만 초기화하십시오. 어떻게 생각해? 단위 테스트를 위해 HttpMessageHandler를 생성자에 전달할 수 있습니다. – raRaRa

+0

@raRaRa 당신은 트위터 비즈니스를 싱글 톤으로 등록 할 수도 있습니다. 이것은 당신의 httpclient가 여전히 인스턴스 변수가 될 수 있지만 HttpClient가 쓰레드에 안전하다고는 생각하지 않는다는 것을 의미합니다. 그래서 모든 mrthod 안에 그것을 만드는 것이 가장 안전 할 것입니다. – Steven

+0

스레드로부터 안전하므로 최대한 재사용해야합니다. 그것이 내가 싱글 톤이되기를 원하는 이유입니다. 그렇지 않으면 TwitterBusiness에서 필요에 따라 HttpClient의 인스턴스를 만들 것입니다. 그러나 당신이 틀림없이, TwitterBusiness는 싱글 톤으로 등록 될 수 있습니다. 나는 이것을 생각하고 결정을 내려고 노력할 것입니다. 도와 주셔서 감사합니다! :) – raRaRa