How to use DI container when OwinStartup

E-Cheng Liu picture E-Cheng Liu · Nov 5, 2013 · Viewed 49.7k times · Source

It's a Web API 2 project.

When I implement DI using Ninject, I got an error message

An error occurred when trying to create a controller of type 'TokenController'. Make sure that the controller has a parameterless public constructor.

[assembly: OwinStartup(typeof(Web.Startup))]

namespace Web
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            ConfigureWebApi(app);
        }
    }
}

public class TokenController : ApiController
{

    private IUserService _userService;

    public TokenController(IUserService userService)
    {
        this._userService = userService;
    }

    [Route("api/Token")]
    public HttpResponseMessage PostToken(UserViewModel model)
    {
        if (_userService.ValidateUser(model.Account, model.Password))
        {
            ClaimsIdentity identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType);
            identity.AddClaim(new Claim(ClaimTypes.Name, model.Account));
            AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
            var currentUtc = new SystemClock().UtcNow;
            ticket.Properties.IssuedUtc = currentUtc;
            ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
            return new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new ObjectContent<object>(new
                {
                    UserName = model.Account,
                    AccessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket)
                }, Configuration.Formatters.JsonFormatter)
            };
        }

        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }
}

When I add <add key="owin:AutomaticAppStartup" value="false" /> to web.config

Ninject works fine, but Startup.OAuthBearerOptions.AccessTokenFormat becomes to null

How to use DI container with OWIN?

UPDATE

Implement IDependencyResolver and use the WebAPI Dependency Resolver as below

public void ConfigureWebApi(IAppBuilder app)
{
    HttpConfiguration config = new HttpConfiguration();

    config.DependencyResolver = new NinjectDependencyResolver(NinjectWebCommon.CreateKernel());

    app.UseWebApi(config);
}

NinjectDependencyResolver


In Simple Injector case

public void ConfigureWebApi(IAppBuilder app)
{
    HttpConfiguration config = new HttpConfiguration();

    var container = new Container();
    container.Register<IUserService, UserService>();
    config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

    app.UseWebApi(config);
}

SimpleInjectorWebApiDependencyResolver

Answer

Maxime Rouiller picture Maxime Rouiller · Dec 5, 2013

You might want to take a look at this blog post.

It's using Unity but it should end-up being the same.

Basically, use the WebAPI Dependency Resolver. Make sure that everything is mapped properly and it should be fine.

If after setting up your DI you still have problem with your OAuth token, let me know.

Cheers