15

This is for MVC5 and the new pipeline. I cannot find a good example anywhere.

public static void ConfigureIoc(IAppBuilder app)
{
    var builder = new ContainerBuilder();
    builder.RegisterControllers(typeof(WebApiApplication).Assembly);
    builder.RegisterApiControllers(typeof(WebApiApplication).Assembly);
    builder.RegisterType<SecurityService().AsImplementedInterfaces().InstancePerApiRequest().InstancePerHttpRequest();

    var container = builder.Build();
    app.UseAutofacContainer(container);
}

The above code doesn't inject. This worked fine before attempting to switch to OWIN pipeline. Just can't find any information on DI with OWIN.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Shane
  • 4,185
  • 8
  • 47
  • 64
  • 2
    And the question is? Btw, why do you register "SecurityService" after the container's been built? – Alexandr Nikitin Nov 19 '13 at 08:17
  • edited sample to move Security service to before. This was just an example. I'm trying to find out if AutoFac is supporting OWIN pipeline yet. – Shane Nov 19 '13 at 13:50
  • There is an Autofac OWIN package available as of february 2014. https://www.nuget.org/packages/Autofac.Owin/ At time of writing it's still in prerelease, so don't forget to change the dropdown if you can't find it in the VS UI. – David De Sloovere Jun 19 '14 at 14:45

1 Answers1

13

Update: There's an official Autofac OWIN nuget package and a page with some docs.

Original:
There's a project that solves the problem of IoC and OWIN integration called DotNetDoodle.Owin.Dependencies available through NuGet. Basically Owin.Dependencies is an IoC container adapter into OWIN pipeline.

Sample startup code looks like:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        IContainer container = RegisterServices();
        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute("DefaultHttpRoute", "api/{controller}");

        app.UseAutofacContainer(container)
           .Use<RandomTextMiddleware>()
           .UseWebApiWithContainer(config);
    }

    public IContainer RegisterServices()
    {
        ContainerBuilder builder = new ContainerBuilder();

        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        builder.RegisterOwinApplicationContainer();

        builder.RegisterType<Repository>()
               .As<IRepository>()
               .InstancePerLifetimeScope();

        return builder.Build();
    }
}

Where RandomTextMiddleware is implementation of OwinMiddleware class from Microsoft.Owin.

"The Invoke method of the OwinMiddleware class will be invoked on each request and we can decide there whether to handle the request, pass the request to the next middleware or do the both. The Invoke method gets an IOwinContext instance and we can get to the per-request dependency scope through the IOwinContext instance."

Sample code of RandomTextMiddleware looks like:

public class RandomTextMiddleware : OwinMiddleware
{
    public RandomTextMiddleware(OwinMiddleware next)
        : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        IServiceProvider requestContainer = context.Environment.GetRequestContainer();
        IRepository repository = requestContainer.GetService(typeof(IRepository)) as IRepository;

        if (context.Request.Path == "/random")
        {
            await context.Response.WriteAsync(repository.GetRandomText());
        }
        else
        {
            context.Response.Headers.Add("X-Random-Sentence", new[] { repository.GetRandomText() });
            await Next.Invoke(context);
        }
    }
}

For more information take a look at the original article.

Alexandr Nikitin
  • 7,258
  • 2
  • 34
  • 42
  • Trying to implement this, but can't figure what the purpose of RandomTextMiddleware is? I don't want that, just want to register my dependencies via injection. – Shane Nov 26 '13 at 01:02
  • 1
    @Shane `RandomTextMiddleware` is just there for the sample showing that you can go through the pipeline and get your dependencies everywhere. So, you can just omit that. – tugberk Dec 08 '13 at 18:44
  • @tugberk So you are saying for this just to omit this .Use line and it should work? app.UseAutofacContainer(container) .Use() .UseWebApiWithContainer(config); – Shane Dec 09 '13 at 19:20
  • @Shane yes, drop `Use()` from there. Register whatever you want inside your pipeline. – tugberk Dec 10 '13 at 15:50
  • @tugberk So this will resolve all dependencies we would normally set in Application_Start() in Global? Essentially we could leave that empty? – Ingó Vals Jan 13 '14 at 10:38
  • @IngóVals Did you have a chance to try? – Alexandr Nikitin Jan 14 '14 at 03:56
  • @AlexandrNikitin Tried it just now and it works fine. I'm using autofac so all extension are there. You seem to register the application layer using the RegisterOwinApplicationContainer(); – Ingó Vals Jan 14 '14 at 08:56
  • What happens to DependencyResolver? It seems not to be registered. – Roland Jan 22 '14 at 22:45
  • There is an official NuGet Autofac.Owin package – Muhammad Rehan Saeed Aug 15 '14 at 14:42
  • 3
    what is `RegisterOwinApplicationContainer`? – George Mauer Apr 28 '15 at 19:35