Skip to content

Instantly share code, notes, and snippets.

@andriybuday
Last active April 16, 2024 15:58
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andriybuday/a96bfc7845ba1514561a4e6f146a629d to your computer and use it in GitHub Desktop.
Save andriybuday/a96bfc7845ba1514561a4e6f146a629d to your computer and use it in GitHub Desktop.
Microsoft.Extensions.DependencyInjection with OWIN Self-Hosted WebAPI
// ...
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;
}
}
@alizim
Copy link

alizim commented Feb 1, 2018

thank you for your example.
if you add
`
class DependencyScope : IDependencyScope
{
private readonly IServiceScope _scope;

			public DependencyScope(IServiceProvider serviceProvider)
			{
					_scope = serviceProvider.CreateScope();
			}


			public void Dispose()
			{
					_scope.Dispose();
			}

			public object GetService(Type serviceType)
			{
					return _scope.ServiceProvider.GetService(serviceType);
			}

			public IEnumerable<object> GetServices(Type serviceType)
			{
					return _scope.ServiceProvider.GetServices(serviceType);
			}

}
`

and return in DefaultDependencyResolver
public IDependencyScope BeginScope() { return new DependencyScope(provider); }

you have also full support for scopes

@kant2002
Copy link

kant2002 commented May 18, 2019

Without addition probosed by @UnknownAngel the server will leak memory.

@kant2002
Copy link

Since this pattern maybe used together with MVC, here the small modification for making similar code working with MVC
kant2002/MvcDIMemoryLeak@b6984d2

@mhDuke
Copy link

mhDuke commented Apr 16, 2024

@kant2002

Without addition probosed by @UnknownAngel the server will leak memory.

could you please point out which part would cause the memory leakage. What is proposed by @UnknownAngel? I see b6984d2 but im unable to figure out what it exactly solves!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment