none
Can't have side-by-side 3.5 and 4.5 assemblies in the same application. RRS feed

  • Question

  • I'm not sure what I missed, but I did not succeed to use a Class Library targeting framework 3.5 (runtime  2.0) within a solution for which the entry project is targeting framework 4.5 (runtime 4.0).

    This should be a simple straight forward thing to do! The simple setup involves 2 projects: a class library and a startup project.

    Startup project:

    • Target framework is: 4.5
    • App.config XML's startup tag is <startup useLegacyV2RuntimeActivationPolicy="true">
    • References the class library described below

    Class library project:

    • Target framework is: 3.5 (all system libraries it references are on runtime 2.0)
    • For each reference system's library ,I set the "Sepcific Version" Attibute to "True" (because I do want the 2.0 system runtime to be picked up at runtime)

    When I launch the application (targeting 4.5), from the referenced library (targeting 3.5):

    • for Assembly.GetExecutingAssembly().ImageRuntimeVersion , I get "v2.0.50727" which is fine and expected.
    • BUT for typeof(Uri).AssemblyQualifiedName , I get "System.Uri, System, Version 4.0.0.0, Culture=neutral, PublicKeyToken=b77a5561934e089"

    Can someone tell me what I'm missing in order to have the .NET runtime 2.0 being used from my library?

    Here is simple code to experiment it.

    1) the Class Library "ClassLibrary_3_5" targeting .NET framework 3.5:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using System.Net;
    using System.Reflection;
    
    namespace ClassLibrary_3_5
    {
        public class MyLibraryClass
        {
            public MyLibraryClass () {}
    
            public void Test()
            {
                Console.WriteLine("Class Lib is targeting framework 3.5");
                Console.WriteLine("Class Lib - ImageRuntimeVersion: " + Assembly.GetExecutingAssembly().ImageRuntimeVersion);
                Console.WriteLine("Class Lib - framework runtime (class Uri): " + typeof(Uri).AssemblyQualifiedName);
    
                string url = "http://www.webserver.com/webpage/hello%2Etxt";
                Console.WriteLine();
                Console.WriteLine("Class Lib - when runtime 2.0 is used uri.OriginalString == uri.AbsoluteUri for the case below"); 
                Uri uri = new Uri(url);
                Console.WriteLine("Class Lib - uri.OriginalString: " + uri.OriginalString);
                Console.WriteLine("Class Lib - uri.AbsoluteUri:    "    + uri.AbsoluteUri);    
            }
            
        }
    }
    2) the Startup Project targeting .NET framework 4.5:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.Reflection;
    using ClassLibrary_3_5;
    
    namespace SideToSideTester
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Test Side-to-Side target frameworks:");
                Console.WriteLine();
                Console.WriteLine("Calling App is targeting framework 4.5");
                Console.WriteLine("Calling App - ImageRuntimeVersion: " + Assembly.GetExecutingAssembly().ImageRuntimeVersion);
                Console.WriteLine("Calling App - framework runtime (class Uri): " + typeof(Uri).AssemblyQualifiedName);
                Console.WriteLine();
    
                MyLibraryClass myLib = new MyLibraryClass();
                myLib.Test();
    
                Console.ReadLine();
            }
        }
    }

    3) the App.config file:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <startup useLegacyV2RuntimeActivationPolicy="true"> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
        </startup>
    </configuration>


    • Edited by Magda7 Tuesday, March 29, 2016 11:51 PM
    Tuesday, March 29, 2016 11:50 PM

Answers

  • Hi Magda7,

    Do I understand correctly?

    Almost agree with you. Here I also found a good explanation from Hans Passant

    The only wrinkle is the dependencies that your 3.5 assembly has on old framework assemblies.  It will for example ask for version 2.0.0.0 of mscorlib.dll.  The CLR automatically translates those requests and replaces them with version 4.0.0.0.  Which in general works just fine, the standard 4.0 framework assemblies are very compatible with the old versions.

    For more detailed information, please check thread Mixing .NET 3.5 with 4/4.5 assemblies in the same process

    >> then I need to split my solution in different executables; one over runtime 4.0 and another one over runtime 2.0.

    If you have a 3.5 assembly referenced from a 4.5 executable, both assemblies will run in the 4.5's CLR environment. It is over runtime4.0.

    Best regards,

    Kristin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Marked as answer by Magda7 Thursday, March 31, 2016 5:29 PM
    Thursday, March 31, 2016 7:49 AM

All replies

  • Hi Magda7,

    >>BUT for typeof(Uri).AssemblyQualifiedName , I get "System.Uri, System, Version 4.0.0.0, Culture=neutral, PublicKeyToken=b77a5561934e089"

    Can someone tell me what I'm missing in order to have the .NET runtime 2.0 being used from my library?

    Based on your scenario, you get the Version is 4.0.0.0, per my understanding, it is right. Though your ClassLibrary is 3.5.  Because Startup project target is 4.5 Framework version overwrites the low version.

    Here is a sample that target .Net 4.5

    using System;
    using System.Reflection;
    
    class MyAssemblyClass
    {
        public static void Main()
        {
            Type objType = typeof(System.Array);
    
            // Print the full assembly name.
            Console.WriteLine ("Full assembly name:\n   {0}.", 
                               objType.Assembly.FullName.ToString()); 
    
            // Print the qualified assembly name.
            Console.WriteLine ("Qualified assembly name:\n   {0}.", 
                               objType.AssemblyQualifiedName.ToString()); 
        }
    }
    // The example displays the following output if run under the .NET Framework 4.5:
    //    Full assembly name:
    //       mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
    //    Qualified assembly name:
    //       System.Array, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.

    For more information, please refer to the following link.

    https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

    >>Can't have side-by-side 3.5 and 4.5 assemblies in the same application.

    From your title, I would suggest you also target your Startup project to the same version(.Net 3.5). Because all the project should be match with the same version, then the result you'll get.

    Best regards,

    Kristin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.



    • Edited by Kristin Xie Wednesday, March 30, 2016 9:14 AM
    Wednesday, March 30, 2016 9:11 AM
  • Thanks Kristin,

    From your explanation I understand that:

    • The startup project's .NET runtime is used for referenced libraries. Which means: when the startup project targets framework 4.5 (therefore uses runtime 4.0), then all class libraries will use the same runtime 4.0 no matter that they are targetting 3.5.
    • The only way to have my libraries to run with 2.0 runtime is to make my startup project targetting 3.5 too.

    Do I understand correctly?

    Therefore if I need framework 4.5 (because TLS 1.2 is not supported in prior versions) AND I also need framework 3.5 because of a bug introduced in 4.5 explained here, then I need to split my solution in different executables; one over runtime 4.0 and another one over runtime 2.0.

    If that's is the case, it makes my project (already complex) very very convoluted....

    • Would it be different to have startup project in 3.5 and the class library in 4.5 ?
    • Do you know easier workarounds?
    • Do you have other hints?

    Thanks for you help

    Wednesday, March 30, 2016 5:20 PM
  • Hi Magda7,

    Do I understand correctly?

    Almost agree with you. Here I also found a good explanation from Hans Passant

    The only wrinkle is the dependencies that your 3.5 assembly has on old framework assemblies.  It will for example ask for version 2.0.0.0 of mscorlib.dll.  The CLR automatically translates those requests and replaces them with version 4.0.0.0.  Which in general works just fine, the standard 4.0 framework assemblies are very compatible with the old versions.

    For more detailed information, please check thread Mixing .NET 3.5 with 4/4.5 assemblies in the same process

    >> then I need to split my solution in different executables; one over runtime 4.0 and another one over runtime 2.0.

    If you have a 3.5 assembly referenced from a 4.5 executable, both assemblies will run in the 4.5's CLR environment. It is over runtime4.0.

    Best regards,

    Kristin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Marked as answer by Magda7 Thursday, March 31, 2016 5:29 PM
    Thursday, March 31, 2016 7:49 AM