Compiling .NET project with different references and frameworks - c#

I am building an SDK dll that needs to support multiple .NET frameworks with different references.
For example, one SDK dll is for Azure Functions which is .Net 4.6.1 with Newtonsoft.Json reference 9.0.0.1 (which was hard coded into Azure Functions). The other is a .NET 4.5.1 framework with newtonsoft.json 10.0.3.
What is the best way to build 2 dll's from the same cs code files using one Visual Studio solution where frameworks and references are different?
thanks

You can use the new .Net Standard class libraries
https://learn.microsoft.com/en-us/dotnet/core/tutorials/library-with-visual-studio
With that you can target the minimum library in your case it will be 1.2
https://learn.microsoft.com/en-us/dotnet/standard/net-standard
Them you can reference this dll from both projects.
For the referenced assemblies you need NOT specify a specific version of your dependency. There is a detailed explanation on how to do that on this answer here.
How exactly does the "Specific Version" property of an assembly reference work in Visual Studio?

Using SharedProjects in visual studio 2015 or greater allows for the targeting of multiple frameworks and references.
http://www.c-sharpcorner.com/UploadFile/7ca517/shared-project-an-impressive-features-of-visual-studio-201/

Related

Where did all the assemblies go ? .NET 5.0 error CS1069

So my code which worked fine yesterday, screwed up when I added a .net 5.0 class library project to my solution.
Error CS1069 The type name 'Bitmap' could not be found in the namespace 'System.Drawing'. This type has been forwarded to assembly 'System.Drawing.Common, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' Consider adding a reference to that assembly.
There is just one problem, when i look at what replaced "References" it now says "Dependencies" and when I try to add a dependency, "Add reference" is gone and there are no more .net assemblies being shown except under COM projects and type libs and when I add system.drawing etc, the error still remains and the code remains unreadable.
There are multiple reasons for what you're experiencing, I'll try to explain with a variety of assorted (and unordered) bullet-points:
Why isn't System.Drawing in .NET Core?
".NET 5" is the next iteration of .NET Core 3.1, not the .NET Framework 4.8 (.NET 5 comes immediately after .NET Core 3.1, there was never was a ".NET Core 4" to avoid confusion with .NET Framework 4).
.NET Core (including .NET 5) is designed to be cross-platform (i.e. to support Windows, Linux, macOS) with a single runtime.
Whereas previously people had to target .NET Framework for Windows, and target Mono, Xamarin, Unity, UWP, Silverlight, etc - which made multi-platform development in C# a pain.
Note that while Windows, Linux, and macOS now all share the real McCoy .NET 5 (and Silverlight is dead), other platforms like Xamarin, Unity, Mono, and UWP still have their own separate implementations of .NET (CLR+BCL) hence the need for ".NET Standard". At least we don't need those weird "Shared Projects" and "Portable Framework" projects anymore, phew!
In the .NET Framework, the System.Drawing API is just a .NET wrapper over Win32's GDI/GDI+, which means it's not cross-platform.
While System.Drawing seems like a platform-independent API, if you look closely at public types and methods like Graphics, Brush, Bitmap, Image and so on you'll see that they're all just thin wrappers and leaky-abstractions over GDI+. Mono does have System.Drawing reimplemented for Linux, however they did it by reimplementing GDIPLUS.dll which is about as horrible as it sounds.
So because System.Drawing is not cross-platform it was removed from .NET Core's "in-box" API.
So now you're wondering how you can get System.Drawing in .NET Core...
How can I get System.Drawing in .NET Core?
Earlier questions asked on StackOverflow from when .NET Core was more anaemic (and not yet pitched as a replacement for .NET Framework 4) have suggested switching to completely different and incompatible (but cross-platform-by-design) library, such as ImageSharp or ImageProcessor, however a better solution for Windows-only applications exists: the official Microsoft Windows Compatibility Pack (note that the aforementioned blog article is from 2017; as of 2021 the Windows Compatibility Pack is pretty-much fully implemented now).
All you need to do is open the NuGet package manager built-in to Visual Studio and add Microsoft.Windows.Compatibility as a package-reference and magically System.Drawing will be available for use in your application. You can also access the NuGet package manager via the Dependencies context-menu in Solution Explorer.
If you're using the .NET CLI ("command-line interface", not the "common language infrastructure", hurrah for overloaded acronyms) then just run dotnet add package Microsoft.Windows.Compatibility.
But why can't I add assembly references in .NET Core like I used to in .NET Framework?
You can!. It's just that (as of April 2021, running Visual Studio 2019 16.9) the UI for adding an assembly reference is kinda horrible.
You can do it manually by editing your .csproj and adding a <Reference Include="pathToDll.dll" /> (in the same <ItemGroup> as the other references).
You can do it from within Visual Studio by ignoring the missing menu option and using the Add Project Reference dialog:
Follow these steps
Go Solution Explorer > Your Project > Dependencies > Add Project Reference.
In the popup dialog, choose the Browse tab:
Then click the Browse... button:
Then browse for your target assembly DLL:
Voila - the added assembly reference will appear under a new Assemblies node under Dependencies:
Do note that (generally speaking, there are exceptions) you can only reference assembly DLLs that target .NET Core or .NET Standard. Because most DLLs built for .NET Core and .NET Standard exist as NuGet packages anyway there isn't much need to add an assembly reference directly.
Microsoft seems to have migrated Add Reference to standard SDK assemblies to "Manage NuGet Packages".. a step I do not understand the point of since the correct assembly is mixed in with third party user contributed search results.
Simply click where references would have been and is now dependencies, and right-click and then click Manage Nuget Packages, do a search for the assembly and VERIFY that Microsoft published it and it meets the .net Core requirements.
Yeah they dropped the ball on this in my humble opinion. Took me a minute to figure out that standard assemblies do not appear to be installed on the system.
The package gets installed under your user account's home directory, not in a system-wide folder requiring elevated user permissions to access the dll, so if your account is bugged, you get to a nice infected copy of the assembly each and every time :)

Referencing .NET Standard csproj project from .NET Framework traditional project

I have a library written against .NET Standard 1.3 which should be compatible with the .NET Framework 4.6.1 runtime. The library uses the new csproj and works fine when referenced by .NET Core projects.
I also have a WPF project on a traditional csproj which should be able to use this library. In Visual Studio 2017 I managed to reference the .NET Standard library and it compiles without errors.
At runtime, it tries to load assemblies which are dependencies of the .NET Standard project and it fails with assembly not found exceptions. And I can see that my output folder doesn't have any of the dependencies indeed.
Is there a way to reference my library in such a way all the required dependencies are copied to the output folder (or an equivalent solution to make the WPF project run fine)?
Note: If I reference manually one by one all the missing dependencies and use runtime assembly version binding I can make it run, but I shouldn't really do this when referencing a project.
This is the full project page: https://github.com/UnoSD/PasswordManager
.NET Standard csproj
WPF package.config
WPF csproj
It currently is a Roslyn problem: GitHub issue
It is an active issue on Roslyn:
https://github.com/dotnet/roslyn/issues/17639
https://github.com/NuGet/Home/issues/4488
You have to specify compiler output for .NET 4.6.1
Put line like below into your csproj in your .NET Standard library project.
<TargetFrameworks>netstandard1.4;net461</TargetFrameworks>
(that should go instead <TargetFramework>netstandard1.4</TargetFramework>)
Build will produce binaries both for .NET 4.6.1 and .NET Core runtime compatible with NET Standard 1.4.

Class library references on Visual Studio 2015

I've added a new Class Library (Package) project to my solution. It's my first experience with a .NET Core (or whatever I'm using, still confused)
My class library contains two references: .NET Framework 4.5.1 and .NET Platform 5.4
I'm trying to import some code from a sample project that uses IPrincipal. For some reason it's saying that it doesn't exist on namespace "System.Security" altohugh I can get it trough intellisense.
What's wrong with my project settings?
The new feature of .NET Core and Class Library (Package) is that it targets multiple platform and will compile into multiple assemblies which get automatically packaged into a nuget package.
When your class library targets multiple targets, it will compile to all of them. So if a certain library is only available on full .NET framework but not on .NET Core or other target framework, then you may receive intellisense if your editor is set to .NET 4.5. More information can be found in my other recent answer.
You can switch back and forth with the pull down menu on top left of the coding window, show in the screenshot below.
If you do not want to target a certain framework, you have to remove it's moniker from the project.json file or use preprocessor directives to write platform specific code or libraries/replacements.
.NET Core is heavily modularized and most of only the core modules are referenced in the default project and if you need additional one you need to reference them within the dotnet5.x section.
Basically you have multiple places with "dependencies" in your project.json, a global one where you can add dependencies which are available on all targeted frameworks and one within each "frameworks" section for each of the targets only.
Though the other answer covers some basic concepts, it would require some attention on which classes are available and which are not.
Microsoft temporarily host a web site at http://packagesearch.azurewebsites.net to assist.
If you can find a suitable package for RC1 from there, then you can add it to your project.json file. If not, you will have to conditional compile it to a desktop profile or use other alternatives.

easiest way to convert .NET project from 4.5 to 4.0?

I have a .NET application that I built in 4.5, which has references to a bunch of libraries that were built in 4.5, which themselves have references to 4.5, etc. A user group that I'm trying to distribute the application to is having problems running the executable because they have 4.0 installed; in particular, they're getting a MissingMethodException:
Method not found: 'System.Type System.Runtime.InteropServices.Marshal.GetTypeFromCLSID(System.Guid)'.
Because we may have trouble getting each user upgraded to 4.5 (as none of them have admin permissions on their machines and this would require a separate upgrade request for each user), I'm looking at finding an easy way to rebuild the project as 4.0. This seems to require that I rebuild every library and its referenced libraries in 4.0; is there an easier way to do this than going through each library one by one and building a 4.0 version? I'm thinking maybe like a one-click option for "Rebuild all referenced libraries in target framework" or something like that.
If you have dependencies on .Net 4.5 DLLs then you will need to also get .Net 4.0 versions of those if you want to successfully downgrade your project. A .Net project can only reference .Net DLLs up to the same version of .Net as the referencing assembly.
The easiest way to do this is to use something like NuGet to manage your dependencies. Note that when you change the target framework version of your project in VS you will need to uninstall and re-install dependencies with NuGet as NuGet does not automatically do this for you when you change the target framework version.
Of course if all the dependencies are to your own code and you aren't publishing this through a dependency management system like NuGet you will need to downgrade all your other code to .Net 4.0 as well
When I use Visual Studio, I right click on the project, change the framework, fix the References and recompile. Usually straight forward.
Please, have a look at this MSDN page to correctly switch your project to a lower target framework without problems! It is a little bit outdated for what concerns versions, but the process is the same described!
This is based on my experience. I had an application initially created in .net framework 4.5 but I wanted to convert it in .net framework 4.0. I created new project initially created 4.0 and then I did copy and paste of all the forms and controls of my previous application and it works. Framework 4.5 is using Aero2 and 4.0 is Aero... Good Luck :)

Framework Upgrade to 3.5

I have a project which references another project's dll. They both were in .net framework 2.0.
So upgraded both to 3.5, but when I go to reference for second project(the one referencing the first project) it still says on properties runtime version 2.0, even though I deleted the reference and readded.
How would I determine if the referenced dll is the upgraded one, before deploying to server where it has version 2.0?
I don't want to delete all files in server and deploy, after upgrading do I need to check the config files are referencing same dlls and deploy published files or it needs replacing all together?
.Net 3.5 and .Net 2 both run on version 2 of the CLR, so the runtime version of the 'old' and 'upgraded' assemblies will not change.
As for finding out whether it is 'upgraded', I would recommend using ILDASM to see which version of mscorlib is referenced.
However, the answers to this SO question provide a few alternatives.
You can easily check which version the assembly is build against by opening it up in Reflector (or another decompiler).
The CLR for .NET 3.0 and .NET 3.5 is the same CLR from .NET 2.0.
Hence the best way to check, if your assemblies are upgraded or not, is to use Assembly version. Do maintain assembly version and build version in AssemblyInfo.cs while building the assembly.
Having a strong named assembly is the best way to check.

Categories