2014-04-15 22 views
1

我有以下代码片段来构建的依赖关系: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的版本是:3.1.1 这也打破了一些退出功能:

控制器这样:

public class AProtectedReadModelController : ApiController 
{ } 

public class AssessmentController : AProtectedReadModelController 
{ 
    [Route("queries/risk/assessment")] 
    [HttpGet] 
    public ProcessInitialScreenModel GetProcessInitialScreen() 
    { 
     return ...; 
    } 
} 

未加载。

+0

您是否确认Autofac正在妥善处理在WebAPI之外的处理? –

+0

我为什么要这么做?我需要这个与WebAPI一起工作。 – Marco

+0

你能告诉我们什么在使用处理程序,以及它的生命周期是什么?我很好奇,如果对象被保持活着,因为依赖它的东西是活着的。例如,如果消耗处理程序的消息是单例消息,那么该消息处理程序将在根作用域范围内解析,并且在根作用域被清除之前不会被清理。 –

回答

2

您遇到的挑战是因为您尝试直接从DependencyResolver中解析对象,而不是使用请求生存期范围。

当您使用Web 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时,我得到了一个空作用域。 – Marco

相关问题