1

I have a Base.dll that targets .NET standard 2.0

This Base.dll is referenced in 2 other projects : Framework.exe and Standard.exe

Framework.exe is a .NET framework 4.6.1 project

Standard.exe is a .NET Core 2.0 project.

My question is: How to write code in Base.dll that will only be executed if the Base.dll is loaded in Standard.exe and not if it is loaded in Framework.exe

This link gives details about conditional compilation based on target framework, but the target framework of Base.dll is always netstandard 2.0. I just want to determine at runtime what is the target framework of the hosting process.

Santhosh
  • 6,547
  • 15
  • 56
  • 63
  • Following will check the Framework of the dll executable : https://stackoverflow.com/questions/3460982/determine-net-framework-version-for-dll – jdweng Dec 10 '19 at 17:19
  • The link you have mentioned talks about compiler directive, those are responsible for code that will be compiled to dll based on directive mentioned. You can use it by assigning compiler directive during compilation . So simple solution would be if creating for .net framework or .net core specify such directive (e.g. foo , bar) – mbshambharkar Dec 10 '19 at 17:29
  • "but the target framework of Base.dll is always netstandard 2.0" - well, the simplest thing to do here would be to *change that* - multi-targeting is trivial in new-style csproj, and is intended for *exactly* this scenario - you then make `#if` (or conditional file include) tweaks depending on the target TFM, and the bait-and-switch loader ensures the correct stuff runs; is changing this an option? – Marc Gravell Dec 10 '19 at 17:34
  • @MarcGravell With the build infrastructure we have this is not a feasible option - as this would involve packaging related changes as well. I am looking at something that I can locally do in the code! – Santhosh Dec 10 '19 at 18:15
  • @Santhosh I'm kinda confused there, because this is literally a 2 line change to the csproj, that will work fine with `dotnet build`, `MSBuild`, etc... – Marc Gravell Dec 11 '19 at 08:03
  • Just don't rely on an oracle to tell you the truth, the code that uses your library can trivially tell you. – Hans Passant Dec 11 '19 at 11:12

1 Answers1

1

IMO the correct way to do this is at the csproj level via multi-targeting - <TargetFrameworks> etc, and either #if (in the C#) or conditional file includes (again in the csproj). Ultimately, what you're describing is exactly what multi-targeting is designed to do, and any solution other than "just use multi-targeting" is missing out on a huge feature explicitly aimed at solving these problems. The build mechanism has a "bait and switch" layer whose job it is to ask "what is the target framework of the host application? ok, I'll give them {this version} of the dependency" - which is why the job of transitive dependency resolution is deferred to the top-level application build, rather than library build (libraries don't reliably know the host TFM, for the reasons I'm about to get to).


However, putting that aside:

Your biggest problem here is going to be that: .NET Standard doesn't exist at runtime, only at compile-time; I mean multiple things by this, including the reality that .NET Framework can host .NET Standard, so when you ask:

what is the target framework of the hosting process.

it will never be .NET Standard. If that is just a typo and you mean .NET Core, then you can probably be reasonably safe borrowing these 2 lines from PlatformDetection.cs:

using System.Runtime.InteropServices;
// ...
public static bool IsFullFramework => RuntimeInformation.FrameworkDescription.StartsWith(
    ".NET Framework", StringComparison.OrdinalIgnoreCase);
public static bool IsNetCore => RuntimeInformation.FrameworkDescription.StartsWith(
    ".NET Core", StringComparison.OrdinalIgnoreCase);

is it clean? no. Will it work: yes.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Yes it is indeed a small change in the .csproj file. But there are several dlls build with target=netstandard2.0 in the code base. And even though changing only the relevant csproj files will work, I think to keep the generated dlls consistent across the code base, I might need to change all csproj files that currently target netstandard2.0 to additionally target net461 also. Not sure, but just saying. But I do agree that multi-targetting + conditional compilation using #IF directives is a cleaner approach than detecting the same from RuntimeInformation. – Santhosh Dec 11 '19 at 13:45