3

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?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
EBarr
  • 11,826
  • 7
  • 63
  • 85

1 Answers1

7

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;
}
Ashley Medway
  • 7,151
  • 7
  • 49
  • 71
Steven
  • 166,672
  • 24
  • 332
  • 435
  • "saving the world one software decoupling at a time." Thanks for not taking me to task on the static reference to the container I snuck into my example :-) – EBarr Mar 11 '14 at 12:44
  • @EBarr: It crossed my mind to say something about that, but I had the feeling you heard that argument before :-) – Steven Mar 11 '14 at 12:46
  • It crosses my mind every day...I work in 2 million lines of extreme coupling daily. That was just quick shorthand while working through examples. – EBarr Mar 11 '14 at 12:57
  • Maybe add this to the last post of https://simpleinjector.codeplex.com/discussions/472187 as I was wondering what was going wrong :) – Luuk May 23 '14 at 13:11