How to ignore NuGet NU1605? - c#

I have a huge solution with many projects and in-house NuGet packages that has a pervasive dependency on Unity 4.0.1. We are evaluating migrating this solution to Unity 5.11.1 to improve performance and solve random DI-related crashes stemming from code that the Unity project outright deleted on the 5.0.0 release.
In searching for a way to ease the migration from the outside-in two tools have been developed:
A Roslyn-based source code converter
A bridge that implements the Unity 5 interface but in reality maps calls transparently to a wrapped Unity 4 container interface
Both tools pass their unit tests just fine and the converter managed to convert one key "leaf" project, however, we've hit a roadblock when trying to reference migrated leaf project from one inner project: The infamous NU1605.
I absolutely can see how the NU106 error is warranted, as the inner project still references Unity 4.0.1 and the leaf project references Unity 5.11.1. however, this is one case of the tools getting in our way: I require both versions to "co-exist", as I am manually bridging their inconsistencies.
On paper, this should be plenty viable as the DLLs have different versions and even namespaces are different.
Is there any way to "force" nuget into accepting this weird setup?

You have two options to suppress that code. One is to use the <NoWarn>NU1605</NoWarn> msbuild property (must be defined inside a PropertyGroup). Visual Studio's project properties probably has a way to edit it in the UI.
The other option is to add the NoWarn="NU1605" metadata to your ProjectReference item:
<ProjectReference Include="package id" Version="1.2.3" NoWarn="NU1605" />
Finally, NuGet actually reports NU1605 as a warning, which you might notice if you read the docs page title carefully. The .NET Core SDK elevates it to a warning using the WarningsAsErrors property. So, if you're sufficiently proficient with MSBuild, you could either remove it after they add it, or check how to prevent it from being added to the list. My guess as to the motivation is because the BCL is being distributed as packages for .NET Core 1.x and 2.x (it won't for 3.x) and when there's a security update, you don't want NuGet's nearest-wins rule causing a package with a known vulnerability to be accidentally used.

Related

How to determine if Microsoft.VisualStudio.Web.CodeGeneration.Design is being used?

I have a reasonable (although imprecise) idea as to what source generators do, but I have several projects in a solution that reference Microsoft.VisualStudio.Web.CodeGeneration.Design and the projects don't (to the best of my knowledge) have any source generators.
Given that this is source generation, I might be mistaken about the usage or it could be used indirectly. How can I determine whether it is safe to remove the reference? There isn’t anything else in the CodeGeneration namespace in the solution.
That package is used to scaffold various aspects in web projects:
Scaffold Identity
Scaffold Controllers
Probably those projects have been created/updated with scaffolding, that is the reason of the reference to Microsoft.VisualStudio.Web.CodeGeneration.Design package
It seems that is needed only if developing via cli:
Microsoft.VisualStudio.Web.CodeGeneration.Design - Code Generation tool for ASP.NET Core. Contains the dotnet-aspnet-codegenerator command used for generating controllers and views.
dotnet-aspnet-codegenerator is only required to scaffold from the command line, it's not needed to use scaffolding with Visual Studio.
It's generally safe to remove a reference which doesn't prevent compilation when absent.
Microsoft.VisualStudio.Web.CodeGeneration.Design seems like a very weird thing to reference in a project - I believe it's used for generating the default code for views & controllers so I'm pretty sure it can be removed as long as it still compiles.

Unnecessary dlls are shipped in Blazor WebAssembly

I'm trying to use Blazor WebAssembly hosted by ASP.NET Core. After implementing a page, I saw in Chrome DevTools many of unnecessary dlls are transmitted to client.
There is an example of situation. Let's assume we have following structure of projects in the solution:
BlazorApp.Client (contains Blazor pages)
Reference to BlazorApp.Shared
BlazorApp.Server (contains ASP.NET core)
Reference to BlazorApp.Client
Reference to BlazorApp.Shared
BlazorApp.Shared (contains shared classes)
Reference to ClassLibrary
ClassLibrary (contains some more shared classes)
NuGet reference to AWSSDK.Core
MyEnum.cs (enum, which is used in Blazor page; not using AWS SDK)
So basically BlazorApp.Shared project has reference to some other project, which could have many nuget packages. Minimum code to reproduce the issue is available in repo https://github.com/GTmAster/blazor-treeshake
My assumption is Mono Linker does a tree shaking in Release build, so all unused code and libraries will be excluded from resulting web assembly.
But when I run my app, I see it loads AWSSDK.Core.dll from the server:
Code in BlazorApp.Client doesn't used it, as well as the code in BlazorApp.Server and in BlazorApp.Shared. It is only loaded, because it is referenced in ClassLibrary.
Am I getting the wrong idea about Mono Linker tree shaking?
Is the only way to exclude this dll from shipping is to move MyEnum to BlazorApp.Shared and break BlazorApp.Shared -> ClassLibrary reference?
I've been investigating this too. It seems that the Linker doesn't do what you expect it to.
https://github.com/dotnet/aspnetcore/issues/28546#issuecomment-742100867
By default Blazor (and all of .NET Core) does not trim application code, it only trims the framework. There are patterns of code that are problematic with trimming. The runtime libraries have been updated and tested to make sure they play well with trimming, arbitrary libraries or user code might not be.
Upon further digging, it seems like you'd need to use Trimming to get further reductions in size. But I found this article, which at the bottom states:
The following trimming approach is being taken for Blazor Apps in .NET 5:
Assemblies from the shared framework/runtimepack get member-level
trimming
Microsoft.Extensions.* assemblies get type-level trimming
from TrimMode=Link
Assemblies from Microsoft.AspNetCore.* are trimmed
via hand generated XML file
All other assemblies are not trimmed
All in all means that the Linker / Trimming isn't going to remove unused assemblies as that's not what it does. It essentially just trims stuff out of the Framework assemblies that it believes you do not need.
You are right, the mono linker is tree shaking.
The only relevant information I could find is here: https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-preview-2-release-now-available/
You may notice with this preview release that the download size of the app during development is now a bit larger, but build times are faster. This is because we no longer run the .NET IL linker during development to remove unused code. In previous Blazor previews we ran the linker on every build, which slowed down development.
So as it is stated:
Now we only run the linker for release builds, which are typically done as part of publishing the app.
Are you looking into release builds?
Try following the this advise if you want tree shaking in debug builds.
If you prefer to still run the .NET IL linker on each build during development, you can turn it on by adding <BlazorWebAssemblyEnableLinking>true</BlazorWebAssemblyEnableLinking> to your project file.

Locally developed nuget with dependent projects

Let's say I have project A and project B. Project A depends on project B. So A would normally have a direct reference to B's DLL.
Then I decided to publish B as a nuget package. Now, A has a reference to B via nuget instead of a local DLL.
The downside to this arrangement is that if I update B, I need to upload a new nuget and wait for it to be available in order to use it from A.
I see that I can point to a local nuget package when updating A's reference to B so that does help a bit. However, if I make a change to B, I do still have to go through the steps of generating a new package and updating A's reference to the package before A will see the change. With the pre-nuget arrangement, I simply built B and A would see the changes.
An alternative is to remove A's reference to B's nuget package and revert to pointing to the local DLL while doing local development. However, if A is published to github, then the reference has to be reverted to a nuget reference before pushing to github.
What's the best practice in a situation like this? Surely many folks are dealing with this sort of thing with github and nuget being widely used.
UPDATE
This topic came up for discussion on the C# subreddit and some interesting approaches were pointed out.
Azure devops - original comment - thanks to B0dona
What we do is use azure devops (
https://azure.microsoft.com/en-us/services/devops/ ) to build and push
our nuget packages to our own repository (nuget.org is slow)
automatically after a new commit has been pushed.
You set it up once, push project B drink some coffee and enjoy the joy
that is updating packages.
git submodules - original comment - thanks to alkrun
You mention GitHub so I'll propose something a bit different:
In my opinion, if work on project A is likely to cause changes in
project B, A referencing B as a git submodule is much easier than
dealing with nuget. Git Submodules aren't without their headaches, but
this is what they were designed for. Some of the benefits:
1) The biggest is that if you say "If I need to change B then I'll
just make the change and push to get a new package built then test it
out in A" it's not a very fluid model to work with and it's asking
developers to push untested code into B. Then that 1-3 minute turn
around for CI build/package turns into 3 x 1-3 minute turnarounds and
it just feels horrible when I've tried it in the past. It's a massive
productivity killer.
2) Any other options around changing csproj files, they can work, but
they're very error prone. Developers aren't always great about
reviewing all changes before they commit them, you're going to have
developers forgetting and checking in the change to a project
reference and it's going to cause build failures.
3) Using B as a submodule for A doesn't prevent you from having
automated builds on B that produce nuget packages, and maybe other
projects which are less likely to change B could/should refer to those
4) At some point in the development of A, if it matures and becomes
less likely to cause changes in B, then you can switch A->B to a nuget
package reference also
Another option, I remember reading an article years ago where someone
had created a tool that generated an msbuild xproj file that would
replace package references with project references. They had it set up
where the xproj file was on the .gitignore and if the file didn't
exist, the nuget package reference was used. In this way, a developer
would run a command to switch over to project references, make the
changes they need, commit them, push changes, then update the nuget
reference. This seemed fairly clean to me, but I can't find the
article and it was a bit more complicated than I'm making it sound.
So I'd still go with the git submodule route. There are some quirks
with git submodules but they have gotten a lot easier to deal with in
the last couple years and it feels like the quirks are easier to
explain than the other options. Having used this for a few projects
now, it's very intuitive. Understand what a Git Submodule in a
detached head state is and how to avoid it, make sure to use the -b
option when adding a submodule, and find a good tool that can
handle submodules well. For what it's worth, VS Code is the most
intuitive interface I've found for working with submodules. Open A in
VS Code then switch to the version control tab and you'll see A and
any submodules listed up top along with the branches they're tracking.
Commit changes to the submodule, then to the parent and you're good to
go.
The Node community demonstrates a more robust approach. The npm link command which is available out of the box (see also this blog post), creates symbolic link from distributed package directory to package source directory. In this way:
package consumers are transparently redirected to package source project
changes in package sources are automatically reflected on the consumer side
The npm link approach has also these advantages over reference switching:
no changes are made to consumer's source code -- which can accidentally be committed.
works cross-platform, doesn't need a specific IDE
can be scripted and shared with the team
This feature is obviously required in the NuGet community, but for some reason, NuGet still lacks it. There is a feature request https://github.com/NuGet/Home/issues/1821, which indicates they have no plans of adding it.
Meanwhile I created a tool, which works similarly to npm link for NuGet packages, you may want to give it a try: https://www.nuget.org/packages/NuLink
If you are using Visual Studio 2017, you can install NuGet Reference Switcher for Visual Studio 2017 extension. Here is a guide how to use it: https://github.com/RicoSuter/NuGetReferenceSwitcher/wiki/Guide

Is it possible to get SLAB working with Microsoft.Diagnostics.Tracing.EventSource?

The official release notes say:
Improved compatibility with the EventSource nuget package
SLAB's source must be updated and rebuilt to work with the EventSource nuget package (which supports channels, but does not
support sampling). The process is now fairly painless.
Added references to the EventSource nuget package to all projects
Changed System.Diagnostics.Tracing to Microsoft.Diagnostics.Tracing in all source files
Defined the EVENT_SOURCE_PACKAGE constant in the unit test project (to disable tests that cannot possibly work with the nuget version).
This is a bit cryptic. Something seems backwards because I can't see any references at all to Microsoft.Diagnostics.Tracing in the Nuget download.
Or are the sub-bullets things that you have to do to get it to build (so it should say, Add, Change, Define instead of Added, Changed, Defined)?
Hm, well those instructions (if they are instructions) are not sufficient:
There are three places where Microsoft.Diagnostics.Tracing is already referenced, so that gives duplicate warnings
There are multiple places where ambiguities appear between Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Etw.Configuration.EventSourceSettings (which is a class) and Microsoft.Diagnostics.Tracing.EventSourceSettings (which is an enum).
A bit of detective work and common sense:
The last release date of SLAB is 25 July 2014, there have been a whole load of versions of Microsoft.Diagnostics.Tracing.EventSource, including one which presumably innocently introduced EventSourceSettings.
If I install and reference version 1.0.26, the instructions work.
Now just have to find out what things from version 1.1.28 are missing, and whether I miss them.
So, I just made SLAB work with the NuGet EventSource packages by following the directions above with SLAB 1.1.28 and the latest NuGet EventSource from the Microsoft.Diagnostics.Tracing.EventSource namespace.
Essentially, you need to fix up the ambiguous references between Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Etw.Configuration.EventSourceSettings and Microsoft.Diagnostics.Tracing.EventSourceSettings, just as it says above.
You want the Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Etw.Configuration.EventSourceSettings reference.
It works, produces flat file logs and writes to the Event Viewer, and when used in conjunction with a controller like PerfView, produces ETL files for detailed analysis.
Next, I'll be testing the out-of-process case.
#Benjol's detective work is correct.
Many users wanted to be able to use EventSource channels (which is included in the EventSource NuGet package) with SLAB so compatibility was improved to make compiling against the EventSource package at the time of release quite painless.
However, SLAB has not been updated recently but the EventSource Package continues to add/modify features. Some of these could be breaking changes with the current SLAB implementation. Since compatibility with subsequent releases of EventSource might not have been tested (I'm not sure what the team has done on this) there could be potential issues.

Version number in filename

At work we have a tracing library that has to be referenced for all applications.
Recently following a major version change, the trace lib name changed as well
From
dotnet_tracing-w32r-1-2
To
dotnet_tracing-w32r-2-0
This broke several of our pre-packaged solutions (projects that have a main branch that get forked for customization to specific customers).
What I'm trying to figure out, is there any way to (auto-magically) reference one OR the other? Having the version in the filename is screwing everything up and I really dont want to maintain two separate branches of these projects.
To solve this problem, we used Conditional References
First I created 2 different build configurations - and based upon those build configurations, I used conditional references to reference the proper assembly. Finally we then use some post build scripting to generate our 2 different NuGet Packages and publish to our NuGet feed.

Categories