2

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 Answer 1

1
// This fixes controllers injection.
GlobalConfiguration.Configuration.DependencyResolver = new MyDependencyResolver();
Sign up to request clarification or add additional context in comments.

1 Comment

Went this route and just used Autofac in the startup project and passed the IServiceCollection registered dependencies from the other projects into the Autofac container

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.