Multitargeting .NET Standard 2.0 missing some framework libraries - msbuild

Had a working ASP.NET Core using a .NET Standard DLL I wrote. I'd like to use TransactionScope in my DLL now, but getting this issue:
.NET Standard and .NET Core 2.0 both recognize System.Transactions, but .NET Framework 4.6.1 is giving an error and won't compile with MSBuild. Visual Studio 2017 offers the following helpful information:
I cannot seem to find a way to force the project to recognize System.Transactions.dll from my system's Framework/Framework64 folders.
Yes, I can use dotnet build to compile the .NET Core version, but that's not what I want... I want to be able to compile for .NET 4.6.1, too.

You need to add a framework referenced conditioned on the target framework.
Add this to your csproj file:
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<Reference Include="System.Transactions" />
</ItemGroup>

Related

What determines the specific version of ASP.NET Core and the corresponding assembly versions that are used when running an ASP.NET Core app?

Assuming that you are using <Project Sdk="Microsoft.NET.Sdk">in your .csproj file, the documentation says that you should reference the ASP.NET Core framework through a shared framework reference like so:
<FrameworkReference Include="Microsoft.AspNetCore.App" />
The.csproj file will also contain a target framework reference. For example, netcoreapp3.1 is specified using the following target framework moniker:
<TargetFramework>netcoreapp3.1</TargetFramework>
What isn't clear to me is how the specific version of ASP.NET Core is selected. I understand that the .NET runtime version selection process is documented here but I don't understand how the ASP.NET Core web framework version is selected. For example, what if I wanted to experiment with different features between two versions of ASP.NET Core that targeted the same version of .NET Core or .NET? How would that be distinguished?
When you target netcoreapp3.1 and you have multiple 3.1.x installed (e.g., you have 3.1.15, 3.1.20 and 3.1.28 installed), the latest version 3.1.28 will be used. Currently no known way to tell the .csproj to pick up a specific version (correct me if any).
For your question
what if I wanted to experiment with different features between two
versions of ASP.NET Core that targeted the same version of .NET Core
or .NET?
the only way I can think of is that you need to have couple build boxes installed with different point releases so that you can try for example 3.1.20 and 3.1.28.

Visual Studio 15.3.1 can't find core DLLs after update

I'm getting the runtime error:
InvalidOperationException: Can not find assembly file mscorlib.dll at '...\bin\Debug\net462\refs,...\bin\Debug\net462\'
This had not been a problem until I updated to version 15.3.1 this morning, and installed the .Net Core 2.0 SDK.
The DLL's are present in my ~\.nuget\packages folder. I'd had the same issue with the "Microsoft.Csharp.dll" assembly until I copied and pasted it into the stated folder.
I tried specifying to use .Net Core 1.1.0 via a global.json file, but then I get the build error:
The version of Microsoft.NET.Sdk used by this project is insufficient to support references to libraries targeting .NET Standard 1.5 or higher. Please install version 2.0 or higher of the .NET Core SDK.
This error goes away if I clean the solution then restore Nuget packages via Command Line- not via the GUI. However it comes back if I change the version of a nuget package.
OK, this seem slightly different to my issue here: Visual Studio update 2017 15.3.1 forces ASP.NET Core SDK 2.0, which then doesn't find "reference assemblies"
If you install the SDK 2.0 from https://www.microsoft.com/net/download/core
You will then "probably" be able to build and run the project again but you'll be back to having the missing Microsoft.CSharp.dll / mscorelib.dll error.
If you then make sure the dependency is correct for the netstandard version:
<DependsOnNETStandard>netstandard1.5</DependsOnNETStandard>
See here: https://learn.microsoft.com/en-us/dotnet/standard/net-standard for the right version for you. My project is using core 1.1 targeting the full framework 4.6.1 and targeting netstandard1.6 has worked for me.
The final piece of the puzzel, was found on the GitHub issues here: https://github.com/dotnet/sdk/issues/1488
Add the following to your references in the .csproj file:
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.0.0" />
This will then build the project as a 1.1 project, but using the 2.0 SDK (which from what I can tell, it's supposed to do!). I can now run the project, update packages and generally got on with my work!

Distribute custom MS Build Task with .NET Standard and VS 2017 via Nuget

I have a .NET Standard library (1.4) VS 2017 project that contains custom MS Build task (MyTask) that need to be distributed via Nuget package (Let's say MyCustomTask.dll and it contains MyTask and Portable.targets that will be imported by target project)
This Nuget package with custom build task is then used by target .NET Standard (1.4) project cspro file to import the Portable.targets that invoke the Custom Build task.
However, at this point I keep on getting the build error
Could not load file or assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
I tried .NET Standard (1.4, 1.5 and 1.6) but same error.
The problem is that the consuming application, MSBuild.exe in this case, would need to include all the forwarding assemblies necessary to run netstandard tasks (e.g. depend on the NETStandard.Library).
The best solution in this case is multi-targeting the task library to a .net framework and a .net standard target framework:
<TargetFrameworks>netstandard1.6;net46</TargetFrameworks>
The idea is to have 2 dlls that will contain the task. In the project files contained in the NuGet package instead of using a dll path directly in <UsingTask>, the idea is to using a different dll file based on the $(MSBuildRuntimeType) property, which will be Core on the .NET Core version of MSBuild:
<PropertyGroup>
<_CustomTaskAssemblyTFM Condition="'$(MSBuildRuntimeType)' == 'Core'">netstandard1.6</_CustomTaskAssemblyTFM>
<_CustomTaskAssemblyTFM Condition="'$(MSBuildRuntimeType)' != 'Core'">net46</_CustomTaskAssemblyTFM>
<_CustomTaskAssembly>$(MSBuildThisFileDirectory)..\tools\$(_CustomTaskAssemblyTFM)\CustomTaskAssemblyName.dll</_CustomTaskAssembly>
</PropertyGroup>
<UsingTask TaskName="SomeCustomTask" AssemblyFile="$(_CustomTaskAssembly)" />
You can see examples of this in the asp.net core build tools and the .NET Core SDK.

DotNet Core add dependecy in VS 2017

I have 2 simple projects one is in DotNet Core(lets say CoreProject) and the other one is in .net 4.5.2 (let's say OldCode). I was able to reference the projects but when I call the OldCode from the CoreProject I encounter the following error:
System.IO.FileNotFoundException occurred
HResult=0x80070002
Message=Could not load file or assembly 'System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
The system cannot find the file specified.
I have tried to add System.Configuration to the project but I don't know exactly to which file I should add it. I do not have project.json. Only config files that I have are: launchSettings.json and appsettings.json. I add System.Configuration with nuGet because it's an older version.
Where I should put the reference so when I run the command dotnet restore to add the dependency to System.Configuration?
At the moment, the .NET family looks something like this:
(Image is from .NET Core, .NET Framework, Xamarin – The “WHAT and WHEN to use it”)
When you create a project targeting one of the frameworks at the top (e.g. .NET Core), you can't use that project against other frameworks (e.g. .NET Framework). System.Configuration is an asset that specifically targets .NET Framework, and it doesn't exist in .NET Core.
On the other hand, you can write code that is compatible with all the frameworks (within limits - see compatibility chart to see how the versions map) by targeting .NET Standard, if your dependencies in turn target .NET Standard. This doesn't apply to System.Configuration, because that's .NET Framework-specific and does not target .NET Standard.
As an alternative, you can use the .NET Core Configuration Model (which, despite the name I'm using, actually targets .NET Standard and thus can be used in any framework). Or else you can use my very own .NET Settings Framework which is an abstraction that works with both the mature System.Configurationmodel (.NET Framework only) and the .NET Core configuration model (.NET Standard).

Upgrading a .Net 2.0 project to .Net 4.0

I have a .Net 2.0 project that depends on many 3rd party .Net dlls (all of which obviously target .Net 2.0).
If I were to migrate my project to VS2010 and target the .Net 4.0 framework, will my app still build? Or will it complain about the .Net 2.0 dll references and I will have to find .Net 4.0 versions of these 3rd party dlls?
Yes it will work. Make sure that you have both the .NET 2 and 4 FW installed on the machines executing the application.
If you need to use older assemblies with 4.0 (Mixed-Mode) you may need to add the following to <yourappname>.config:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
I had to do this when I attempted to load some old 1.1 assemblies into my Ironpython program (.NET 4.0) and got the following error:
"Mixed mode assembly is built against version 'v1.1.4322' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information."
Adding those three lines to my ipyw.exe.config file let me run those assemblies in mixed mode.