Gyum Fox
Gyum Fox

Reputation: 3627

How to use LightInject with Web Forms?

I have a legacy ASP.Net Web Forms application targeting .Net 4.8 in which I would like to use dependency injection. Our engine of choice is LightInject.

With the help of this answer and the source code of ContainerServiceProvider.Cs from the Microsoft.AspNet.WebFormsDependencyInjection.Unity project, I was able to create my own IServiceProvider container for LightInject and assign it to the HttpRuntime.WebObjectActivator:

void Application_Start(object sender, EventArgs e)
{
    ...

    // Register the service provider
    ContainerServiceProvider containerServiceProvider = new ContainerServiceProvider(HttpRuntime.WebObjectActivator);
    HttpRuntime.WebObjectActivator = containerServiceProvider;

    // Register services used with dependency injection
    var container = containerServiceProvider.Container;
    container.Register<IDummyService, DummyService>();
}

I am able to register my services, and access them via HttpRuntime.WebObjectActivator.GetService().

However, I am yet to see constructor (or property) injection in action... When I declare an ASPX page (say About.aspx) with the following constructor, I get an error when I access the page: "'About' does not contain a constructor that takes 0 arguments"

public About(IDummyService dummy)
{
    ...
}

A screenshot of the error that occurs when accessing the page

EDIT: this was because the website was targetting an older version of .Net in its config file. Retargetting 4.8 fixed this first issue.

Now the issue is different: if I debug the ContainerServiceProvider I implemented, I can see that .Net tries to get the ASP.about_aspx service that's defined in a temporary assembly (eg: C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/e15e9fc8/41270200/App_Web_cdps00j5.DLL), which my LightInject container doesn't know.

So I'm not sure what else I have to do to have constructor injection working in my pages. I'm assuming that I have to tell LightInject that my pages are candidates for dependency injection somehow, but I have no idea on how to do that (the documentation is very scarce). Also, I'm wondering how Unity works because I couldn't see any magic in the source code of Microsoft.AspNet.WebFormsDependencyInjection.Unity apart from the implementation of the ContainerServiceProvider.cs that I reused.

UPDATE: I have tried manually registering all the types that implement pages, but it did not work:

foreach (var assembly in BuildManager.GetReferencedAssemblies().Cast<Assembly>())
{
    try
    {
        container.RegisterAssembly(
            assembly,
            () => new LightInject.PerScopeLifetime(),
            (serviceType, implementingType) => serviceType.IsSubclassOf(typeof(System.Web.UI.Page)));
    }
    catch
    {
    }
}

Upvotes: 2

Views: 284

Answers (0)

Related Questions