How to enable forward compatibility in a reusable .NET library?

I am now creating a new small version of the project. This project is released on NuGet and is compatible with .NET 4.0 and higher. Some of the new features that I present require .NET 4.5 (users should be able to IReadOnlyCollection<T> and IReadOnlyList<T> , both of the interfaces that were introduced in .NET 4.5), but I need the project to be compatible with. NET 4.0, as not all developers can easily upgrade to the latest .NET platform.

So, Im problem is faced with how to solve this "direct compatibility" problem. There are two solutions that I thought of, but both of them are not very attractive, so hopefully someone can give me some ideas or recommendations here.

Here are two solutions I came up with:

Solution 1. Use the #if compiler #if and create a version of the DLL for the .NET platform and send these versions using the NuGet packages and upload them to the project site.

The disadvantage of this method is that when developers upgrade their Visual Studio project from .NET 4.0 to .NET 4.5, they do not automatically receive .NET 4.5 (with specific .NET 4.5 features). This violates the Least of Surprise Principle and leaves developers stunned at why the feature doesn't work when they try to use it a few months later.

Solution 2. Use one single DLL and type emot on the fly, which implement both new interfaces when they exist in the current application domain. This allows you to send a single DLL to the user and allows available functions when the developer switches the .NET framework versions to his project. This will make things "just work." This is the direction Im currently heading btw.

Since I need to return a type that should implement interfaces, the disadvantage is that this type must be created at runtime using Reflection.Emit, ModuleBuilder, TypeBuilder, etc. This is seriously nasty. But in addition, since this type must be created in a new (anonymous) assembly, I have to make some internal types public (the type that needs to be inherited, and the interface that needs to be implemented). If these internal types publicly pollute the project API and will not allow me to make changes to these types.

I think these are my options, but I could have missed something obvious. So my question is: am I missing an opportunity? Is there a way around workarounds for solution 1, or would it be better to go with a hardcore root from a runtime type?

+6
source share
2 answers

Have you thought about another custom assembly with missing elements in it? Then you check if the type / method exists (which will exist only in .net 4.5), and if that happens, you load the assembly.

That way, you can keep the same methods and classes and get rid of the pain in order to make all this crazy emission (not to mention the perfectional blow that you will take if you find so much).

+2
source

I have a project called Dynamitey that allows you to load a type at runtime and call it static methods and DLR constructors. Which would be much less messy than a lot of reflection or emitting api download code, which is not always available.

 dynamic bigIntType = new DynamicObjects.LateType("System.Numerics.BigInteger, System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); if (bigIntType.IsAvailable) { var one = bigIntType.@new (1); var two = bigIntType.@new (2); Assert.IsFalse(one.IsEven); Assert.AreEqual(true, two.IsEven); var tParsed = bigIntType.Parse("4"); Assert.AreEqual(true, tParsed.IsEven); } 

I also have a project called ImpromptuInterface that will produce proxy types for interfaces around objects that can be used for ducks (also uses DLR).

 var targetType =Type.GetType("System.Collections.Generic.IReadOnlyList`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); var list = new List<string>{"lala", "la","lala"}; object readonlyList; if(targetType != null){ readonlyList = Impromptu.DynamicActLike(list, targetType); } 
0
source

Source: https://habr.com/ru/post/950836/


All Articles