2

We are developing addons for an other application. The application was built with .Net 4.5 and also runs on .Net 4.5. Our code is called via reflection from this application.

Is it possible to build our assemblies with higher .Net version (e.g. 4.6.1 or 4.7) than the application was build? (assumed the higher .Net run time is installed on the machine)

This what I found on MSDN (https://learn.microsoft.com/de-de/dotnet/framework/migration-guide/version-compatibility)

An app can control the version of the .NET Framework on which it runs, but a component cannot. Components and class libraries are loaded in the context of a particular app, and therefore automatically run on the version of the .NET Framework that the app runs on.

That means for me: NO

On the other hand I found that article: Loading an assembly targeted for .NET 4.5 on a .NET 4.0 app domain If I interpret that article correctly (in context of .Net 4.0 and 4.5), the answer was there: Yes. It is no problem to load a .Net assembly with higher version (here 4.5) into an app build with and running on a lower .Net version (here 4.0)

McGuireV10
  • 9,572
  • 5
  • 48
  • 64
harsc
  • 21
  • 3
  • 3
    "An app can control the version of the .NET Framework on which it runs" - this is only partly true; some .NET versions are side-by-side, but most are "over the top", so; if the machine has .NET 4.7 on it, you're effectively going to be running .NET 4.7 *even if* your app targets 4.5 - at least, as I understand it. This is further complicated because there are some shims and compat layers that make it very murky! – Marc Gravell Mar 19 '18 at 10:04
  • The odds that a .NET app *actually* runs on 4.5 today are excessively small. Having to support machines whose owner intentionally disabled Windows Update is no joy and should always be avoided. If you *must* target a higher version to get your code to compile then the odds it works well on such a machine are low. There is no point in risking this, speak the truth and it will set you free to do more useful things. – Hans Passant Mar 19 '18 at 10:07
  • 1
    All .NET framework version of 4.x runs practically the same .NET CLR version. Difference between the versions is what is available in the framework API. So if your application exclusively uses something that is only available in .NET 4.7 on a .NET 4.5 installation. You will then get a FileNotFoundException when trying to load the assembly from the GAC. – Thomas K Mar 19 '18 at 11:09
  • 1
    @ThomasK or a `MissingMethodException` – Marc Gravell Mar 19 '18 at 12:17

1 Answers1

0

I have had the same problem and have found following solution that works for me to make use of an .NET 4.61 Assembly within an .NET 4.5 Application:

public void FunctionOfDotNet45Application()
{ 
  // Load .net4.61 Assembly in .net4.5 Application
  AppDomainSetup domaininfo = new AppDomainSetup();
  domaininfo.ApplicationBase = System.Environment.CurrentDirectory;
  Evidence adevidence = AppDomain.CurrentDomain.Evidence;
  AppDomain domain = AppDomain.CreateDomain("MyDomain", adevidence, domaininfo);
  Proxy prxy = (Proxy)domain.CreateInstanceAndUnwrap(typeof(Proxy).Assembly.FullName, typeof(Proxy).FullName);
  string executionPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
  string net461AssemblyFilename = Path.Combine(executionPath, "DotNet461.dll");
  var net461Assembly = prxy.GetAssembly(net461AssemblyFilename);

  // Create and use object
  Type net461Type = net461Assembly.GetType("DotNet461DllNamespace.Net461Type");
  object net461Object = Activator.CreateInstance(net461Type, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
  net461Type.GetProperty("Property1").SetValue(net461Object, 1);
  net461Type.GetProperty("Property2").SetValue(net461Object, 2);
  byte[] retval = (byte[])net461Type.GetMethod("Function1", new Type[] { typeof(int) }).Invoke(net461Object, new object[] { 7 });
}

public class Proxy : MarshalByRefObject
{
  public Assembly GetAssembly(string assemblyPath)
  {
    return Assembly.LoadFile(assemblyPath);
  }
}

Sources:

(1) https://jonathancrozier.com/blog/how-to-dynamically-load-different-versions-of-an-assembly-in-the-same-dot-net-application

(2) How to Load an Assembly to AppDomain with all references recursively?

user1027167
  • 4,320
  • 6
  • 33
  • 40