Microsoft.Extensions.DependencyInjection - ASP.NET

on Monday, August 17, 2020

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();
}
}
}
view raw Extensions.cs hosted with ❤ by GitHub

0 comments:

Post a Comment


Creative Commons License
This site uses Alex Gorbatchev's SyntaxHighlighter, and hosted by herdingcode.com's Jon Galloway.