There is an fantastic Stackoverflow answer on how to use Microsoft.Extensions.DependencyInjection inside of a WebAPI 2 project (ASP.NET Full Framework). While it’s not cutting edge, it is a good middle ground solution when rewriting an entire ASP.NET application to ASP.NET Core seems out of the realm of possibility.
I took the code snippet and broke it apart a little bit to create a reusable project to house it. It’s not great, so I don’t really think it’s worth creating a github repo or a nuget package, but if you want to drop it into a project in your code base it could help out.
Here’s an example usage in a .NET 4.8 ASP.NET MVC / WebApi 2 based project:
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using System.Web; | |
using System.Web.Http; | |
using System.Web.Http.Controllers; | |
using System.Web.Http.Dependencies; | |
using System.Web.Http.ExceptionHandling; | |
using System.Web.Http.Filters; | |
using System.Web.Mvc; | |
using System.Web.Optimization; | |
using System.Web.Routing; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.DependencyInjection.Extensions; | |
using DependencyInjection.AspNet.WebApi; | |
using IDependencyResolver = System.Web.Http.Dependencies.IDependencyResolver; | |
using IExceptionFilter = System.Web.Http.Filters.IExceptionFilter; | |
namespace YourNamespace | |
{ | |
/// <summary> | |
/// https://stackoverflow.com/questions/50358349/using-microsoft-extension-dependencyinjection-in-asp-net-web-api2 | |
/// </summary> | |
public class WebApiApplication : System.Web.HttpApplication | |
{ | |
protected void Application_Start() | |
{ | |
AreaRegistration.RegisterAllAreas(); | |
GlobalConfiguration.Configure(WebApiConfig.Register); | |
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); | |
RouteConfig.RegisterRoutes(RouteTable.Routes); | |
BundleConfig.RegisterBundles(BundleTable.Bundles); | |
GlobalConfiguration.Configuration.AddMicrosoftDependencyInjectionProvider(services => | |
{ | |
services.AddControllersAsServices(System.Reflection.Assembly.GetExecutingAssembly()); | |
}); | |
} | |
} |
And, it relies on a DependencyInjection.AspNet.WebApi library, which is targeting framework net48 (here’s the .csproj):
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<TargetFramework>net48</TargetFramework> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.7" /> | |
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.3" /> | |
</ItemGroup> | |
<ItemGroup> | |
<Reference Include="System.Web" /> | |
</ItemGroup> | |
</Project> |
And, here’s the original stackoverflow posts code, just slightly modified:
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using System.Web; | |
using System.Web.Http; | |
using System.Web.Http.Controllers; | |
using System.Web.Http.Dependencies; | |
using Microsoft.Extensions.DependencyInjection; | |
namespace DependencyInjection.AspNet.WebApi | |
{ | |
public static class HttpConfigurationExtensions | |
{ | |
public static IServiceProvider AddMicrosoftDependencyInjectionProvider( | |
this HttpConfiguration config, | |
Action<IServiceCollection> configure = null | |
) { | |
var provider = IServiceCollectionExtensions.BuildServiceProvider(configure); | |
var resolver = new DefaultDependencyResolver(provider); | |
config.DependencyResolver = resolver; | |
return provider; | |
} | |
} | |
public static class HttpApplicationExtensions | |
{ | |
public static IServiceProvider BuildServiceProvider(this HttpApplication application, Action<IServiceCollection> configure = null) | |
{ | |
var provider = IServiceCollectionExtensions.BuildServiceProvider(configure); | |
return provider; | |
} | |
} | |
public static class IServiceCollectionExtensions | |
{ | |
public static IServiceProvider BuildServiceProvider(Action<IServiceCollection> configure = null) | |
{ | |
var services = new ServiceCollection(); | |
configure?.Invoke(services); | |
var serviceProvider = services.BuildServiceProvider(); | |
return serviceProvider; | |
} | |
public static IServiceCollection AddControllersAsServices(this IServiceCollection services, | |
Assembly controllersAssembly) | |
{ | |
var controllerTypes = GetControllers(controllersAssembly); | |
foreach (var type in controllerTypes) | |
{ | |
services.AddTransient(type); | |
} | |
return services; | |
} | |
public static IEnumerable<Type> GetControllers(Assembly controllersAssembly) | |
{ | |
var controllers = controllersAssembly.GetExportedTypes() | |
.Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition) | |
.Where(t => typeof(IHttpController).IsAssignableFrom(t) | |
|| t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)); | |
return controllers; | |
} | |
} | |
public class DefaultDependencyResolver : IDependencyResolver | |
{ | |
protected IServiceProvider ServiceProvider { get; set; } | |
public DefaultDependencyResolver(IServiceProvider serviceProvider) | |
{ | |
this.ServiceProvider = serviceProvider; | |
} | |
public object GetService(Type serviceType) | |
{ | |
return this.ServiceProvider.GetService(serviceType); | |
} | |
public IEnumerable<object> GetServices(Type serviceType) | |
{ | |
return this.ServiceProvider.GetServices(serviceType); | |
} | |
public IDependencyScope BeginScope() | |
{ | |
return new DefaultDependencyResolver(this.ServiceProvider.CreateScope().ServiceProvider); | |
} | |
public void Dispose() | |
{ | |
// you can implement this interface just when you use .net core 2.0 | |
// this.ServiceProvider.Dispose(); | |
} | |
} | |
} |
0 comments:
Post a Comment