Copy local on implicit references?


(JohnMoshakis) #1

Hi,

I created a .net standard class library and a .net console app. I then added dapper and System.Data.SqlClient nugets to the library and added a reference to the library to the console app.

I did a build and attempted to run the console app. I see these errors in the console

~> Process NetConsoleApplication started
~> Ignored exception of type System.IO.FileNotFoundException on thread 0001 ()
~> Message:
~> Ignored exception of type System.IO.FileNotFoundException on thread 0001 ()
~> Message:
~> Ignored exception of type System.PlatformNotSupportedException on thread 0001 ()
~> Message: System.Data.SqlClient is not supported on this platform.

I also noticed that it hasn’t copied the implicit .net standard library reference to the bin of the console.

Should I be allowed to do copy local on the implicit reference or should that be automatic ?

I repeated the same in visual studio for mac and the only thing I needed to do was add a dapper reference to the console app. Im then able to run the console.

I can see that it appears to have copied all the references.

Cheers,
John


(marc hoffman) #2

John,

I don’t believe that one should be copied, as that would, essentially, deploy. a million System.* dlls with your app that are, well, part of the system?

Well, since they are implicit, you cant set any flags on em (where would those go?). If you want to control behavior of a reference, it has to be an explicit reference.

Hmm, so VSCode copies all the system refs alongside your exe? But regardless, that seems to not be the cause of your error message (if the system references were missing, you’d be in dapper trouble than “System.Data.SqlClient is not supported on this platform.”, surely?

Can I see a concrete project / test case for this?


(JohnMoshakis) #3

Just to be clear Im using visual studio for mac. Ive attached the screenshot and the projects.


TestConsoleApp.zip (43.6 KB)
CSharpStandardDataAccess.zip (1.1 MB)

If Im planning to deploy a regular .net framework app which references a .net standard library would I not need to deploy all the .net standard libs to my bin as well ?


(marc hoffman) #4

No. and thats precisely the point. these are all system dlls, they should not be deployed with your app. The point of .NET Standard is that its a set of established APIs (not concrete .dlls) supported by all .NET implementations. E.g. .NET Standard “Version X” APIs are supported by .NET Core “Version Y” and by full .NET Framework “Version Z”. But they still use the system dlls of the framework version in question.

So when your .NET Standard library runs on the full framework and it uses, say, String, it uses the String class from mscorlib.dll. When the same .NET Standard library runs on .NET Core, it uses the one from whatever .dll Microsoft hides it in for that runtime, and so on.

.NET Standard is an api specification/promise only, it’s not an actual implementation.


(marc hoffman) #5

I meant the Elements projects that fails with “System.Data.SqlClient is not supported on this platform.”.


(JohnMoshakis) #6

Ah ok.

This is the
DataAcessStandardClassLibrary.zip (51.5 KB)


(marc hoffman) #7

Thanx. I can repro the System.PlatformNotSupportedException: System.Data.SqlClient is not supported on this platform.. But are we sure thats in error? maybe that class really just is not supported own macOS? As far as I can tell, it builds fine, it copies/uses the SqlClient dll from the netstandard2.0 folder, which would be the right version to use in a core 2.x app…

That said, your main project is not a .NET Core app, it’s a standard .NET app (<TargetFramework>.NETFramework4.6</TargetFramework>), so it runs as Mono, not on .NET Core.

The loaded dlls are

#> (edb) image list
~> [0] Dapper, Version=1.50.5.0, Culture=neutral, PublicKeyToken=null: /Users/mh/Downloads/DataAcessStandardClassLibrary/NetConsoleApplication/Bin/Debug/Dapper.dll [no symbols]
~> [1] DataAcessStandardClassLibrary, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null: /Users/mh/Downloads/DataAcessStandardClassLibrary/NetConsoleApplication/Bin/Debug/DataAcessStandardClassLibrary.dll [no symbols]
~> [2] NetConsoleApplication, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null: /Users/mh/Downloads/DataAcessStandardClassLibrary/NetConsoleApplication/Bin/Debug/NetConsoleApplication.exe [no symbols]
~> [3] System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089: /Library/Frameworks/Mono.framework/Versions/5.16.0/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll [no symbols]
~> [4] System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089: /Library/Frameworks/Mono.framework/Versions/5.16.0/lib/mono/gac/System.Core/4.0.0.0__b77a5c561934e089/System.Core.dll [no symbols]
~> [5] System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089: /Library/Frameworks/Mono.framework/Versions/5.16.0/lib/mono/gac/System.Data/4.0.0.0__b77a5c561934e089/System.Data.dll [no symbols]
~> [6] System.Data.SqlClient, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a: /Users/mh/Downloads/DataAcessStandardClassLibrary/NetConsoleApplication/Bin/Debug/System.Data.SqlClient.dll [no symbols]
~> [7] System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089: /Library/Frameworks/Mono.framework/Versions/5.16.0/lib/mono/gac/System.Transactions/4.0.0.0__b77a5c561934e089/System.Transactions.dll [no symbols]
~> [8] System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089: /Library/Frameworks/Mono.framework/Versions/5.16.0/lib/mono/gac/System.Xml/4.0.0.0__b77a5c561934e089/System.Xml.dll [no symbols]
~> [9] mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089: /Library/Frameworks/Mono.framework/Versions/5.16.0/lib/mono/4.5/mscorlib.dll [no symbols]
~> [10] netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51: /Library/Frameworks/Mono.framework/Versions/5.16.0/lib/mono/4.5/Facades/netstandard.dll [no symbols]

So it’s using the referenced SqlClient dll, from .NETStandard, on Mono (5.16 ion my case). tbh I’m not sure f that’s something that’s supposed to work. Chances are, the error is legit.


(JohnMoshakis) #8

I think its in error. Using mono was intentional, it should support .net standard shouldnt it ?

I thought if I change some of my assemblies to .net standard I can develop on fire and deploy them to a windows machine.


(marc hoffman) #9

Well, ting is I don’t see what Elements/EBuild could be doing wrong that would cause the SqlCient to emit that error. It seems much more likely that SqlClient just isn’t implemented for macOS? It might depend on native drivers that are only available on Windows?

Yes. But that doesnt mean that Microsoft (or anyone) can’t put platform-specific code into a .NET Standard Assembly, and have it fail on different platforms.

Mono has its own implementation of System.Data.SqlClient (afaik?), and that will probably work, but I’d be the opposite of shocked if Microsoft’s SQL Server client implementation is Windows-specific…

One day to find out would be to look at System.Data.SqlClient.SqlConnection..ctor in ILSpy and see what it does. I can do that later when I’m near my Windows PC. My money is on it having a hard platform check and throwing that exception on non-Windows.


(marc hoffman) #10

Sure. the app will probably run fine on Windows, as is.


(JohnMoshakis) #11

The .net core one should be fine, Im not expecting the one that comes with the regular framework to work.


(marc hoffman) #12

Well, not sure what to tell ya, Burt the .dll has

/ System.Data.SqlClient.SqlConnection
public SqlConnection()
{
    throw new PlatformNotSupportedException(System.SR.PlatformNotSupported_DataSqlClient);
}

that’s from

.../EBuild/Packages/NuGet/System.Data.SqlClient-4.5.1/lib/netstandard2.0/System.Data.SqlClient.dll

That entire .dll is built to be able to link against it, but not to use it. Every single method on SqlConnection looks like this.


(marc hoffman) #13

(as an aside, if you make the SqlClient reference not Copy Local, the app works, as at runtime it then uses the Mono version of the dll provided by the system. Maybe that’s the intended use scenario for this?


(JohnMoshakis) #14

Yeah interesting. If I remove the System.Data.SqlClient assembly from the .net standard library the mono app using it throws a platformnotsupported exception.

If I create another mono console app which the same data access code inside it works fine.


(JohnMoshakis) #15

A core console app using my standard library fails to load.

Even with your new build Im unable to build a core console app with dapper and system.data.sqlclient.


(marc hoffman) #16

Can you send me a test case for that one, and I’ll try here, later. Also, let me know what your core runtime version setting is, as that might affect things. Mine is 2.1.2 I believe (can’t check right now as I’m out for some Christmas Eve beaching :beach_umbrella: for a few hours :wink:


(JohnMoshakis) #17

I’ll fiddle around for a bit and then I’ll create a test case.

Have a great time on the beach.


(marc hoffman) #18

thanx! back now.


(JohnMoshakis) #19

So I have the following

  1. core using system.data.sqlclient nuget fails to run with PlatformNotSupported exception
  2. core using my standard library fails because it cant load the standard library I created
  3. Mono using framework can query the database
  4. Mono using my standard library fails to run with PlatformNotSupported exception

I’ll try the same for visual studio for mac


(JohnMoshakis) #20

So far the Mono console and Core console can both connect to the database.

I upgraded visual studio for mac and seem to be having a problem creating my standard library.

At the moment I think EBuild is using the wrong assembly ?