2016-08-15 3 views
0

은 내가이 컨트롤러를 사용하려고하면콘크리트 유형

public class FooController : ApiController 
{ 
    private readonly IDictionary<string, string> messageDictionary; 
    private readonly TimeSpan timeout; 

    public FooController(IDictionary<string, string> messageDictionary, TimeSpan timeout) 
    { 
     // set fields 
    } 

    public async Task<IHttpActionResult> Post([FromBody] string message) 
    { 
     try 
     { 
      using (var tokenSource = new CancellationTokenSource(timeout)) 
      { 
       CancellationToken token = tokenSource.Token; 

       // call some api 
       token.ThrowIfCancellationRequested(); 

       // do some other stuff 
       token.ThrowIfCancellationRequested(); 

       return Ok(); 
      } 
     } 
     catch 
     { 
      // LogException 
      return InternalServerError(); 
     } 
    } 
} 

같은 것을 보이는 웹 API 컨트롤러 FooController을 가지고, 나는 인 디폴트 생성자가 없다는 내용의 오류 좋아, 그 정도는 분명하다.

내가 Global.asax 파일에 의해이 같은 것을에서 보이는 사용자 지정 설정 섹션을 사용하여 web.config 파일에서 messageDictionary의 값을 읽고 있어요

private IDictionary<string, string> messageDictionary; 
private TimeSpan controllerTimeout; 

// ... 

void Application_Start(object sender, EventArgs e) 
{ 
    GlobalConfiguration.Configure(WebApiConfig.Register); 

    messageDictionary = BuildMessageDictionaryFromConfig(); 

    controllerTimeout = GetControllerTimeoutFromConfig(); 
} 

내 목표는 컨트롤러가 걱정하지하는 것입니다 구성에서 물건을 읽거나 messageDictionaryGlobal에서 가져 오는 것에 대해

ControllerBuilder.Current.SetControllerFactory(new FooControllerFactory()); 

또는

ControllerBuilder.Current.SetControllerFactory(typeof(FooControllerFactory)); 
처럼 Global#Application_Start에 등록에도 불구하고,

나는 내가 거기에 필요한 컨트롤러를 구축하기 위해 DefaultControllerFactory 연장으로 보았다,하지만 내 새로운 컨트롤러 공장의 생성자는 호출되지 않았다

DI를 사용할 수 있도록 새로운 IMessageDictionary 인터페이스를 만드는 것을 고려했습니다 (다른 데이터를 포함하는 다른 컨트롤러에 다른 IDictionary<string, string> 필드가 있기 때문에). 그러나 t 모자는 생성자의 timeout 매개 변수의 문제를 해결하지 않습니다.

이 문제를 어떻게 해결할 수 있습니까?

+0

컨트롤러 용으로 작동하는 서비스 인터페이스를 삽입 할 수 있습니다. 이게 정말 당신의 디자인을 향상시킬 지 모르겠습니다. – Noppey

+0

'ITimeoutProvider'를 주입하고 간단한 구현을 만들어 DI 서비스에 등록하십시오. DI를 사용하지 않는 경우 AutoFac과 같은 프레임 워크를 고려하십시오. – Igor

답변

0

모든 구성 관련 작업을 한 곳에서 통합하는 IConfigurationManager을 만든 다음 해당 관리자에 메시지와 시간 제한을 모두 포함시킬 수 있으며 DI를 통해 인스턴스를 가져올 수 있습니다.

0

나는 사용자 정의 구성 클래스가 대부분의 필요를 과도하게 비난하는 경향이 있음을 발견했습니다. 이것은 내가하는 일이며 훌륭하게 작동합니다. 먼저 AppSettings 클래스를 만듭니다.

public interface IAppSettings 
{ 
    string this[string key] { get; } 
} 

public class AppSettings : IAppSettings 
{ 
    public string this[string key] => ConfigurationManager.AppSettings[key]; 
} 

둘째, IoC 컨테이너로 등록하십시오. 그런 다음 컨트롤러에서 IAppSettings에 의존하고 필요한 것을 얻을 수 있습니다.

public FooController(IAppSettings appSettings) 
{ 
    var mySetting = appSettings["MySetting"]; 
} 

이렇게하면 단위 테스트에서 구성 설정을 모의하기가 매우 쉽습니다.

관련 문제