diff --git a/.cspell/dot-net.txt b/.cspell/dot-net.txt
index 0c6eaf4994..6970f20a1e 100644
--- a/.cspell/dot-net.txt
+++ b/.cspell/dot-net.txt
@@ -31,3 +31,4 @@ corelib
 ASPNETCORE
 HOSTINGSTARTUPASSEMBLIES
 Bootstrapper
+NETFX
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 614040e89b..2e68964d3c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -77,6 +77,17 @@ jobs:
         with:
           name: bin-${{ matrix.machine }}
           path: bin/tracer-home
+      - name: Delete SQL Server MSI
+        if: ${{ runner.os == 'Windows' }}
+        shell: bash
+        run: |
+          rm SqlLocalDB.msi
+      - name: Generated files unchanged
+        shell: bash
+        run: |
+          git status
+          git diff
+          [[ -z "$(git status --porcelain)" ]]
 
   build-container:
     strategy:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c728d5649d..3709e0614a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,10 @@ This beta release is built on top of [OpenTelemetry .NET](https://github.com/ope
  `ConfigureTracesOptions(StackExchangeRedisCallsInstrumentationOptions options)`.
 - Add plugin support for
  `ConfigureMetricsOptions(AspNetCoreMetricsInstrumentationOptions options)`.
+- Add automatic assembly redirection for .NET Framework applications. The redirection
+ can be enabled or disabled via the
+ `OTEL_DOTNET_AUTO_NETFX_REDIRECT_ENABLED` environment variable.
+ See the [additional settings](./docs/config.md#additional-settings) table for details.
 
 ### Changed
 
diff --git a/build/AssemblyRedirectionSourceGenerator.cs b/build/AssemblyRedirectionSourceGenerator.cs
new file mode 100644
index 0000000000..4e0680094f
--- /dev/null
+++ b/build/AssemblyRedirectionSourceGenerator.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Mono.Cecil;
+using Serilog;
+
+public class AssemblyRedirectionSourceGenerator
+{
+    public static void Generate(string assembliesFolderPath, string generatedFilePath)
+    {
+        Log.Debug("Generating assembly redirection file {0}", generatedFilePath);
+        var assemblies = new SortedDictionary<string, AssemblyNameDefinition>();
+        foreach (var fileName in Directory.EnumerateFiles(assembliesFolderPath))
+        {
+            try
+            {
+                using var moduleDef = ModuleDefinition.ReadModule(fileName);
+                var assemblyDef = moduleDef.Assembly.Name!;
+                if (assemblyDef.Name == "netstandard")
+                {
+                    // Skip netstandard, since it doesn't need redirection.
+                    continue;
+                }
+
+                assemblies[assemblyDef.Name] = assemblyDef;
+                Log.Debug("Adding {0} assembly to the redirection map. Targeted version {1}", assemblyDef.Name, assemblyDef.Version);
+            }
+            catch (BadImageFormatException)
+            {
+                Log.Debug("Skipping \"{0}\" couldn't open it as a managed assembly", fileName);
+            }
+        }
+
+        var sourceContents = GenerateSourceContents(assemblies);
+
+        File.WriteAllText(generatedFilePath, sourceContents, Encoding.UTF8);
+        Log.Information("Assembly redirection source generated {0}", generatedFilePath);
+    }
+
+    static string GenerateSourceContents(SortedDictionary<string, AssemblyNameDefinition> assemblies)
+    {
+        var sb = new StringBuilder(assemblies.Count * 256);
+        sb.AppendLine($"// Auto-generated file, do not change it - generated by the {nameof(AssemblyRedirectionSourceGenerator)} type");
+        sb.Append(@"
+#include ""cor_profiler.h""
+
+#ifdef _WIN32
+namespace trace
+{
+void CorProfiler::InitNetFxAssemblyRedirectsMap()
+{
+    assembly_version_redirect_map_.insert({
+");
+        foreach (var kvp in assemblies)
+        {
+            var v = kvp.Value.Version!;
+            sb.AppendLine($"        {{ L\"{kvp.Key}\", {{{v.Major}, {v.Minor}, {v.Build}, {v.Revision}}} }},");
+        }
+
+        sb.Append(@"    });
+}
+}
+#endif
+");
+
+        return sb.ToString();
+    }
+}
diff --git a/build/Build.Steps.Windows.cs b/build/Build.Steps.Windows.cs
index 6292b50b03..5214d09755 100644
--- a/build/Build.Steps.Windows.cs
+++ b/build/Build.Steps.Windows.cs
@@ -1,10 +1,8 @@
 using System.IO;
 using Nuke.Common;
 using Nuke.Common.IO;
-using Nuke.Common.ProjectModel;
 using Nuke.Common.Tooling;
 using Nuke.Common.Tools.Docker;
-using Nuke.Common.Tools.DotNet;
 using Nuke.Common.Tools.MSBuild;
 using Serilog;
 using static Nuke.Common.EnvironmentInfo;
@@ -17,6 +15,7 @@ partial class Build
     Target CompileNativeSrcWindows => _ => _
         .Unlisted()
         .After(CompileManagedSrc)
+        .After(GenerateNetFxAssemblyRedirectionSource)
         .OnlyWhenStatic(() => IsWin)
         .Executes(() =>
         {
@@ -118,4 +117,16 @@ partial class Build
                 .SetProcessWorkingDirectory(aspNetProject.Parent)
             );
         });
+
+    Target GenerateNetFxAssemblyRedirectionSource => _ => _
+        .Unlisted()
+        .After(PublishManagedProfiler)
+        .OnlyWhenStatic(() => IsWin)
+        .Executes(() =>
+        {
+            var netFxAssembliesFolder = TracerHomeDirectory / MapToFolderOutput(TargetFramework.NET462);
+            var generatedSourceFile = SourceDirectory / Projects.AutoInstrumentationNative / "netfx_assembly_redirection.h";
+
+            AssemblyRedirectionSourceGenerator.Generate(netFxAssembliesFolder, generatedSourceFile);
+        });
 }
diff --git a/build/Build.Steps.cs b/build/Build.Steps.cs
index 579a0d5637..4f68ac71c7 100644
--- a/build/Build.Steps.cs
+++ b/build/Build.Steps.cs
@@ -198,11 +198,6 @@ partial class Build
                 .EnableNoRestore()
                 .SetFramework(TargetFramework.NET6_0)
                 .SetOutput(TracerHomeDirectory / MapToFolderOutput(TargetFramework.NET6_0)));
-
-            string MapToFolderOutput(TargetFramework targetFramework)
-            {
-                return targetFramework.ToString().StartsWith("net4") ? "netfx" : "net";
-            }
         });
 
     Target PublishNativeProfiler => _ => _
@@ -565,4 +560,9 @@ private void RunBootstrappingTests()
             }
         }
     }
+
+    private string MapToFolderOutput(TargetFramework targetFramework)
+    {
+        return targetFramework.ToString().StartsWith("net4") ? "netfx" : "net";
+    }
 }
diff --git a/build/Build.cs b/build/Build.cs
index 0a28c32033..56188d617a 100644
--- a/build/Build.cs
+++ b/build/Build.cs
@@ -28,7 +28,7 @@ partial class Build : NukeBuild
     [Parameter("Test projects filter. Optional, default matches all test projects. The project will be selected if the string is part of its name.")]
     readonly string TestProject = "";
 
-    [Parameter("Test name fitler. Optional")]
+    [Parameter("Test name filter. Optional")]
     readonly string TestName;
 
     [Parameter("Number of times each dotnet test is run. Default is '1'")]
@@ -88,6 +88,7 @@ void DeleteReparsePoints(string path)
         .DependsOn(Restore)
         .DependsOn(CompileManagedSrc)
         .DependsOn(PublishManagedProfiler)
+        .DependsOn(GenerateNetFxAssemblyRedirectionSource)
         .DependsOn(CompileNativeSrc)
         .DependsOn(PublishNativeProfiler)
         .DependsOn(CopyIntegrationsJson)
diff --git a/build/_build.csproj b/build/_build.csproj
index f94e5f1b74..5b8462ce80 100644
--- a/build/_build.csproj
+++ b/build/_build.csproj
@@ -11,6 +11,7 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <PackageReference Include="Mono.Cecil" Version="0.11.4" />
     <PackageReference Include="Nuke.Common" Version="6.3.0" />
     <PackageReference Include="Nuget.CommandLine" Version="6.3.1" ExcludeAssets="all" />
   </ItemGroup>
diff --git a/docs/config.md b/docs/config.md
index 93d964ea5d..cbf856bdd8 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -243,6 +243,7 @@ Important environment variables include:
 | `OTEL_DOTNET_AUTO_OPENTRACING_ENABLED`         | Enables OpenTracing tracer.                                                                                                                                                                                                                                                                                                                                                                        | `false`       |
 | `OTEL_DOTNET_AUTO_LOGS_ENABLED`                | Enables logs.                                                                                                                                                                                                                                                                                                                                                                                      | `true`        |
 | `OTEL_DOTNET_AUTO_METRICS_ENABLED`             | Enables metrics.                                                                                                                                                                                                                                                                                                                                                                                   | `true`        |
+| `OTEL_DOTNET_AUTO_NETFX_REDIRECT_ENABLED`      | Enables automatic redirection of the assemblies used by the automatic instrumentation on the .NET Framework.                                                                                                                                                                                                                                                                                       | `true`        |
 | `OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES`   | Comma-separated list of additional `System.Diagnostics.ActivitySource` names to be added to the tracer at the startup. Use it to capture manually instrumented spans.                                                                                                                                                                                                                              |               |
 | `OTEL_DOTNET_AUTO_LEGACY_SOURCES`              | Comma-separated list of additional legacy source names to be added to the tracer at the startup. Use it to capture `System.Diagnostics.Activity` objects created without using the `System.Diagnostics.ActivitySource` API.                                                                                                                                                                        |               |
 | `OTEL_DOTNET_AUTO_FLUSH_ON_UNHANDLEDEXCEPTION` | Controls whether the telemetry data is flushed when an [AppDomain.UnhandledException](https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception) event is raised. Set to `true` when you suspect that you are experiencing a problem with missing telemetry data and also experiencing unhandled exceptions.                                                                 | `false`       |
diff --git a/src/OpenTelemetry.AutoInstrumentation.Loader/Startup.NetFramework.cs b/src/OpenTelemetry.AutoInstrumentation.Loader/Startup.NetFramework.cs
index b99bc3dc09..86974accb3 100644
--- a/src/OpenTelemetry.AutoInstrumentation.Loader/Startup.NetFramework.cs
+++ b/src/OpenTelemetry.AutoInstrumentation.Loader/Startup.NetFramework.cs
@@ -48,11 +48,20 @@ private static string ResolveManagedProfilerDirectory()
             return null;
         }
 
+        StartupLogger.Debug("Requester [{0}] requested [{1}]", args?.RequestingAssembly?.FullName ?? "<null>", args?.Name ?? "<null>");
         var path = Path.Combine(ManagedProfilerDirectory, $"{assemblyName}.dll");
         if (File.Exists(path))
         {
-            StartupLogger.Debug("Loading {0}", path);
-            return Assembly.LoadFrom(path);
+            try
+            {
+                var loadedAssembly = Assembly.LoadFrom(path);
+                StartupLogger.Debug("Assembly.LoadFrom(\"{0}\") succeeded={1}", path, loadedAssembly != null);
+                return loadedAssembly;
+            }
+            catch (Exception ex)
+            {
+                StartupLogger.Debug("Assembly.LoadFrom(\"{0}\") Exception: {1}", path, ex);
+            }
         }
 
         return null;
diff --git a/src/OpenTelemetry.AutoInstrumentation.Native/clr_helpers.h b/src/OpenTelemetry.AutoInstrumentation.Native/clr_helpers.h
index 50edd35716..74d4e17d8e 100644
--- a/src/OpenTelemetry.AutoInstrumentation.Native/clr_helpers.h
+++ b/src/OpenTelemetry.AutoInstrumentation.Native/clr_helpers.h
@@ -486,6 +486,52 @@ struct FunctionInfo
     }
 };
 
+struct AssemblyVersionRedirection
+{
+    // This struct is used to check and track version against ASSEMBLYMETADATA structs
+    // so it uses the same naming conventions, keeping fields with the same names in both
+    // structs.
+    USHORT      usMajorVersion;         // Major Version.
+    USHORT      usMinorVersion;         // Minor Version.
+    USHORT      usBuildNumber;          // Build Number.
+    USHORT      usRevisionNumber;       // Revision Number.
+
+    // Redirection related fields
+    ULONG       ulRedirectionCount;     // Tracks the number of times that the redirection was applied.
+
+    AssemblyVersionRedirection() :
+        usMajorVersion(0), usMinorVersion(0), usBuildNumber(0), usRevisionNumber(0), ulRedirectionCount(0)
+    {
+    }
+
+    AssemblyVersionRedirection(USHORT major, USHORT minor, USHORT build, USHORT revision) : ulRedirectionCount(0)
+    {
+        usMajorVersion = major;
+        usMinorVersion = minor;
+        usBuildNumber = build;
+        usRevisionNumber = revision;
+    }
+
+    int CompareToAssemblyVersion(const ASSEMBLYMETADATA& assembly)
+    {
+        return
+            usMajorVersion != assembly.usMajorVersion
+            ? (usMajorVersion > assembly.usMajorVersion ? 1 : -1) :
+            usMinorVersion != assembly.usMinorVersion
+            ? (usMinorVersion > assembly.usMinorVersion ? 1 : -1) :
+            usBuildNumber != assembly.usBuildNumber
+            ? (usBuildNumber > assembly.usBuildNumber ? 1 : -1) :
+            usRevisionNumber != assembly.usRevisionNumber
+            ? (usRevisionNumber > assembly.usRevisionNumber ? 1 : -1) :
+            0;
+    }
+
+    WSTRING VersionStr()
+    {
+        return trace::VersionStr(usMajorVersion, usMinorVersion, usBuildNumber, usRevisionNumber);
+    }
+};
+
 RuntimeInformation GetRuntimeInformation(ICorProfilerInfo7* info);
 
 AssemblyInfo GetAssemblyInfo(ICorProfilerInfo7* info, const AssemblyID& assembly_id);
diff --git a/src/OpenTelemetry.AutoInstrumentation.Native/cor_profiler.cpp b/src/OpenTelemetry.AutoInstrumentation.Native/cor_profiler.cpp
index 579ae95357..826d57c59b 100644
--- a/src/OpenTelemetry.AutoInstrumentation.Native/cor_profiler.cpp
+++ b/src/OpenTelemetry.AutoInstrumentation.Native/cor_profiler.cpp
@@ -27,6 +27,10 @@
 #include <mach-o/getsect.h>
 #endif
 
+#ifdef _WIN32
+#include "netfx_assembly_redirection.h"
+#endif
+
 namespace trace
 {
 
@@ -91,6 +95,13 @@ HRESULT STDMETHODCALLTYPE CorProfiler::Initialize(IUnknown* cor_profiler_info_un
         return E_FAIL;
     }
 
+#ifdef _WIN32
+    if (runtime_information_.is_desktop() && IsNetFxAssemblyRedirectionEnabled())
+    {
+        InitNetFxAssemblyRedirectsMap();
+    }
+#endif
+
     const auto process_name = GetCurrentProcessName();
     const auto exclude_process_names = GetEnvironmentValues(environment::exclude_process_names);
 
@@ -303,6 +314,140 @@ HRESULT STDMETHODCALLTYPE CorProfiler::AssemblyLoadFinished(AssemblyID assembly_
     return S_OK;
 }
 
+#ifdef _WIN32
+void CorProfiler::RedirectAssemblyReferences(
+    const ComPtr<IMetaDataAssemblyImport>& assembly_import,
+    const ComPtr<IMetaDataAssemblyEmit>& assembly_emit)
+{
+    HRESULT hr = S_FALSE;
+    HCORENUM core_enum_handle = NULL;
+    const ULONG assembly_refs_sz = 16;
+    mdAssemblyRef assembly_refs[assembly_refs_sz];
+    ULONG assembly_refs_count;
+
+    // Inspect all assembly references and make any necessary redirects.
+    while (true)
+    {
+        hr = assembly_import.Get()->EnumAssemblyRefs(&core_enum_handle, assembly_refs, assembly_refs_sz, &assembly_refs_count);
+        if (hr == S_FALSE)
+        {
+            // This is expected when the enumeration finished.
+            Logger::Debug("RedirectAssemblyReferences: EnumAssemblyRefs returned S_FALSE assembly_refs_count=", assembly_refs_count);
+            break;
+        }
+
+        // Loop and process each AssemblyRef
+        for (ULONG i = 0; i < assembly_refs_count; i++)
+        {
+            const void* public_key_or_token;
+            ULONG public_key_or_token_sz;
+            WCHAR name[kNameMaxSize];
+            ULONG name_len = 0;
+            ASSEMBLYMETADATA assembly_metadata{};
+            const void* hash_value;
+            ULONG hash_value_sz;
+            DWORD assembly_flags = 0;
+
+            hr = assembly_import->GetAssemblyRefProps(
+                assembly_refs[i],
+                &public_key_or_token,
+                &public_key_or_token_sz,
+                name,
+                kNameMaxSize,
+                &name_len,
+                &assembly_metadata,
+                &hash_value,
+                &hash_value_sz,
+                &assembly_flags);
+            if (FAILED(hr) || name_len == 0)
+            {
+                Logger::Warn("RedirectAssemblyReferences: GetAssemblyRefProps failed HRESULT=", HResultStr(hr));
+                continue;
+            }
+
+            const auto wsz_name = WSTRING(name);
+            if (Logger::IsDebugEnabled())
+            {
+                Logger::Debug("RedirectAssemblyReferences: AssemblyRef for [", wsz_name, "] version=", AssemblyVersionStr(assembly_metadata));
+            }
+
+            const auto found_redirect = assembly_version_redirect_map_.find(wsz_name);
+            if (found_redirect == assembly_version_redirect_map_.end())
+            {
+                // No redirection to be applied here.
+                continue;
+            }
+
+            AssemblyVersionRedirection& redirect = found_redirect->second;
+            auto version_comparison = redirect.CompareToAssemblyVersion(assembly_metadata);
+            if (version_comparison > 0)
+            {
+                // Redirection was a higher version, let's proceed with the redirection
+                Logger::Info("RedirectAssemblyReferences: redirecting [", wsz_name, "] from_version=", AssemblyVersionStr(assembly_metadata),
+                    " to_version=", redirect.VersionStr(),
+                    " previous_redirects=", redirect.ulRedirectionCount);
+                assembly_metadata.usMajorVersion = redirect.usMajorVersion;
+                assembly_metadata.usMinorVersion = redirect.usMinorVersion;
+                assembly_metadata.usBuildNumber = redirect.usBuildNumber;
+                assembly_metadata.usRevisionNumber = redirect.usRevisionNumber;
+                hr = assembly_emit.Get()->SetAssemblyRefProps(
+                    assembly_refs[i],
+                    public_key_or_token,
+                    public_key_or_token_sz,
+                    name,
+                    &assembly_metadata,
+                    hash_value,
+                    hash_value_sz,
+                    assembly_flags);
+                if (hr != S_OK)
+                {
+                    Logger::Warn("RedirectAssemblyReferences: redirection error: SetAssemblyRefProps HRESULT=", HResultStr(hr));
+                }
+                else
+                {
+                    redirect.ulRedirectionCount++;
+                }
+            }
+            else if (version_comparison == 0)
+            {
+                // No need to redirect since it is the same assembly version on the ref and on the map
+                if (Logger::IsDebugEnabled())
+                {
+                    Logger::Debug("RedirectAssemblyReferences: same version for [", wsz_name, "] version=", redirect.VersionStr(), " previous_redirects=", redirect.ulRedirectionCount);
+                }
+            }
+            else
+            {
+                // Redirection points to a lower version. If no redirection was done yet modify the map to
+                // point to the higher version. If redirection was already applied do not redirect and let
+                // the runtime handle it.
+                if (redirect.ulRedirectionCount == 0)
+                {
+                    // Redirection was not applied yet use the higher version. Also increment the redirection
+                    // count to indicate that this version was already used.
+                    Logger::Info("RedirectAssemblyReferences: redirection update for [", wsz_name, "] to_version=", AssemblyVersionStr(assembly_metadata),
+                        " previous_version_redirection=", redirect.VersionStr());
+                    redirect.usMajorVersion = assembly_metadata.usMajorVersion;
+                    redirect.usMinorVersion = assembly_metadata.usMinorVersion;
+                    redirect.usBuildNumber = assembly_metadata.usBuildNumber;
+                    redirect.usRevisionNumber = assembly_metadata.usRevisionNumber;
+                    redirect.ulRedirectionCount++;
+                }
+                else
+                {
+                    // This is risky: we aren't sure if the reference will be actually be used during the runtime.
+                    // So it is possible that nothing will happen but we can't be sure. Using higher versions on
+                    // the OpenTelemetry.AutoInstrumentation dependencies minimizes the chances of hitting this code
+                    // path.
+                    Logger::Error("RedirectAssemblyReferences: AssemblyRef [", wsz_name, "] version=", AssemblyVersionStr(assembly_metadata),
+                        " has a higher version than an earlier applied redirection to version=", redirect.VersionStr());
+                }
+            }
+        }
+    }
+}
+#endif
+
 void CorProfiler::RewritingPInvokeMaps(ComPtr<IUnknown> metadata_interfaces, ModuleMetadata* module_metadata, WSTRING nativemethods_type_name)
 {
     HRESULT hr;
@@ -500,34 +645,32 @@ HRESULT STDMETHODCALLTYPE CorProfiler::ModuleLoadFinished(ModuleID module_id, HR
         return S_OK;
     }
 
-    for (auto&& skip_assembly : skip_assemblies)
+    // It is not safe to skip assemblies if applying redirection on .NET Framework
+    if (!runtime_information_.is_desktop() || !IsNetFxAssemblyRedirectionEnabled())
     {
-        if (module_info.assembly.name == skip_assembly)
+        // Not .NET Framework or assembly redirection is disabled, check if the 
+        // assembly can be skipped.
+        for (auto&& skip_assembly : skip_assemblies)
         {
-            Logger::Debug("ModuleLoadFinished skipping known module: ", module_id, " ", module_info.assembly.name);
-            return S_OK;
+            if (module_info.assembly.name == skip_assembly)
+            {
+                Logger::Debug("ModuleLoadFinished skipping known module: ", module_id, " ", module_info.assembly.name);
+                return S_OK;
+            }
         }
-    }
 
-    for (auto&& skip_assembly_pattern : skip_assembly_prefixes)
-    {
-        if (module_info.assembly.name.rfind(skip_assembly_pattern, 0) == 0)
+        for (auto&& skip_assembly_pattern : skip_assembly_prefixes)
         {
-            Logger::Debug("ModuleLoadFinished skipping module by pattern: ", module_id, " ", module_info.assembly.name);
-            return S_OK;
+            if (module_info.assembly.name.rfind(skip_assembly_pattern, 0) == 0)
+            {
+                Logger::Debug("ModuleLoadFinished skipping module by pattern: ", module_id, " ", module_info.assembly.name);
+                return S_OK;
+            }
         }
     }
 
     ComPtr<IUnknown> metadata_interfaces;
     ModuleMetadata* module_metadata = nullptr;
-
-    if (module_info.IsDynamic())
-    {
-        // For CallTarget we don't need to load metadata on dynamic modules.
-        Logger::Debug("ModuleLoadFinished skipping Dynamic module: ", module_id, " ", module_info.assembly.name);
-        return S_OK;
-    }
-
     auto hr = this->info_->GetModuleMetaData(module_id, ofRead | ofWrite, IID_IMetaDataImport2, metadata_interfaces.GetAddressOf());
 
     if (FAILED(hr))
@@ -541,10 +684,25 @@ HRESULT STDMETHODCALLTYPE CorProfiler::ModuleLoadFinished(ModuleID module_id, HR
     const auto assembly_import = metadata_interfaces.As<IMetaDataAssemblyImport>(IID_IMetaDataAssemblyImport);
     const auto assembly_emit = metadata_interfaces.As<IMetaDataAssemblyEmit>(IID_IMetaDataAssemblyEmit);
 
-    module_metadata = new ModuleMetadata(metadata_import, metadata_emit, assembly_import, assembly_emit,
-                                            module_info.assembly.name, app_domain_id, &corAssemblyProperty);
+#ifdef _WIN32
+    if (runtime_information_.is_desktop() && IsNetFxAssemblyRedirectionEnabled())
+    {
+        // On the .NET Framework redirect any assembly reference to the versions required by
+        // OpenTelemetry.AutoInstrumentation assembly, the ones under netfx/ folder.
+        RedirectAssemblyReferences(assembly_import, assembly_emit);
+    }
+#endif
+
+    if (module_info.IsDynamic())
+    {
+        // For CallTarget we don't need to load metadata on dynamic modules.
+        Logger::Debug("ModuleLoadFinished skipping Dynamic module: ", module_id, " ", module_info.assembly.name);
+        return S_OK;
+    }
 
     // store module info for later lookup
+    module_metadata = new ModuleMetadata(metadata_import, metadata_emit, assembly_import, assembly_emit,
+                                            module_info.assembly.name, app_domain_id, &corAssemblyProperty);
     module_id_to_info_map_[module_id] = module_metadata;
 
     if (module_info.assembly.name == managed_profiler_name)
diff --git a/src/OpenTelemetry.AutoInstrumentation.Native/cor_profiler.h b/src/OpenTelemetry.AutoInstrumentation.Native/cor_profiler.h
index 6804233ab8..854c7e936c 100644
--- a/src/OpenTelemetry.AutoInstrumentation.Native/cor_profiler.h
+++ b/src/OpenTelemetry.AutoInstrumentation.Native/cor_profiler.h
@@ -58,6 +58,17 @@ class CorProfiler : public CorProfilerBase
     std::unordered_map<ModuleID, ModuleMetadata*> module_id_to_info_map_;
     ModuleID managed_profiler_module_id_ = 0;
 
+    //
+    // Assembly redirect private members
+    //
+#ifdef _WIN32
+    std::unordered_map<WSTRING, AssemblyVersionRedirection> assembly_version_redirect_map_;
+    void InitNetFxAssemblyRedirectsMap();
+    void RedirectAssemblyReferences(
+        const ComPtr<IMetaDataAssemblyImport>& assembly_import,
+        const ComPtr<IMetaDataAssemblyEmit>& assembly_emit);
+#endif
+
     //
     // Helper methods
     //
diff --git a/src/OpenTelemetry.AutoInstrumentation.Native/environment_variables.h b/src/OpenTelemetry.AutoInstrumentation.Native/environment_variables.h
index e925b2bb2b..8120fa141b 100644
--- a/src/OpenTelemetry.AutoInstrumentation.Native/environment_variables.h
+++ b/src/OpenTelemetry.AutoInstrumentation.Native/environment_variables.h
@@ -93,6 +93,9 @@ const WSTRING clr_enable_inlining = WStr("OTEL_DOTNET_AUTO_CLR_ENABLE_INLINING")
 // Sets whether to enable NGEN images.
 const WSTRING clr_enable_ngen = WStr("OTEL_DOTNET_AUTO_CLR_ENABLE_NGEN");
 
+// Enable the assembly version redirection when running on the .NET Framework.
+const WSTRING netfx_assembly_redirection_enabled = WStr("OTEL_DOTNET_AUTO_NETFX_REDIRECT_ENABLED");
+
 // Additional dependencies that are to be lighted up at runtime.
 // See https://github.com/dotnet/runtime/blob/main/docs/design/features/additional-deps.md
 const WSTRING dotnet_additional_deps = WStr("DOTNET_ADDITIONAL_DEPS");
diff --git a/src/OpenTelemetry.AutoInstrumentation.Native/environment_variables_util.h b/src/OpenTelemetry.AutoInstrumentation.Native/environment_variables_util.h
index d6fad279ac..552c7b0d83 100644
--- a/src/OpenTelemetry.AutoInstrumentation.Native/environment_variables_util.h
+++ b/src/OpenTelemetry.AutoInstrumentation.Native/environment_variables_util.h
@@ -70,6 +70,10 @@ bool AreLogsEnabled() {
   ToBooleanWithDefault(GetEnvironmentValue(environment::logs_enabled), true);
 }
 
+bool IsNetFxAssemblyRedirectionEnabled() {
+  ToBooleanWithDefault(GetEnvironmentValue(environment::netfx_assembly_redirection_enabled), true);
+}
+
 }  // namespace trace
 
 #endif  // OTEL_CLR_PROFILER_ENVIRONMENT_VARIABLES_UTIL_H_
\ No newline at end of file
diff --git a/src/OpenTelemetry.AutoInstrumentation.Native/netfx_assembly_redirection.h b/src/OpenTelemetry.AutoInstrumentation.Native/netfx_assembly_redirection.h
new file mode 100644
index 0000000000..1ff0e234e3
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation.Native/netfx_assembly_redirection.h
@@ -0,0 +1,153 @@
+// Auto-generated file, do not change it - generated by the AssemblyRedirectionSourceGenerator type
+
+#include "cor_profiler.h"
+
+#ifdef _WIN32
+namespace trace
+{
+void CorProfiler::InitNetFxAssemblyRedirectsMap()
+{
+    assembly_version_redirect_map_.insert({
+        { L"Google.Protobuf", {3, 19, 4, 0} },
+        { L"Grpc.Core", {2, 0, 0, 0} },
+        { L"Grpc.Core.Api", {2, 0, 0, 0} },
+        { L"Microsoft.Bcl.AsyncInterfaces", {1, 0, 0, 0} },
+        { L"Microsoft.Extensions.Configuration", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.Configuration.Abstractions", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.Configuration.Binder", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.Configuration.EnvironmentVariables", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.DependencyInjection", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.DependencyInjection.Abstractions", {5, 0, 0, 0} },
+        { L"Microsoft.Extensions.Logging", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.Logging.Abstractions", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.Logging.Configuration", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.Options", {5, 0, 0, 0} },
+        { L"Microsoft.Extensions.Options.ConfigurationExtensions", {3, 1, 0, 0} },
+        { L"Microsoft.Extensions.Primitives", {5, 0, 0, 0} },
+        { L"Microsoft.Win32.Primitives", {4, 0, 3, 0} },
+        { L"OpenTelemetry", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Api", {1, 0, 0, 0} },
+        { L"OpenTelemetry.AutoInstrumentation", {0, 5, 1, 0} },
+        { L"OpenTelemetry.Exporter.Console", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Exporter.Jaeger", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Exporter.OpenTelemetryProtocol", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Exporter.Prometheus.HttpListener", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Exporter.Zipkin", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Extensions.DependencyInjection", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Extensions.Propagators", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Instrumentation.AspNet", {1, 0, 0, 7} },
+        { L"OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule", {1, 0, 0, 7} },
+        { L"OpenTelemetry.Instrumentation.GrpcNetClient", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Instrumentation.Http", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Instrumentation.Process", {1, 0, 0, 3} },
+        { L"OpenTelemetry.Instrumentation.Runtime", {1, 1, 0, 2} },
+        { L"OpenTelemetry.Instrumentation.SqlClient", {1, 0, 0, 0} },
+        { L"OpenTelemetry.Instrumentation.Wcf", {1, 0, 0, 7} },
+        { L"OpenTelemetry.Shims.OpenTracing", {1, 0, 0, 0} },
+        { L"OpenTracing", {0, 12, 1, 0} },
+        { L"System.AppContext", {4, 1, 2, 0} },
+        { L"System.Buffers", {4, 0, 3, 0} },
+        { L"System.Collections", {4, 0, 11, 0} },
+        { L"System.Collections.Concurrent", {4, 0, 11, 0} },
+        { L"System.Collections.NonGeneric", {4, 0, 3, 0} },
+        { L"System.Collections.Specialized", {4, 0, 3, 0} },
+        { L"System.ComponentModel", {4, 0, 1, 0} },
+        { L"System.ComponentModel.EventBasedAsync", {4, 0, 11, 0} },
+        { L"System.ComponentModel.Primitives", {4, 1, 2, 0} },
+        { L"System.ComponentModel.TypeConverter", {4, 1, 2, 0} },
+        { L"System.Console", {4, 0, 2, 0} },
+        { L"System.Data.Common", {4, 2, 0, 0} },
+        { L"System.Diagnostics.Contracts", {4, 0, 1, 0} },
+        { L"System.Diagnostics.Debug", {4, 0, 11, 0} },
+        { L"System.Diagnostics.DiagnosticSource", {7, 0, 0, 0} },
+        { L"System.Diagnostics.FileVersionInfo", {4, 0, 2, 0} },
+        { L"System.Diagnostics.Process", {4, 1, 2, 0} },
+        { L"System.Diagnostics.StackTrace", {4, 1, 0, 0} },
+        { L"System.Diagnostics.TextWriterTraceListener", {4, 0, 2, 0} },
+        { L"System.Diagnostics.Tools", {4, 0, 1, 0} },
+        { L"System.Diagnostics.TraceSource", {4, 0, 2, 0} },
+        { L"System.Diagnostics.Tracing", {4, 2, 0, 0} },
+        { L"System.Drawing.Primitives", {4, 0, 2, 0} },
+        { L"System.Dynamic.Runtime", {4, 0, 11, 0} },
+        { L"System.Globalization", {4, 0, 11, 0} },
+        { L"System.Globalization.Calendars", {4, 0, 3, 0} },
+        { L"System.Globalization.Extensions", {4, 1, 0, 0} },
+        { L"System.IO", {4, 1, 2, 0} },
+        { L"System.IO.Compression", {4, 2, 0, 0} },
+        { L"System.IO.Compression.ZipFile", {4, 0, 3, 0} },
+        { L"System.IO.FileSystem", {4, 0, 3, 0} },
+        { L"System.IO.FileSystem.DriveInfo", {4, 0, 2, 0} },
+        { L"System.IO.FileSystem.Primitives", {4, 0, 3, 0} },
+        { L"System.IO.FileSystem.Watcher", {4, 0, 2, 0} },
+        { L"System.IO.IsolatedStorage", {4, 0, 2, 0} },
+        { L"System.IO.MemoryMappedFiles", {4, 0, 2, 0} },
+        { L"System.IO.Pipes", {4, 0, 2, 0} },
+        { L"System.IO.UnmanagedMemoryStream", {4, 0, 3, 0} },
+        { L"System.Linq", {4, 1, 2, 0} },
+        { L"System.Linq.Expressions", {4, 1, 2, 0} },
+        { L"System.Linq.Parallel", {4, 0, 1, 0} },
+        { L"System.Linq.Queryable", {4, 0, 1, 0} },
+        { L"System.Memory", {4, 0, 1, 2} },
+        { L"System.Net.Http", {4, 2, 0, 0} },
+        { L"System.Net.NameResolution", {4, 0, 2, 0} },
+        { L"System.Net.NetworkInformation", {4, 1, 2, 0} },
+        { L"System.Net.Ping", {4, 0, 2, 0} },
+        { L"System.Net.Primitives", {4, 0, 11, 0} },
+        { L"System.Net.Requests", {4, 0, 11, 0} },
+        { L"System.Net.Security", {4, 0, 2, 0} },
+        { L"System.Net.Sockets", {4, 2, 0, 0} },
+        { L"System.Net.WebHeaderCollection", {4, 0, 1, 0} },
+        { L"System.Net.WebSockets", {4, 0, 2, 0} },
+        { L"System.Net.WebSockets.Client", {4, 0, 2, 0} },
+        { L"System.Numerics.Vectors", {4, 1, 4, 0} },
+        { L"System.ObjectModel", {4, 0, 11, 0} },
+        { L"System.Reflection", {4, 1, 2, 0} },
+        { L"System.Reflection.Extensions", {4, 0, 1, 0} },
+        { L"System.Reflection.Primitives", {4, 0, 1, 0} },
+        { L"System.Resources.Reader", {4, 0, 2, 0} },
+        { L"System.Resources.ResourceManager", {4, 0, 1, 0} },
+        { L"System.Resources.Writer", {4, 0, 2, 0} },
+        { L"System.Runtime", {4, 1, 2, 0} },
+        { L"System.Runtime.CompilerServices.Unsafe", {6, 0, 0, 0} },
+        { L"System.Runtime.CompilerServices.VisualC", {4, 0, 2, 0} },
+        { L"System.Runtime.Extensions", {4, 1, 2, 0} },
+        { L"System.Runtime.Handles", {4, 0, 1, 0} },
+        { L"System.Runtime.InteropServices", {4, 1, 2, 0} },
+        { L"System.Runtime.InteropServices.RuntimeInformation", {4, 0, 2, 0} },
+        { L"System.Runtime.Numerics", {4, 0, 1, 0} },
+        { L"System.Runtime.Serialization.Formatters", {4, 0, 2, 0} },
+        { L"System.Runtime.Serialization.Json", {4, 0, 1, 0} },
+        { L"System.Runtime.Serialization.Primitives", {4, 2, 0, 0} },
+        { L"System.Runtime.Serialization.Xml", {4, 1, 3, 0} },
+        { L"System.Security.Claims", {4, 0, 3, 0} },
+        { L"System.Security.Cryptography.Algorithms", {4, 3, 0, 0} },
+        { L"System.Security.Cryptography.Csp", {4, 0, 2, 0} },
+        { L"System.Security.Cryptography.Encoding", {4, 0, 2, 0} },
+        { L"System.Security.Cryptography.Primitives", {4, 0, 2, 0} },
+        { L"System.Security.Cryptography.X509Certificates", {4, 1, 2, 0} },
+        { L"System.Security.Principal", {4, 0, 1, 0} },
+        { L"System.Security.SecureString", {4, 1, 0, 0} },
+        { L"System.Text.Encoding", {4, 0, 11, 0} },
+        { L"System.Text.Encoding.Extensions", {4, 0, 11, 0} },
+        { L"System.Text.Encodings.Web", {4, 0, 5, 0} },
+        { L"System.Text.Json", {4, 0, 1, 2} },
+        { L"System.Text.RegularExpressions", {4, 1, 1, 0} },
+        { L"System.Threading", {4, 0, 11, 0} },
+        { L"System.Threading.Overlapped", {4, 1, 0, 0} },
+        { L"System.Threading.Tasks", {4, 0, 11, 0} },
+        { L"System.Threading.Tasks.Extensions", {4, 2, 0, 1} },
+        { L"System.Threading.Tasks.Parallel", {4, 0, 1, 0} },
+        { L"System.Threading.Thread", {4, 0, 2, 0} },
+        { L"System.Threading.ThreadPool", {4, 0, 12, 0} },
+        { L"System.Threading.Timer", {4, 0, 1, 0} },
+        { L"System.ValueTuple", {4, 0, 3, 0} },
+        { L"System.Xml.ReaderWriter", {4, 1, 1, 0} },
+        { L"System.Xml.XDocument", {4, 0, 11, 0} },
+        { L"System.Xml.XmlDocument", {4, 0, 3, 0} },
+        { L"System.Xml.XmlSerializer", {4, 0, 11, 0} },
+        { L"System.Xml.XPath", {4, 0, 3, 0} },
+        { L"System.Xml.XPath.XDocument", {4, 1, 0, 0} },
+    });
+}
+}
+#endif
diff --git a/src/OpenTelemetry.AutoInstrumentation.Native/util.cpp b/src/OpenTelemetry.AutoInstrumentation.Native/util.cpp
index 194f4097b5..cde66bb293 100644
--- a/src/OpenTelemetry.AutoInstrumentation.Native/util.cpp
+++ b/src/OpenTelemetry.AutoInstrumentation.Native/util.cpp
@@ -189,4 +189,16 @@ WSTRING HResultStr(const HRESULT hr)
     return ToWSTRING(ss.str());
 }
 
+WSTRING VersionStr(const USHORT major, const USHORT minor, const USHORT build, const USHORT revision)
+{
+    std::stringstream ss;
+    ss << major << "." << minor << "." << build << "." << revision;
+    return ToWSTRING(ss.str());
+}
+
+WSTRING AssemblyVersionStr(const ASSEMBLYMETADATA& assembly_metadata)
+{
+    return VersionStr(assembly_metadata.usMajorVersion, assembly_metadata.usMinorVersion, assembly_metadata.usBuildNumber, assembly_metadata.usRevisionNumber);
+}
+
 } // namespace trace
diff --git a/src/OpenTelemetry.AutoInstrumentation.Native/util.h b/src/OpenTelemetry.AutoInstrumentation.Native/util.h
index 8735b31e2e..193702ac5e 100644
--- a/src/OpenTelemetry.AutoInstrumentation.Native/util.h
+++ b/src/OpenTelemetry.AutoInstrumentation.Native/util.h
@@ -44,6 +44,10 @@ WSTRING TokenStr(const mdToken* token);
 // Convert HRESULT to a friendly string, e.g.: "0x80000002"
 WSTRING HResultStr(const HRESULT hr);
 
+WSTRING VersionStr(const USHORT major, const USHORT minor, const USHORT build, const USHORT revision);
+
+WSTRING AssemblyVersionStr(const ASSEMBLYMETADATA& assembly_metadata);
+
 template <class Container>
 bool Contains(const Container& items, const typename Container::value_type& value)
 {
diff --git a/test/IntegrationTests/GraphQLTests.cs b/test/IntegrationTests/GraphQLTests.cs
index 7104b173cb..9269442cb9 100644
--- a/test/IntegrationTests/GraphQLTests.cs
+++ b/test/IntegrationTests/GraphQLTests.cs
@@ -68,6 +68,7 @@ public async Task SubmitsTraces(bool setDocument)
         SetEnvironmentVariable("OTEL_DOTNET_AUTO_GRAPHQL_SET_DOCUMENT", setDocument.ToString());
         SetEnvironmentVariable("OTEL_DOTNET_AUTO_TRACES_ENABLED_INSTRUMENTATIONS", "GraphQL");
         SetEnvironmentVariable("OTEL_TRACES_SAMPLER", "always_on");
+        SetEnvironmentVariable("OTEL_DOTNET_AUTO_NETFX_REDIRECT_ENABLED", "false");
 
         int aspNetCorePort = TcpPortProvider.GetOpenPort();
         SetEnvironmentVariable("ASPNETCORE_URLS", $"http://127.0.0.1:{aspNetCorePort}/");
diff --git a/test/IntegrationTests/HttpNetFrameworkTests.cs b/test/IntegrationTests/HttpNetFrameworkTests.cs
index 957c4b06f9..def3be48d9 100644
--- a/test/IntegrationTests/HttpNetFrameworkTests.cs
+++ b/test/IntegrationTests/HttpNetFrameworkTests.cs
@@ -36,7 +36,6 @@ public void SubmitTraces()
         SetExporter(collector);
 
         collector.Expect("OpenTelemetry.Instrumentation.Http.HttpWebRequest");
-        collector.Expect("TestApplication.Http.NetFramework");
 
         RunTestApplication();
 
diff --git a/test/OpenTelemetry.AutoInstrumentation.Loader.Tests/StartupTests.cs b/test/OpenTelemetry.AutoInstrumentation.Loader.Tests/StartupTests.cs
index 91fa41fabb..b621d9b7ac 100644
--- a/test/OpenTelemetry.AutoInstrumentation.Loader.Tests/StartupTests.cs
+++ b/test/OpenTelemetry.AutoInstrumentation.Loader.Tests/StartupTests.cs
@@ -18,21 +18,32 @@
 using System.IO;
 using System.Linq;
 using Xunit;
+using Xunit.Abstractions;
 
 namespace OpenTelemetry.AutoInstrumentation.Loader.Tests;
 
 public class StartupTests
 {
+    private ITestOutputHelper _testOutput;
+
+    public StartupTests(ITestOutputHelper testOutput)
+    {
+        _testOutput = testOutput;
+    }
+
     [Fact]
     public void Ctor_LoadsManagedAssembly()
     {
         var directory = Directory.GetCurrentDirectory();
         var profilerDirectory = Path.Combine(directory, "..", "Profiler");
+        _testOutput.WriteLine($"profilerDirectory={profilerDirectory}");
 
 #if NETFRAMEWORK
-        if (Directory.Exists(Path.Combine(profilerDirectory, "net462")))
+        var srcDir = Path.Combine(profilerDirectory, "net462");
+        var dstDir = Path.Combine(profilerDirectory, "netfx");
+        if (Directory.Exists(srcDir) && !Directory.Exists(dstDir))
         {
-            Directory.Move(Path.Combine(profilerDirectory, "net462"), Path.Combine(profilerDirectory, "netfx"));
+            Directory.Move(srcDir, dstDir);
         }
 #else
         if (Directory.Exists(Path.Combine(profilerDirectory, "net6.0")))
@@ -41,6 +52,7 @@ public void Ctor_LoadsManagedAssembly()
         }
 #endif
 
+        Environment.SetEnvironmentVariable("OTEL_DOTNET_AUTO_DEBUG", "1");
         Environment.SetEnvironmentVariable("OTEL_DOTNET_AUTO_HOME", profilerDirectory);
 
         var exception = Record.Exception(() => new AutoInstrumentation.Loader.Startup());
diff --git a/test/OpenTelemetry.AutoInstrumentation.Native.Tests/OpenTelemetry.AutoInstrumentation.Native.Tests.vcxproj b/test/OpenTelemetry.AutoInstrumentation.Native.Tests/OpenTelemetry.AutoInstrumentation.Native.Tests.vcxproj
index 289bef809d..4dde0a4712 100644
--- a/test/OpenTelemetry.AutoInstrumentation.Native.Tests/OpenTelemetry.AutoInstrumentation.Native.Tests.vcxproj
+++ b/test/OpenTelemetry.AutoInstrumentation.Native.Tests/OpenTelemetry.AutoInstrumentation.Native.Tests.vcxproj
@@ -70,6 +70,7 @@
     <ClInclude Include="test_helpers.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="assembly_version_redirection_test.cpp" />
     <ClCompile Include="integration_loader_test.cpp" />
     <ClCompile Include="integration_test.cpp" />
     <ClCompile Include="clr_helper_test.cpp" />
diff --git a/test/OpenTelemetry.AutoInstrumentation.Native.Tests/assembly_version_redirection_test.cpp b/test/OpenTelemetry.AutoInstrumentation.Native.Tests/assembly_version_redirection_test.cpp
new file mode 100644
index 0000000000..cc6e8ba857
--- /dev/null
+++ b/test/OpenTelemetry.AutoInstrumentation.Native.Tests/assembly_version_redirection_test.cpp
@@ -0,0 +1,25 @@
+#ifdef _WIN32
+#include "pch.h"
+
+#include "../../src/OpenTelemetry.AutoInstrumentation.Native/clr_helpers.h"
+
+using namespace trace;
+
+TEST(AssemblyVersionRedirectionTest, CompareToAssemblyVersion_Equal) {
+  ASSERT_TRUE(AssemblyVersionRedirection(1, 2, 3, 4).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) == 0);
+}
+
+TEST(AssemblyVersionRedirectionTest, CompareToAssemblyVersion_Lower) {
+  ASSERT_TRUE(AssemblyVersionRedirection(0, 2, 3, 4).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) < 0);
+  ASSERT_TRUE(AssemblyVersionRedirection(1, 1, 3, 4).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) < 0);
+  ASSERT_TRUE(AssemblyVersionRedirection(1, 2, 2, 4).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) < 0);
+  ASSERT_TRUE(AssemblyVersionRedirection(1, 2, 3, 3).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) < 0);
+}
+
+TEST(AssemblyVersionRedirectionTest, CompareToAssemblyVersion_Higher) {
+  ASSERT_TRUE(AssemblyVersionRedirection(2, 2, 3, 4).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) > 0);
+  ASSERT_TRUE(AssemblyVersionRedirection(1, 3, 3, 4).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) > 0);
+  ASSERT_TRUE(AssemblyVersionRedirection(1, 2, 4, 4).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) > 0);
+  ASSERT_TRUE(AssemblyVersionRedirection(1, 2, 3, 5).CompareToAssemblyVersion(ASSEMBLYMETADATA{1, 2, 3, 4}) > 0);
+}
+#endif
diff --git a/test/test-applications/integrations/Directory.Build.props b/test/test-applications/integrations/Directory.Build.props
index bbc68c41a9..7b4c218eed 100644
--- a/test/test-applications/integrations/Directory.Build.props
+++ b/test/test-applications/integrations/Directory.Build.props
@@ -8,8 +8,4 @@
     <Compile Include="$(MSBuildThisFileDirectory)GlobalSuppressions.cs" Link="GlobalSuppressions.integrations.cs" />
   </ItemGroup>
 
-  <!-- .NET Framework apps do not have shared store to bump these libraries -->
-  <ItemGroup Condition="$(TargetFramework.StartsWith('net4'))">
-    <PackageReference Include="System.Diagnostics.DiagnosticSource" Version="7.0.0" />
-  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/test/test-applications/integrations/TestApplication.DomainNeutral/App.config b/test/test-applications/integrations/TestApplication.DomainNeutral/App.config
deleted file mode 100644
index 63f272fd9a..0000000000
--- a/test/test-applications/integrations/TestApplication.DomainNeutral/App.config
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- To be removed when https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/1646 is fixed -->
-<configuration>
-  <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
-  </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/test/test-applications/integrations/TestApplication.GraphQL/TestApplication.GraphQL.csproj b/test/test-applications/integrations/TestApplication.GraphQL/TestApplication.GraphQL.csproj
index 427816d6af..89dd9d24ce 100644
--- a/test/test-applications/integrations/TestApplication.GraphQL/TestApplication.GraphQL.csproj
+++ b/test/test-applications/integrations/TestApplication.GraphQL/TestApplication.GraphQL.csproj
@@ -12,4 +12,10 @@
     <ProjectReference Include="..\dependency-libs\TestApplication.Shared\TestApplication.Shared.csproj" />
   </ItemGroup>
 
+  <!-- "Microsoft.AspNetCore" is incompatible with the .NET Fx automatic redirection.       -->
+  <!-- The element below injects the necesary dependencies during build time, for more info -->
+  <!-- https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/1727   -->
+  <ItemGroup Condition="$(TargetFramework.StartsWith('net4'))">
+    <PackageReference Include="System.Diagnostics.DiagnosticSource" Version="7.0.0" />
+  </ItemGroup>
 </Project>
diff --git a/test/test-applications/integrations/TestApplication.Http.NetFramework/App.config b/test/test-applications/integrations/TestApplication.Http.NetFramework/App.config
deleted file mode 100644
index 63f272fd9a..0000000000
--- a/test/test-applications/integrations/TestApplication.Http.NetFramework/App.config
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- To be removed when https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/1646 is fixed -->
-<configuration>
-  <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
-  </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/test/test-applications/integrations/TestApplication.Http.NetFramework/TestApplication.Http.NetFramework.csproj b/test/test-applications/integrations/TestApplication.Http.NetFramework/TestApplication.Http.NetFramework.csproj
index 3770780cba..c9f82c2bd5 100644
--- a/test/test-applications/integrations/TestApplication.Http.NetFramework/TestApplication.Http.NetFramework.csproj
+++ b/test/test-applications/integrations/TestApplication.Http.NetFramework/TestApplication.Http.NetFramework.csproj
@@ -2,12 +2,4 @@
   <PropertyGroup>
     <TargetFrameworks>net462</TargetFrameworks>
   </PropertyGroup>
-
-  <ItemGroup>
-    <Content Remove="App.config" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <None Include="App.config" />
-  </ItemGroup>  
 </Project>
diff --git a/test/test-applications/integrations/TestApplication.Http.NetFramework/TestServer.cs b/test/test-applications/integrations/TestApplication.Http.NetFramework/TestServer.cs
index 6b4d858e56..6afcc2f49b 100644
--- a/test/test-applications/integrations/TestApplication.Http.NetFramework/TestServer.cs
+++ b/test/test-applications/integrations/TestApplication.Http.NetFramework/TestServer.cs
@@ -15,7 +15,6 @@
 // </copyright>
 
 using System;
-using System.Diagnostics;
 using System.IO;
 using System.Net;
 using System.Text;
@@ -26,8 +25,6 @@ namespace TestApplication.Http.NetFramework;
 
 public class TestServer : IDisposable
 {
-    private static readonly ActivitySource MyActivitySource = new ActivitySource("TestApplication.Http.NetFramework", "1.0.0");
-
     private readonly HttpListener _listener;
     private readonly Thread _listenerThread;
 
@@ -70,11 +67,6 @@ private void HandleHttpRequests()
 
                 Console.WriteLine("[SERVER] Received: {0}", request);
 
-                using (var activity = MyActivitySource.StartActivity("manual span"))
-                {
-                    activity?.SetTag("test_tag", "test_value");
-                }
-
                 // NOTE: HttpStreamRequest doesn't support Transfer-Encoding: Chunked
                 // (Setting content-length avoids that)
                 ctx.Response.ContentType = "text/plain";
diff --git a/test/test-applications/integrations/TestApplication.MongoDB/Program.cs b/test/test-applications/integrations/TestApplication.MongoDB/Program.cs
index d9272af59e..aacc61715d 100644
--- a/test/test-applications/integrations/TestApplication.MongoDB/Program.cs
+++ b/test/test-applications/integrations/TestApplication.MongoDB/Program.cs
@@ -16,7 +16,6 @@
 
 using System;
 using System.Collections.Generic;
-using System.Diagnostics;
 using System.Linq;
 #if !MONGODB_2_15
 using System.Threading;
@@ -32,8 +31,6 @@ namespace TestApplication.MongoDB;
 
 public static class Program
 {
-    internal static readonly ActivitySource ActivitySource = new("TestApplication.MongoDB", "1.0.0");
-
     public static void Main(string[] args)
     {
         ConsoleHelper.WriteSplashScreen(args);
@@ -53,7 +50,6 @@ public static void Main(string[] args)
             }
         };
 
-        using var mainScope = ActivitySource.StartActivity("Main()");
         var connectionString = $"mongodb://{Host()}:{mongoPort}";
 
         var client = new MongoClient(connectionString);
@@ -72,7 +68,6 @@ public static void Run(IMongoCollection<BsonDocument> collection, BsonDocument n
     {
         var allFilter = new BsonDocument();
 
-        using var syncScope = ActivitySource.StartActivity("sync-calls");
         collection.DeleteMany(allFilter);
         collection.InsertOne(newDocument);
 
@@ -108,7 +103,6 @@ public static async Task RunAsync(IMongoCollection<BsonDocument> collection, Bso
     {
         var allFilter = new BsonDocument();
 
-        using var asyncScope = ActivitySource.StartActivity("async-calls");
         await collection.DeleteManyAsync(allFilter);
         await collection.InsertOneAsync(newDocument);
 
@@ -124,19 +118,13 @@ public static async Task RunAsync(IMongoCollection<BsonDocument> collection, Bso
 #if !MONGODB_2_15
     public static void WireProtocolExecuteIntegrationTest(MongoClient client)
     {
-        using (var syncScope = ActivitySource.StartActivity("sync-calls-execute"))
-        {
-            var server = client.Cluster.SelectServer(new ServerSelector(), CancellationToken.None);
-            var channel = server.GetChannel(CancellationToken.None);
-            channel.KillCursors(new long[] { 0, 1, 2 }, new global::MongoDB.Driver.Core.WireProtocol.Messages.Encoders.MessageEncoderSettings(), CancellationToken.None);
-        }
+        var server = client.Cluster.SelectServer(new ServerSelector(), CancellationToken.None);
+        var channel = server.GetChannel(CancellationToken.None);
+        channel.KillCursors(new long[] { 0, 1, 2 }, new global::MongoDB.Driver.Core.WireProtocol.Messages.Encoders.MessageEncoderSettings(), CancellationToken.None);
 
-        using (var asyncScope = ActivitySource.StartActivity("async-calls-execute"))
-        {
-            var server = client.Cluster.SelectServer(new ServerSelector(), CancellationToken.None);
-            var channel = server.GetChannel(CancellationToken.None);
-            channel.KillCursorsAsync(new long[] { 0, 1, 2 }, new global::MongoDB.Driver.Core.WireProtocol.Messages.Encoders.MessageEncoderSettings(), CancellationToken.None).Wait();
-        }
+        server = client.Cluster.SelectServer(new ServerSelector(), CancellationToken.None);
+        channel = server.GetChannel(CancellationToken.None);
+        channel.KillCursorsAsync(new long[] { 0, 1, 2 }, new global::MongoDB.Driver.Core.WireProtocol.Messages.Encoders.MessageEncoderSettings(), CancellationToken.None).Wait();
     }
 #endif
 
diff --git a/test/test-applications/integrations/TestApplication.Npgsql/App.config b/test/test-applications/integrations/TestApplication.Npgsql/App.config
deleted file mode 100644
index 63f272fd9a..0000000000
--- a/test/test-applications/integrations/TestApplication.Npgsql/App.config
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- To be removed when https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/1646 is fixed -->
-<configuration>
-  <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
-  </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/test/test-applications/integrations/TestApplication.Smoke/App.config b/test/test-applications/integrations/TestApplication.Smoke/App.config
deleted file mode 100644
index 63f272fd9a..0000000000
--- a/test/test-applications/integrations/TestApplication.Smoke/App.config
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- To be removed when https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/1646 is fixed -->
-<configuration>
-  <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
-  </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/test/test-applications/integrations/TestApplication.Smoke/TestApplication.Smoke.csproj b/test/test-applications/integrations/TestApplication.Smoke/TestApplication.Smoke.csproj
index c6f8b26e46..c56c5c6eae 100644
--- a/test/test-applications/integrations/TestApplication.Smoke/TestApplication.Smoke.csproj
+++ b/test/test-applications/integrations/TestApplication.Smoke/TestApplication.Smoke.csproj
@@ -4,10 +4,11 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
+    <ProjectReference Include="..\dependency-libs\TestApplication.Shared\TestApplication.Shared.csproj" />
   </ItemGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\dependency-libs\TestApplication.Shared\TestApplication.Shared.csproj" />
+    <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
   </ItemGroup>
+
 </Project>
diff --git a/test/test-applications/integrations/TestApplication.SqlClient.NetFramework/App.config b/test/test-applications/integrations/TestApplication.SqlClient.NetFramework/App.config
deleted file mode 100644
index 63f272fd9a..0000000000
--- a/test/test-applications/integrations/TestApplication.SqlClient.NetFramework/App.config
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- To be removed when https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/1646 is fixed -->
-<configuration>
-  <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
-  </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/test/test-applications/integrations/TestApplication.SqlClient/App.config b/test/test-applications/integrations/TestApplication.SqlClient/App.config
deleted file mode 100644
index 63f272fd9a..0000000000
--- a/test/test-applications/integrations/TestApplication.SqlClient/App.config
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- To be removed when https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/1646 is fixed -->
-<configuration>
-  <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
-  </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/test/test-applications/integrations/TestApplication.StrongNamed/App.config b/test/test-applications/integrations/TestApplication.StrongNamed/App.config
deleted file mode 100644
index 63f272fd9a..0000000000
--- a/test/test-applications/integrations/TestApplication.StrongNamed/App.config
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- To be removed when https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/1646 is fixed -->
-<configuration>
-  <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
-  </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/test/test-applications/integrations/TestApplication.Wcf.Client.NetFramework/App.config b/test/test-applications/integrations/TestApplication.Wcf.Client.NetFramework/App.config
index 8d69d4b4b9..79d935d360 100644
--- a/test/test-applications/integrations/TestApplication.Wcf.Client.NetFramework/App.config
+++ b/test/test-applications/integrations/TestApplication.Wcf.Client.NetFramework/App.config
@@ -30,16 +30,4 @@
       <endpoint address="net.tcp://127.0.0.1:9090/Telemetry" binding="netTcpBinding" bindingConfiguration="netTCPConfig" behaviorConfiguration="telemetry" contract="TestApplication.Wcf.Client.NetFramework.IStatusServiceContract" name="StatusService_Tcp" />
     </client>
   </system.serviceModel>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
 </configuration>
diff --git a/test/test-applications/integrations/TestApplication.Wcf.Server.NetFramework/App.config b/test/test-applications/integrations/TestApplication.Wcf.Server.NetFramework/App.config
index e0cf1a1a92..7b85082332 100644
--- a/test/test-applications/integrations/TestApplication.Wcf.Server.NetFramework/App.config
+++ b/test/test-applications/integrations/TestApplication.Wcf.Server.NetFramework/App.config
@@ -38,16 +38,4 @@
       </service>
     </services>
   </system.serviceModel>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
 </configuration>
\ No newline at end of file