.NET Core project dependency "bleed" - c#

Reference encapsulation in .NET Core seems to have changed in a way which allows references in one project to "bleed" into another project.
In prior versions of .NET, assemblies referenced by project "X" were not exposed to other projects in the solution which referenced project "X".
So for example, if you had a Domain project which referenced Entity Framework, adding a reference to that Domain project to another project in your solution would not grant that other project access to any Entity Framework classes.
This was a good thing (at least in my opinion).
Was playing around with a .NET Core 2.1 app tonight, and created a domain project
which leveraged EF Core.
I then created a unit test project (in eager anticipation of leveraging the new EF Core InMemory provider), and referenced my domain project.
What completely caught me off guard was that the unit test project was able to access EF Core classes even though I did not bring the EF Core NuGet package into the unit test project; my only assumption is that it was able to access EF via my domain project, ie:
This seems highly undesirable; I don't care too much about reference bleeds in my unit tests, but I do care very much about this kind reference bleed when working with other projects in my solution (such as an ASP.NET Core Web project).
Is there a way to hide / shield these package references in my Domain project from other projects which reference it?

This is a curious thing and i have never noticed it before,
However take a look at this
Controlling dependency assets
PrivateAssets These assets will be consumed but won't flow to the
parent project
And the tag
compile Contents of the lib folder and controls whether your project
can compile against the assemblies within the folder
Right click Class library -> Dependencies -> Nuget -> Package, and set the PrivateAssets to the word compile... I was seemingly able to use (and yet hide the dependency) in a calling .Net Core project.
Disclaimer, i really only played with this setting out of curiosity, and not really sure if there are any side affects to doing this

Related

Is there a way to have multiple applications reference a global project that has other project references

After searching quite a bit, I seem to be unable to find an answer to my problem. Usually, I find that means it is a non existent or incorrect approach, but I think it worth it to have an answer floating around on the internet nonetheless.
Essentially, we have 4 applications referencing 5 different "source" projects. So the scenario is, when we add a 5th application (for example), we will need to create project references to the other 5 different projects, as the application requires their output.
Its not a difficult task because the amount of projects is small, but it got us thinking. What if you could create a single project, maybe called Libs or something, reference all 5 projects in that project, and then the applications must only reference Libs. The idea seems cool, but I don't know if it will work because when you create a project reference, it points to Libs single output libs.dll.
So to actually ask a question, is this possible, and if so, how can it be done? Currently, having Libs reference the other "source" projects, and then having the applications reference the Lib project does not work, as it says there are missing assemblies.
And just to go over how this was created. The 5 source projects reside in a couple different solutions, so the only tedious part of this approach is "add existing project" at the initial start of the application's solution.
The way we manage this kind of thing in my organisation is to make a NuGet package for each of these shared "source" projects (e.g. in our case we have an error logging library, an XML utils library, a bespoke HTTP client, and others). These are published to our private NuGet feed URL (hosted on Azure DevOps, but you can just use a standard Windows fileshare if necessary) for our developers to use in their applications.
This has some clear advantages over your approach:
1) Dependencies - this seems most relevant to your question. If the project you built the NuGet package from itself depends on any other NuGet packages (either publicly available ones, or others from our private feed) then when someone installs that package in their project it will automatically install all the other packages it depends on.
So in your case you could create a shell "libs" package which doesn't deliver any content itself, but has dependencies on all your other packages, causing them to be installed automatically. In our case we have several cases of dependency (e.g. a "base" error logging package which is relied on by error handling modules which are tailored to different app types, e.g. MVC, Web API, Windows Services), and it works very well.
2) Updates and maintenance. In your scenario if you make a breaking change to one of your "source" projects, then, because you have a direct project reference declared in Visual Studio, any project which references the source one will have to make related changes to cope with the updates to the source project, before you can re-compile it and do whatever feature changes you're trying to achieve. This could be a pain, and be an untimely problem, especially in the case of major updates. However if instead you install a NuGet package containing that functionality, the developer of the application can choose if and when to install an updated version of the package.
There are other minor benefits as well which I won't go into, but there are some very good reasons why almost all major programming languages now provide similar "package" and "feed" functionality as a way of managing dependency on external projects and libraries. Your approach is, I feel, outdated and naive, resulting in the issue you've described and the potential for other irritations as well.

Adding system references to .NET Core application

Okay, this is (or at least should be) a stupid question: How do I add a reference to a system assembly in .NET Core projects?
I have a .NET Core class library. If I right click on Dependencies, there is still a Add Reference... command, but it only allows me to add references to my other projects. There is now an SDK section, but right clicking there provides no option to add new references.
This was so straight forward before. I don't understand why this has changed or how I now add a reference to something like Microsoft.Win32.Registry. (My understanding is I need a NuGet package for this assembly, but my question still stands about adding system references.)
Even if your system contains this assembly it does not gurantee that other systems also contain it. .Net Core is about cross platform so I do not think there is this assembly in Linux system. So you should distribute not only your code but some of "system" dll as well. And it is easier to update only one nuget package for adding new functionality, bug-fixing, etc than update all framework.

Share code between multiple .NET Core projects

I would like to know how I can share c# source codes between two (or more) .NET Core projects (commandline projects!).
As far as I understand, I can not link to source files in different directories in xproj/project.json based projects. I noticed that it now seems to be recommended to create nuget packages for everything. But is it really necessary for me to setup a private repository and create a nuget package only to be able to share some common source units?
VS2015 contains a template for .NET Core library which may be suitable for building a shared lib. Is it possible to link this lib to a project without a nuget package?
.NET Core Library is an excellent solution for you.
Do it the same way as in standard C# solution - just create the project and reference this project or add a reference to DLL file.
You don't need to use a Nuget, for your own purpose. Nuget packages could be useful to distribute your dll outside.
Clarification:
I miss one point - I'm using VS2015, but I have included Class Library project in my solution, and I'm referencing by project, not by DLL file, and this works fine in ASP.Net Core.
I also have a different project, where referencing DLL file directly working fine, but this is the previous version of ASP.NET app (not Core) - seems NET Core doesn't support this way like as the previous version (yet?).
Sorry for confusing you, sometimes it's too many technologies ;)
So could you just include ClassLibrary project into solution with your project and refer it as a project?
I have achieved this by using source control to branch from my commonly used projects in each new solution, and again merging back to the master branch if I make any changes.
Alternatively, baring in mind that NuGet is only an archived collection of files, you could keep this NuGet package locally, or even create a Template for Visual Studio that has the common libraries by default.
There are a wide range of possibilities that are down to your preference, and current environment state (I.E: Able to setup Source Control, or a package repository).

.net core classlibrary calling .net framework class library

Could not find an answer to my doubts and hopefully somebody can clarify.
I Have created a dummy solution with
1 class library(.net framework)
1 .net core library
Tried to reference either way but I cant,they are not compatible,fine makes sense.
Now my question
I have a utility class library(.net framework)with extensions,helpers etc...
that is used by winforms-wpf-asp.net mvc 4,5 apps now with the event of .net core it looks to me that I cannot use this library anymore unless I port it to .net core,which then i cannot use with my other apps.
What is the correct approach?
Am i missing the obvious?
Sharing code between a normal .NET library and a Core project did not work for me via simply using a Shared project, because I could not reference it from the Core project.
However, with a little trick I could make it work.
Let me explain with this folder/file structure:
[ProjectName] // Root of Core project
project.json
[ProjectName].xproj
Shared // Root of Shared project
[ProjectName].Shared.projitems
[ProjectName].Shared.shproj
// -- Source files here --
Net // Root of .NET project
[ProjectName].csproj
Properties
AssemblyInfo.cs // For both Core and .NET project
// NO source files here
So, you will need 3 projects, of course: a Core project, a normal .NET project, and a Shared project.
The Shared project has all the source files.
The .NET project references the Shared project, so it also has those files.
The Core project sees all the files the Shared project has, so it also has the same files.
That's it. You now can have common source code files for the .NET and the Core project.
A few notes:
Do NOT ever put the .shroj and the .csproj into the same folder. For me, it totally turned off intellisense in VS (2015). This information costed a lot of pain for me...
You can use #if -s to fine tune the common code
You can also use NuGet 2 in the .NET project with the above folder structure.
Note, that if you'd put the (NuGet 2) packages.config into the same folder where the (NuGet 3) project.json is located, the latter would totally overwrite the earlier.
You could try to use a shared library project. It compiles against the platform of the referencing application/library, so to speak. That gives you the ability to create class libraries targeting different platforms without the need to duplicate any code, but it may require some #if...
https://blogs.msdn.microsoft.com/dotnet/2014/04/21/sharing-code-across-platforms/

C# dll not found at compile time

I'm writing an application in .Net 3.5.
I have 3 projects in the solution so far. When adding the references to the other projects from my main project, the intellisense manages to find the classes from the other project's dlls but at compile time it seems to be "loosing" the reference.
This might be because I initially created the project with target framework .Net 4.0. However since I needed to use the ASP.NET web services I had to downgrade to 3.5.
Any help will be greatly appreciated.
The referrenced projects must be Copy Local : True
Referrence -> Properites ->Copy Local : True
Batch clean all projects in your solution, make sure all the projects in your dependency graph target the .NET 3.5 framework. Check the reference's HintPath in your .csproj file (open with text editor) for references to external DLLs and make sure they're all <=3.5.
However since I needed to use the ASP.NET web services I had to downgrade to 3.5.
There are also several different web service projects in .NET 4. I don't quite understand this move.
You have project references, intellisense sees your referenced classes but when compiling, the compiler seems not to find the referenced assemblies.
I see two possible reasons for this behaviour:
Your main project references a lower version of the .NET framework than your library projects (this is the most likely cause).
Your library projects won't get built at all / or in the wrong order (check the settings in the configuration manager. Open it with a right click on your solution in the solition explorer).

Categories

Resources