2014-04-15 1 views
1

I 종속 관계를 구축하는 다음 코드 조각이 :AutoFac + WebAPI를 폐기하지 객체

private static void InitializeContainer(HttpConfiguration config) 
{ 
    var builder = new ContainerBuilder(); 
    var controllers = AssemblyUtils.GetAssemblies(true); 

    controllers.Add(Assembly.GetExecutingAssembly()); 

    builder.RegisterApiControllers(controllers.ToArray()).PropertiesAutowired(); 

    builder 
     .RegisterAssemblyTypes(
      new List<Assembly>(AssemblyUtils.GetAssemblies(false)) 
      { 
       Assembly.GetExecutingAssembly() 
      }.ToArray()) 
     .Where(t => 
      t.GetCustomAttributes(typeof(IocContainerMarkerAttribute), false).Any() || 
      t.IsSubclassOf(typeof(HandlerAspectAttribute)) || 
      typeof(ICoreContract).IsAssignableFrom(t)) 
     .AsImplementedInterfaces().InstancePerDependency() 
     .PropertiesAutowired().OwnedByLifetimeScope(); 

    var container = builder.Build(); 

    GlobalConfiguration.Configuration.DependencyResolver = 
     new AutofacWebApiDependencyResolver(container); 

    config.DependencyResolver = 
     GlobalConfiguration.Configuration.DependencyResolver; 
} 

처리기 :

public class ArchieveDocumentCommandHandler 
    : IHandler<ArchieveDocumentCommand>, IDisposable 
{ 
    public IServiceMessageDispatcher Dispatcher { get; set; } 
    public IDocumentRepository DocumentRepository { get; set; } 
    public IFileSystemProvider FileSystemProvider { get; set; } 
    public ICoreSettingRepository CoreSettingRepository { get; set; } 

    public void Handles(ArchieveDocumentCommand message) { } 

    public void Dispose() { } 
} 

그러나 어떻게 든 Autofac이 객체의 Dispose 방법 후 호출되지 않는다 요청이 완료되었습니다. 평생 범위에 대해 읽었지만,이 경우에는 범위를 관리하는 Autofac이므로, 무슨 일이 벌어지고 있는지 이해할 수는 없습니다.

여기 뭔가 잘못 되었나요?

UPDATE

public class CommandsController : ApiController 
{ 
    [HttpPost] 
    public HttpResponseMessage Deliver() 
    { 
    ... 

     var handler = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(ICommandValidator<>).MakeGenericType(message.GetType())); 

     if (handler == null) 
     { 
      return new Dictionary<string, string>(); 
     } 

     return (Dictionary<string, string>)handler.GetType() 
      .InvokeMember("ValidateCommand", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, handler, new object[] { message }); 
    } 
} 

또한 내가 사용하고 autofac 웹 API 버전은 다음과 같습니다

컨트롤러 등 :

public class AProtectedReadModelController : ApiController 
{ } 

public class AssessmentController : AProtectedReadModelController 
{ 
    [Route("queries/risk/assessment")] 
    [HttpGet] 
    public ProcessInitialScreenModel GetProcessInitialScreen() 
    { 
     return ...; 
    } 
} 
일부 종료 기능을 돌파 3.1.1

이로드되지 않았습니다.

+0

WebAPI 외부에서 자동 청소이 올바르게 처리되고 있는지 확인할 수 있습니까? –

+0

왜 그렇게하고 싶습니까? 나는 WebAPI와 함께 작업 할 필요가있다. – Marco

+0

핸들러를 사용하는 것과 그 수명이 어느 정도인지를 보여줄 수 있습니까? 객체가 살아있는 상태로 유지되는지 궁금합니다. 그 객체에 의존하는 것이 살아 있기 때문입니다. 예를 들어, 핸들러를 사용하는 것이 싱글 톤이면 처리기는 루트 유효 기간 범위에서 처리되고 루트 범위가 정리 될 때까지 정리되지 않습니다. –

답변

2

요청 평생 범위를 사용하는 대신 DependencyResolver에서 바로 개체를 해결하려고하기 때문에 발생하는 문제입니다.

웹 API를 사용하면 "요청 수명 범위"가 인바운드 요청 메시지에 의해 관리됩니다. DependencyResolver 루트에서 바로 문제를 해결하면 요청의 일부가 아닌 응용 프로그램/최상위 레벨에서 문제가 해결됩니다. 그래서 소유하고있는 평생 범위가 뿌리 수준에 있기 때문에 소유 한 수명 범위가 폐기되지 않기 때문에 폐기 된 것을 볼 수 없습니다.

나는이 질문에 대한 답으로 요청 수명 범위에 대해 긴 토론이 있습니다 Transitioning to AutofacWebApiDependencyResolver from MVC's DependencyResolver - Where is .Current?

, 그것에 대한 대답은 여전히 ​​유효 테스트 시나리오에 대한 다른 질문 회담 동안 - (수동 뭔가를 해결해야하는 경우가있는 가능하다면 서비스 위치를 추천하지 않을 것입니다. 그렇다면 요청 메시지와 관련된 요청 범위에서 그렇게해야합니다.

// In the controller... 
var validatorType = typeof(ICommandValidator<>) 
         .MakeGenericType(message.GetType()); 
var handler = this.Request 
        .GetDependencyScope() 
        .GetService(validatorType); 
+0

도와 주셔서 감사합니다. 이제 왜 InstancePerApiRequest를 사용할 때 null 범위를 얻었는지 알 수 있습니다. – Marco