I am working on a legacy ASP.NET WebForms system and dependency injection must be implemented. I've already set up DI for the Page classes using Microsoft.Extensions.DependencyInjection and a custom ServiceProvider, which works well enough.
ServiceProvider
public class ServiceProvider : IServiceProvider
{
private readonly IServiceProvider _serviceProvider;
public ServiceProvider(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public object GetService(Type serviceType)
{
try
{
IServiceScope lifetimeScope;
var currentHttpContext = HttpContext.Current;
if (currentHttpContext != null)
{
lifetimeScope = (IServiceScope)currentHttpContext.Items[typeof(IServiceScope)];
if (lifetimeScope == null)
{
void CleanScope(object sender, EventArgs args)
{
if (sender is HttpApplication application)
{
application.RequestCompleted -= CleanScope;
lifetimeScope.Dispose();
}
}
lifetimeScope = _serviceProvider.CreateScope();
currentHttpContext.Items.Add(typeof(IServiceScope), lifetimeScope);
currentHttpContext.ApplicationInstance.RequestCompleted += CleanScope;
}
}
else
{
lifetimeScope = _serviceProvider.CreateScope();
}
return ActivatorUtilities.GetServiceOrCreateInstance(lifetimeScope.ServiceProvider, serviceType);
}
catch (InvalidOperationException)
{
//No public ctor available, revert to a private/internal one
return Activator.CreateInstance(serviceType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, null, null);
}
}
}
And in Global.asax
IServiceCollection services = this.ConfigureServices(new ServiceCollection());
var provider = new Infrastructure.DI.ServiceProvider(services.BuildServiceProvider());
HttpRuntime.WebObjectActivator = provider;
On the client side of this application there is a piece of JS that must call the server via ajax. Because of the design of this legacy application it's not an option to call a [WebMethod] on the respective .aspx page, so a System.Web.Http API Controller was introduced to handle this call.
I expected that by setting up DI like this in the Global.asax that I could just inject my needed service in the controller constructor, but that does not work and the ControllerContext returns a null HttpConfiguration.
How can I use my current DI and provide it to my controllers?