2017-04-14 2 views
0

업무상 유형의 서비스가 있으므로 AccountService으로 전화하십시오.X로 인수로 인스턴스화해야하는 X에 서비스를 삽입하려면 어떻게해야합니까?

class AccountService : IAccountService { 
    public AccountService(ILoggingService log) { 
     _log = log; 
    } 
} 

이 서비스는 ctor injection에서 로깅 서비스가 필요합니다. 로깅 서비스는 새로운 인스턴스로 주입됩니다 있도록

var log = LoggingServiceFactory.GetService(typeof(AccountService)); 

가 어떻게 형식으로 계정 서비스를 전달하는 객체 그래프를 정의합니까 :

로깅 서비스는 유형으로 포함하는 서비스를 전달하는 인스턴스화해야합니까?

나는이

container.RegisterType<IAccountService, AccountService>(); 
container.RegisterType<ILoggingService>(/* ??? */); 

할 수 ...하지만 난 거기에 넣어 모르겠어요.

해야합니까? 이 예를 들어 OK입니다

container.RegisterType<IAccountService>(() => return new AccountService(LoggingServiceFactory.GetService(typeof(AccountService))); 

,하지만뿐만 아니라 내 AccountService 필요한 기타 주사하면? 그 모든 람다 표현에 모든 것을 넣어야합니까?

container.RegisterType<IAccountService>(() => return new AccountService(LoggingServiceFactory.GetService(typeof(AccountService)), container.Resolve<IOtherService>(), container.Resolve<ISecondOtherService>()); 

다른 서비스에서도 다른 서비스 (로깅 서비스를 다시 포함)가 필요한 경우에는 어떻게해야합니까? 이처럼 꽤 지저분해질 수 있습니다.

class AccountService : IAccountService { 
    public AccountService(LoggingServiceFactory factory) { 
     _log = factory.GetService(typeof(this)); 
    } 
} 

그들에게이 방법 등록 :

은 내가 대신 공장을 주입 할 수 있도록 내가 상황을 타개 생각

container.RegisterType<IAccountService, AccountService>(); 
container.RegisterType<LoggingServiceFactory, LoggingServiceFactory>(); 

을 ...하지만 ILoggingServiceFactory이없는 아아 그래서 나는 것 콘크리트 유형을 주입하기 때문에 단위 테스트가 더 어려워집니다. 로깅 서비스를 변경할 수 없습니다 (제 3 자이며이를 사용해야합니다).

더 좋은 방법이 있습니까?

답변

0

당신이 사용하고있는 IOC의에 의존하지만, 대부분이 할 수있는 방법이 있습니다

container.Register<LoggingService>(); 

이 요구되었다 어디든지 그냥 LoggingService의 새로운 인스턴스를 얻을 것입니다. 대부분은 또한 싱글 톤 인스턴스를 등록하는 방법을 가질 것입니다. 위의 구문은 SimpleInjector가 사용하는 구문입니다. (필자가 지금 당장 나에게 앉아있는 구문입니다.)

로깅 서비스를 변경할 수 없습니다 (제 3 자이므로 사용해야 함).

절대 선택의 여지가 없다면 구체적인 유형을 사용하지 않을 것입니다. 비록 그것을 수정할 수는 없지만, 당신은 항상 당신 자신의 구체적인 클래스에서 이것을 감쌀 수 있고 인터페이스를 연결할 수 있습니다.

이렇게하면 더 이상 구체적인 클래스에 바인딩 할 수 없으며 다른 클래스의 로깅 서비스를 쉽게 바꿀 수 있습니다.

+0

맞아, 그 정도는 알지만 ... LoggingService는 로깅 할 코드가 일치하는'Type' 인수로 인스턴스화해야합니다 (로거가 범위 정보를 내보낼 수 있도록). 어떻게 그 인수를 생성자에 전달합니까? 그것은 질문입니다. –

+0

@ JohnWu Oh ... 그 생성자를 통해 주입되는 것이 아니라 생성자에서 인스턴스화됩니다. fbhdev는 공장을 만드는 데있어서 더 정확합니다. – TyCobb

1

여러 가지 방법으로이를 수행 할 수 있습니다

1) 반사 클래스 유형 사용하여 로깅 서비스를 얻기 위해 공장을 사용

class AccountService : IAccountService 
{ 
    public AccountService(ILoggingServiceFactory factory) 
    { 
     _log = factory.GetService(this.GetType()); 
    } 
} 

2)를 사용하여 공장 일반적인 방법

class AccountService : IAccountService 
{ 
    public AccountService(ILoggingServiceFactory factory) 
    { 
     _log = factory.GetService<AccountService>(); 
    } 
} 

3) 로깅 서비스를 일반화합니다.

class AccountService : IAccountService 
{ 
    public AccountService(ILoggingService<AccountService> log) 
    { 
     _log = log; 
    } 
} 
+0

제 질문에 언급했듯이, 'ILoggingServiceFactory'가 없습니다. –

+0

두 번째 대답에서 언급했듯이 로깅 구현을 특정 로깅 라이브러리에 단단히 결합하지 않는 것이 좋습니다. 사용중인 현재 로깅 공급자에게 로깅을 위임 한 ILoggingServiceFactory 및 ILoggingService를 만듭니다. – fbhdev

+0

그런 다음 시작시에 container.RegisterType 와 같이 구성 할 수 있습니다. – fbhdev

관련 문제