Skip to content

Constructor-based dependency injection in ASP.NET Web Forms (introduced in .NET Framework 4.7.2) doesn't work #34

@OlegFedko

Description

@OlegFedko

Constructor-based dependency injection in ASP.NET Web Forms (introduced in .NET Framework 4.7.2) doesn't work.

The reason is that BinaryCompatibility.Current.TargetsAtLeastFramework472 is false here:

if (BinaryCompatibility.Current.TargetsAtLeastFramework472 &&

This is because there is a bug in .NET Framework but it was hidden by App Domains, but WebFormsForCore doesn't use App Domains.

Look at System.Web.Hosting.ApplicationManager.CreateAppDomainWithHostingEnvironment:

Here we first time initialize ApplicationData, but there is no TargetFrameworkKey yet (appDomainAdditionalData is empty):

SetApplicationData(bindings, appDomainAdditionalData, AssemblyLoadContext.Default, AppDomain.CurrentDomain);

It will be calculated but not yet added to ApplicationData here:

appDomainAdditionalData[System.Web.Util.BinaryCompatibility.TargetFrameworkKey] = targetFrameworkName;

Then some strange code here that breaks everything:

requireHostExecutionContextManager = new System.Web.Util.BinaryCompatibility(targetFrameworkName).TargetsAtLeastFramework45 ? true : false;

It is because there is implicit call to System.Web.Util.BinaryCompatibility's static constructor:

var targetFramework = ApplicationManager.GetLoadContextData(TargetFrameworkKey) as FrameworkName;

And since there is no TargetFrameworkKey in ApplicationData - System.Web.Util.BinaryCompatibility.Current became .NET Framework 4.0 (VersionUtil.FrameworkDefault)! And now BinaryCompatibility.Current.TargetsAtLeastFramework472 everytime will return false!

At last TargetFrameworkKey is added to ApplicationData, but it is too late:

SetApplicationData(bindings, appDomainAdditionalData, appContext, appDomain);

As I said .NET Framework also has this bug. BUT! Here:

env.Initialize(this, appHost, configMapPathFactory, hostingParameters, policyLevel);

System.Web.dll!System.Web.Hosting.HostingEnvironment.Initialize is called in another AppDomain, and later it calls System.Web.Util.BinaryCompatibility's static constructor again! And that time ApplicationData already has TargetFrameworkKey and BinaryCompatibility.Current.TargetsAtLeastFramework472 is true.

But WebFormsForCore doesn't use App Domains and doesn't call static constructor again.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions