Dependency Injection in ASP.NET Web Forms

Shout out to all my ASP.NET Web Forms devs out there. This one is for you.

As much as we’re stoked about .NET Core leading us into the future, many of us still need to keep our heads down, maintaining or enhancing decades old systems built upon our favorite stable elder: Web Forms.

Some news came and went that I recently tried out and wanted to share with you in case you missed it.

A chance for you to try out something you’ve probably heard about 1000 times: Dependency injection!

If you’re not sure what dependency injection is, check out the Why Series DI article. It’s also a good one, even if you don’t use Web Forms.

Dependency Injection now available in Web Forms via Unity

The original news article is here which explains how to do it, but I’ll give you my personal rendition below, along with any gotchas you might encounter (there are a couple not mentioned in the original article).

Step 1: Upgrade all the projects in your solution to target at least .NET Framework 4.7.2

This feature is only available starting at 4.7.2, so you’ll need to target 4.7.2 across all your projects. In Visual Studio that means right clicking the project, clicking Properties, and in the Application section, select .NET 4.7.2 from the Target Framework dropdown.

You’ll also need to set the target framework in your web.config file as an attribute of the httpRuntime element.

1
2
3
  <system.web>
    <httpRuntime targetFramework="4.7.2" />
    ...

When I made this change, I was already at 4.7.1 so it was mostly a seamless upgrade, but you’ll want to be sure to compile your projects and iron out any build errors.

Possible Gotcha: Disabling unobtrusive validation mode

I can’t say for certain if the upgrade caused this issue, but soon after I did it, I noticed some errors appearing related to javascript on some of my existing pages, and the solution was to disable a newly defaulted feature known as Unobtrusive Validation Mode.

To disable this feature, add None as the value of this key in your web.config file.

1
2
3
<appSettings>
  <add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
</appSettings>

Step 2: Install the Microsoft.AspNet.WebFormsDependencyInjection.Unity NuGet Package to your web application project (the project that your Global.asax.cs file resides.)

This is the Unity package that will allow you to inject dependencies at application startup time.

Step 3: Add the Unity container to the Global.asax.cs file and register a type for injection.

Within your Global.asax.cs file, you’ll need to add these two using references:

1
2
using Microsoft.AspNet.WebFormsDependencyInjection.Unity;
using Unity;

Then in your Application_Start method, add the call to create the container and register a type:

1
2
3
4
5
6
protected void Application_Start(Object sender, EventArgs e)
{
    var container = this.AddUnity();

    container.RegisterType<IQuoteService, FakeQuoteService>();
}

In this example, whenever an IQuoteService is used as a constructor argument for one of your pages or controls, a FakeQuoteService will be injected.

Step 4: Use the interface within a page or user control.

To reap the benefits, you simply need to add the interface as a constructor parameter like so:

1
2
3
4
5
6
private IQuoteService _myQuoteService;

public QuotePage(IQuoteService myQuoteService)
{
    _myQuoteService = myQuoteService;
}

If everything is set up correctly, this page will be working with a FakeQuoteService at runtime yet conveniently hidden behind an interface.

Quirk: A build error appears intermittently

On occasion you may see a build error complaining about the lack of a zero-argument constructor on the page. I notice that this error will magically go away depending on the context. Someone else suggested using property injection with the Dependency attribute on pages to get around this, but i didn’t find that was necessary.

Enjoy!

Hop on the train to Visual Studio wizardy and get 6 practical VS tips over the next 6 months