ASP WebForms with System.Web.Http API Controllers- Constructor dependency Injection in controllers not working

Viewed 303

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?

1 Answers
// This fixes controllers injection.
GlobalConfiguration.Configuration.DependencyResolver = new MyDependencyResolver();
Related