Closed Ririshi closed 2 months ago
Maybe this is possible with https://github.com/0xced/Chisel and <ChiselPackage Include="Microsoft.Data.SqlClient.SNI.runtime" />
Thanks for the suggestion, that looks promising. It looks like Chisel doesn't (yet) work with class libraries, which means I'd have to set it up for all of my executable projects. I only mentioned a single project but in reality there are many projects that are all consuming the same EF Core project. I'm trying to set it up with a Directory.Build.props file now, will update here if it works out.
It appears I've found out how to do this. Adding the following block into my Directory.Build.props file defines Chisel as a dependency for all executable projects, omits the SNI dll from all of those projects while also enabling managed networking. Perhaps I can add another condition to only do this if the Microsoft.Data.SqlClient package is a (transient) dependency, but I don't know how to write a conditional basd on other dependencies yet.
An interesting point: apparently it is possible to set an AppContext switch by using RuntimeHostConfigurationOption
in MSBuild. I haven't seen it documented anywhere officially, so proceed at your own risk, but it seems to be working for us so far.
<ItemGroup Condition="'$(OutputType)'=='Exe'">
<PackageReference Include="Chisel" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<ChiselPackage Include="Microsoft.Data.SqlClient.SNI.runtime" />
<RuntimeHostConfigurationOption
Include="Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows" Value="true" />
</ItemGroup>
@Ririshi It looks like you've been able to find a solution, but I will bring this to the team to see if an alternative option is available.
Thank you, much appreciated.
While my suggested solution does work, it is a bit roundabout and feels hacky, because Chisel does not support dependency removal directly on class libraries. Enabling Chisel on all executable projects works, but some don't use my EF Core class library. This causes Chisel to generate build warnings saying that those projects do not have the SNI.runtime package in their dependency graph. I've disabled this warning (CHISEL002) for now using NoWarn.
As I said before, the best alternative in my opinion would be to have an MSBuild option that switches managed networking for the project in which it is set, as well as any projects referencing it. Ideally, it would work both for projects that directly reference M.D.SqlClient as well as projects that reference it as a transitive dependency, e.g. through EF Core.
The same could be said for Azure support, which is what Chisel was made for in the first place. That part might be irrelevant / off-topic though, since I also read something about creating separate packages to support on-prem and Azure separately.
the SNI .targets file have a variable as $(CopySNIFiles), can you try with your msbuild command and add
-p:CopySNIFiles=false
to see the outcome?
I have a framework-dependent single-file executable project that I would like to publish without having to bundle native libraries. I found the AppContext switch to use managed networking, which eliminates the need for the native SNI dll. However, when publishing my application, the SNI dll is always placed next to the executable, even though it is not actually used at runtime.
How can I best prevent the SNI dll from being published alongside the executable? I would be happy to hardcode a workaround into my csproj file, but I have not found a way yet to do this in a good way. The only workaround that I currently know of is to add a post-publish target that deletes the SNI dll, but that is not a very elegant solution.
On another note, it would be great if there was a compile-time configuration to switch between managed networking and native SNI. That way, the dependency on the native SNI dll would be entirely eliminated if managed networking is enabled.