Ihor Bats
Ihor Bats

Reputation: 169

Simple Injector works without BeginExecutionContextScope, Web Api and OWIN

I have a Console application that hosts WebApi(OWIN) project with Simple Injector, and according to documentation I have to add a few code lines of code to make it work.

But in my case it works even without that configuration, so the question is: What I am doing wrong and why it works?

as for me there are two option: I thing that something was fixed recently and documentation is not up to date OR Actually I did something wrong and it might cause a lot of problems in the future.

Here is my code:

class Program
{
    static void Main(string[] args)
    {
        var disposable = WebApp.Start<Startup>("http://localhost:8085");

        Console.WriteLine("Server Started; Press enter to Quit");
        Console.ReadLine();
    }
}

public class Startup
{
    // This method is required by Katana:
    public void Configuration(IAppBuilder app)
    {
        var container = new Container();

        //app.Use(async (context, next) => {
        //    using (container.BeginExecutionContextScope())
        //    {
        //        await next();
        //    }
        //});

        container.RegisterWebApiRequest<ITestRepo, TestRepo>();

        //container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

        container.Verify();

        var config = ConfigureWebApi();

        config.DependencyResolver =
          new SimpleInjectorWebApiDependencyResolver(container);

        //WebApiConfig.Register(config);
        app.UseWebApi(config);
    }

    private HttpConfiguration ConfigureWebApi()
    {
        var config = new HttpConfiguration();
        HttpRouteCollectionExtensions.MapHttpRoute(config.Routes, "DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });
        return config;
    }

Controller:

public class CompaniesController : ApiController
{
    private readonly ITestRepo _repo;

    public CompaniesController(ITestRepo repo)
    {
        _repo = repo;//i get it here...
    }
}

Is it Ok that it works Thanks Ihor

Upvotes: 2

Views: 1780

Answers (1)

Steven
Steven

Reputation: 172786

Simple Injector's SimpleInjectorWebApiDependencyResolver will ensure that an execution context scope is started when IDependencyResolver.BeginScope is called by the Web API pipeline. This ensures that a ApiController is resolved within a scope and this allows scoped instances to be resolved and injected.

When integrating Web API in OWIN however, you'll often find yourself wanting to execute certain logic in the OWIN pipeline, before or after executing an Web API Controller. But because this code runs either before or after the Web API pipeline, there is no active scope at that point.

If in case you need to run logic that requires scoped instances, you will need to start an execution context scope explicitly using the app.Use(async (context, next) call that you commented out.

Since Simple Injector v2.8, the SimpleInjectorWebApiDependencyResolver will ensure that when IDependencyResolver.BeginScope is called in case it is already running in the context of an existing execution context scope (because for instance you start a scope in the OWIN pipeline, it will not start a new scope itself, but reuse that existing scope. This ensures that all scoped instances will be created just once per request (which is what you normally want).

Long story short, what you are doing has always worked; you only need to register the execution context scope explictly when you are resolving instances in the OWIN pipeline. What has changed is that now Web API ensures that it won't run its own scope, which is often much more convenient.

Upvotes: 4

Related Questions