I could not find an example showing how to use Microsoft.Extensions.DependencyInjection as IoC in OWIN Self-Hosted WebApi, as a result here is this blog post.
Let’s imagine that you have WebApi that you intend to Self-Host using OWIN. This is fairly easy to do. All you will need to do is to use Microsoft.Owin.Hosting.WebApp.Start
method and then have a bit of configuration on IAppBuilder
(check out ServiceHost.cs
and WebApiStartup.cs
in the gist below).
It becomes a bit more complicated when you want to use an IoC container, as OWIN’s implementation takes care of creating Controller instances. To use another container you will need to tell the configuration to use implementation of IDependencyResolver
(see WebApiStartup.cs
and DefaultDependencyResolver.cs
). DefaultDependencyResolver.cs
is a very simple implementation of the resolver.
In case you are wondering what Microsoft.Extensions.DependencyInjection
is. It is nothing more than a lightweight DI abstractions and basic implementation (github page). It is currently used in ASP.NET Core and EF Core, but nothing prevents you from using it in “normal” .NET. You can integrate it with more feature-rich IoC frameworks. At the moment it looks like Autofac has the best integration and nice documentation in place. See OWIN integration.
Rest is just usual IoC clutter. See the gist
// ... | |
using Microsoft.Owin.Hosting; | |
// ... | |
public class ServiceHost | |
{ | |
private IDisposable server = null; | |
const string baseAddress = "https://*:443"; | |
public void Start() | |
{ | |
server = WebApp.Start<WebApiStartup>(baseAddress); | |
} |
public class WebApiStartup | |
{ | |
public void Configuration(IAppBuilder appBuilder) | |
{ | |
appBuilder.Map("/api", api => | |
{ | |
var config = new HttpConfiguration(); | |
config.MapHttpAttributeRoutes(); | |
// Add IoC | |
var serviceProvider = IocStartup.BuildServiceProvider(); | |
config.DependencyResolver = new DefaultDependencyResolver(serviceProvider); | |
// ... | |
api.UseCors(CorsOptions.AllowAll); | |
api.UseWebApi(config); | |
}); | |
// ... |
// ... | |
using System.Web.Http.Dependencies; | |
using Microsoft.Extensions.DependencyInjection; | |
// ... | |
public class DefaultDependencyResolver : IDependencyResolver | |
{ | |
private readonly IServiceProvider provider; | |
public DefaultDependencyResolver(IServiceProvider provider) | |
{ | |
this.provider = provider; | |
} | |
public object GetService(Type serviceType) | |
{ | |
return provider.GetService(serviceType); | |
} | |
public IEnumerable<object> GetServices(Type serviceType) | |
{ | |
return provider.GetServices(serviceType); | |
} | |
public IDependencyScope BeginScope() | |
{ | |
return this; | |
} | |
public void Dispose() | |
{ | |
} | |
} |
public static class IocStartup | |
{ | |
public static IServiceProvider BuildServiceProvider() | |
{ | |
var services = new ServiceCollection(); | |
// Register all dependent services | |
// | |
// IocSomeAssembly.Register(services); | |
// | |
// services.AddTransient<ISomething, Something>() | |
// For WebApi controllers, you may want to have a bit of reflection | |
var controllerTypes = Assembly.GetExecutingAssembly().GetExportedTypes() | |
.Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition) | |
.Where(t => typeof(ApiController).IsAssignableFrom(t) | |
|| t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)); | |
foreach (var type in controllerTypes) | |
{ | |
services.AddTransient(type); | |
} | |
// It is only that you need to get service provider in the end | |
var serviceProvider = services.BuildServiceProvider(); | |
return serviceProvider; | |
} | |
} |
I hope this blog post helps you with integrating Microsoft.Extensions.DependencyInjection in WebApi hosted via OWIN.