I'm new to SimpleInjector and working through examples using it with WebAPI. I used the SimpleInjector.Integration.WebApi.WebHost.QuickStart nu-get package, then registered a simple type for my tests, like so:

container.RegisterWebApiRequest<SimplePOCO>();

From inside an ApiController method, I am able to request an instance. So far, so good. I wanted to expand my test to earlier in pipeline, specifically a Message Handler. So I created a simple DelegatingHandler like :

protected override Task<HttpResponseMessage> SendAsync(
                                           HttpRequestMessage request,
                                           CancellationToken cancellationToken) {
    Task<HttpResponseMessage> response;

    var container =  SimpleInjectorWebApiInitializer.container;
    var rc = container.GetInstance<SimplePOCO>();
    response = base.SendAsync(request, cancellationToken);
    response.ContinueWith((responseMsg) =>  {   });

    return response;
}

Calling GetInstance<SimplePOCO>() errors with the following message:

The registered delegate for type SimplePOCO threw an exception. The SimplePOCO is registered as 'Web API Request' lifestyle, but the instance is requested outside the context of a Web API Request.

Am I doing something wrong? Are Message Handlers outside the lifetime of a WebAPI request? This seems odd, considering how integral they are. If message handlers are outside the lifetime is there a longer lifetime that encompasses the message handlers?

有帮助吗?

解决方案

Are Message Handlers outside the lifetime of a WebAPI request?

Well, as a matter of fact, they are. Unless you trigger the creation of the IDependencyScope explicitly, the IDependencyScope gets created (by calling request.GetDependencyScope()) inside the DefaultHttpControllerActivator.Create method.

To make sure your code runs within a dependency scope, all you have to do is call request.GetDependencyScope() explicitly inside your handler:

protected override Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken) {

    // trigger the creation of the scope.
    request.GetDependencyScope();

    Task<HttpResponseMessage> response;

    var container =  SimpleInjectorWebApiInitializer.container;
    var rc = container.GetInstance<SimplePOCO>();
    response = base.SendAsync(request, cancellationToken);
    response.ContinueWith((responseMsg) =>  {   });

    return response;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top