How should I upgrade an old C# project which uses code contracts? - c#

I am working on a large C# project which uses code contracts extensively and compiles against an older version of the .NET Framework (3.5). This project is a library, and I am also developing other applications which consume it as a dependency. I would like to use .NET Core 2.1 for these new projects. I believe my options are as follows:
Upgrade the library from .NET Framework 3.5 to .NET Framework 4.6.1+, which I believe will make it compatible with .NET Standard 2.0 and thus usable by a .NET Core 2.1 project.
Upgrade the library to build against .NET Standard 2.0 explicitly, using the new .NET Core toolchain.
I have the following questions:
It looks like code contracts are dead and unsupported in .NET core; this means I will be unable to run the code contract analyzer if I go with Option (2), correct?
If I go with Option (1), the analyzer can still run but I'll have to switch to Igor Beck's unofficial NuGet package per this answer to support .NET 4.6.1+, correct?
Ideally I'd like to keep the benefits of code contracts, although since they're unsupported I recognize this will continue to hold back the library version as time goes on.

Related

ISystemClock not available in netstandard2.0

I'm still getting to grips with .Net Standard vs .Net Core after many years of development ASP.NET Framework. I have set up a new Web Api "app" which targets netcoreapp3.1 framework along with a middle-tier/Business Logic ClassLib and Data Access ClassLib, both of which target .Net Standard for maximum future compatibility. However, I can't seem to use ISystemClock from the Microsoft.AspNetCore.Authentication namespace in the .Net Standard classlibs!
From reading this SO question, I believe this might be because netstandard2.0 might not implement Microsoft.AspNetCore.App framework. Is this correct?
If it doesn't, should I:
Provide my own IMySystemClock interface in my class libraries which
the "app" itself can implement a trivial concrete class for?; or
Change my class middle and data access tiers to netcoreapp3.1
framework (seems over kill and restrictive to do this)?
Something else? Maybe I am missing the point of .Net Standard`?
A service (like ISystemClock) to provide the current (real or mock) time seems quite a fundamental service so I'm unsure why it's not appearing in .net standard framework?
Thanks
BloodBaz
If you want to access that functionality from a library, change the target framework of your library to .NET Core 3.1. Libraries can be built in .NET Standard or .NET Core. You can't use .NET Core functionality within a .NET Standard library, but you can do the reverse. Use .NET Standard functionality within a .NET Core library.
Also as a side note, unless it's required for compatibility reasons, I recommend you switch to .NET Standard 2.1. Visual Studio defaults new projects to .NET Standard 2.0, but a ton of new functionality was added in .NET Standard 2.1.
I spent years in the .NET Framework, so I feel the confusion. It took me a while to get used to it. I have a huge project I recently migrated over from .NET Framework to .NET Standard / .NET Core. What I ended up doing was dividing my code up into three sections. A .NET Standard 2.1 library with all the non .NET Core specific common code, a .NET Core 3.1 library with all my .NET Core specific common code (which referenced my .NET Standard library), and my applications as .NET Core 3.1 projects (which referenced my .NET Core 3.1 library).
Make sure you take a read at the answer in this question as well: What is the difference between .NET Core and .NET Standard Class Library project types?

Why does a dotnet Core App with a reference to a classic .Net project works and compiles [duplicate]

I'd really like to start using .NET Core and slowly migrate applications and libraries to it. However, I can't realistically upgrade my entire code base to use .NET Core and then go through the process of testing and deploying a plethora of applications in production.
As an example, if I create a new .NET Core application and try to reference one of my .NET Framework projects I get the following:
The following projects are not supported as references: -
Foobar.NetFramework has target frameworks that are incompatible with
targets in current project Foobar.NetCore.
Foobar.NetCore: .NETCoreApp,Version=v1.0
Foobar.NetFramework: .NETFramework,Version=v4.5
Is it possible to create a new .NET Core application and reference my existing .NET Framework libraries? If so, what's the process for doing that? I've spent hours going through Microsoft's documentation and searching their issues on GitHub, but I can't find anything official on how to achieve this or what their long-term vision is for this process.
Old question, but with the release of .NetStandard 2.0 and .netcore 2.0 and vs2017.3, the game has changed.
You can use the Full .NET Framework (TFM) with .NetCore 2.0, but how?
In Visual Studio 2017.3, you can reference the Full .NET Framework (any version) directly from within a .NetCore2 project.
You can build the .NetStandard2 class library and reference your TFM. Then reference your .NetStandard2 library from your .NetCore2 project.
For example, referencing json.net net45 from .NetStandard2.
Browse to the folder and select version net45 (not netstandard1.3)
See the dependency in the image below, no yellow warning as you see.
Even if a Nuget library is not ready to be ported to .Netstandard 2, you can use any API in the library that is compliant to net461.
Quoting for the .NET Core 2/Standard 2.0 announcement with links:
.NET Core 2.0 is able to freely reference libraries that have been built for .NET Framework up to version 4.6.1
However, some libraries may fail at run time if they try to use API methods that aren't available on .NET Core
Reference: .NET Core App target .NET framework 4.5.2 on Linux
A need to use third-party .NET libraries or NuGet packages not available for .NET Core
So only in cases where the libraries or NuGet packages use technologies that aren't available in .NET Standard/.NET Core, you need to use the .NET Framework.
Reference: Choosing between .NET Core and .NET Framework for server apps
You can now reference .NET Framework libraries from .NET Standard libraries using Visual Studio 2017 15.3. This feature helps you migrate .NET Framework code to .NET Standard or .NET Core over time (start with binaries and then move to source). It is also useful in the case that the source code is no longer accessible or is lost for a .NET Framework library, enabling it to be still be used in new scenarios.
Reference: Announcing .NET Core 2.0
Yes, we are currently attempting the same thing. The trick is to make sure that you are supporting the same .NET frameworks. Inside your project.json file, make sure the framework matches the framework of the project you wish to include. For example:
"frameworks": {
"net46": { --This line here <<<<
"dependencies": {
"DomainModel": {
"target": "project"
},
"Models": {
"target": "project"
}
}
}
},
FYI: You might need to change the framework of your .NET Core or your older projects to achieve this. .NET Core can be changed just by editing the project.json file as seen above. You can so the same in .NET projects by right clicking the project and opening properties. Change the framework level there.
Once you have matched the two project frameworks then you should be able to include them. Good Luck!
We delayed migrations as long as could as it seemed daunting as first. But we got an insistent client who wanted to migrate ASAP.
So we migrated their Fintech Web App developed on .NET Framework 4.8 Web Forms to .NET 6 Razor Page. Our team scoured though hundreds of online resources & spoke to Microsoft Tech Support before we started the project. Hope the high-level walkthrough of our journey help you plan your migrations.
Our .NET Framework Website consisted of 1 .NET Web Forms project and 12 Class Libraries.
Here is how we did it.
Refactored the .NET Framework 4.8 Web Forms code
We ensured that the Web Forms code behind did not have a single line of service or business logic code. When we did find some business logic code in the web forms code behind, we refactored it, by moving it to the class libraries.
Created new .NET Standard projects
We created a new .Standard 2.0 Class library project for every .NET Framework 4.8 Class Library. If the original project was called "FintechProjectName.StockMarketClient", we named the .NET standard project "FintechProjectName.StockMarketClient.Standard".
Copied all files from .NET framework to .NET standard
We copied all the class files from .NET framework to .NET standard projects. We then removed all the .NET framework class libraries from the solution and added references to the new class libraries. All projects compiled on the 1st try itself and all our test cases too passed with minor changes.
Create new .NET 6 Web App Project
We created a new .NET 6 Web App Project. We had to entirely redo the front-end as there is no direct path for migrating Web Forms to Razor Pages. This was the only project which took us about 1 month to migrate.
Reference .NET standard class libraries in the new .NET 6 website
We copied all the .NET Standard libraries to this new solution containing the Razor Pages web site. Added the references and got it to work.
Move from .NET Standard to .NET 6 class libraries
Once the new website was up and running, with all test cases passed, we did the last step in the process which was the simplest. Created .NET 6 class library projects for each of the .NET standard libraries and named the projects appropriately. Copied all class files from .NET standard projects to their corresponding .NET 6 projects. Then we removed the .NET Standard libraries and added references to the new class libraries.
Overall project timelines were about a month and a half, most of it spend on Razor Pages implementation using the same html design.
Note:
If you are using any 3rd party library which does not have a .NET standard or .NET 5 version, then you are out of luck. You will need to find a replacement nuget package and recode your application to use this new library.
In my case with .net6 referencing framework 4.8 library ( both winforms), the trick seems to be to add the reference to the framework dll as a shared reference.

With the final release of netstandard 2.0 and netcore 2.0, why we care to build netstandard2 library while we can use the full framework 4.6.1

.Netstandard2 is released final with .Net Core 2.0 and vs2017.3 with nuget4.3 and API surface cover 32k (except 41 class) and full cover net461
Quoting from Announcing .NET Core 2.0
You can now reference .NET Framework libraries from .NET Standard libraries using Visual Studio 2017 15.3. This feature helps you migrate .NET Framework code to .NET Standard or .NET Core over time (start with binaries and then move to source). It is also useful in the case that the source code is no longer accessible or is lost for a .NET Framework library, enabling it to be still be used in new scenarios.
We expect that this feature will be used most commonly from .NET Standard libraries. It also works for .NET Core apps and libraries. They can depend on .NET Framework libraries, too.
The supported scenario is referencing a .NET Framework library that happens to only use types within the .NET Standard API set. Also, it is only supported for libraries that target .NET Framework 4.6.1 or earlier (even .NET Framework 1.0 is fine).
So, in .netcore2 environment we can continue build/use Full .Net Framework as we did many years without the need to switch to .netstandard2 libraries.
With multi target project ,(net64;netstandard2), we get .net standard 2.0 out of box free (zero time effort) with the same API coverage.
Can you share your experience regarding: Can we continue build Full Framework 4.6.1 class library and use it in .netcore2? what is the limitation?
When you build a .NET Framework library, you can only use 4.6.1 with .NET Standard. If you want to use a newer API that is in e.g. netstandard2.0 or .NET 4.7, you'd need to retarget your library to 4.7, which then cannot be used by netstandard2.0 / netcoreapp2.0 projects. Effectively, you are locked into .NET Framework version 4.6.1 and can (/should) never update it to a newer version. (Of course, there is a workaround involving disabling the implicit fallback definition and manually setting AssetTargetFallback in the consuming project, but it requires manually editing the .csproj file and instructing all package consumers to do so).
Furthermore, the compatibility layer does not protect against using APIs that are not implemented on netstandard so a consuming project may get exceptions about missing types, methods, assemblies etc. Only when you target .NET Standard, your library is guaranteed to work on .NET Standard conformant platforms.
A practical limitation currently is that referencing .NET Framework library projects(!) (not NuGet packages) from .NET Core is not possible / only works with specific setups and workarounds (you will get an incompatible target framework warning).

Can I use any old arbitrary WIndows library in a .net core web app?

I just can't understand why I can't use an old library in a .net Core app targeting Windows and the full .net framework (I don't care about multi-platform).
Just trying to understand the limits here. I don't want to hit a wall after investing too much into it.
Steps followed:
Create a new .Net core web Application
Added PetaPoco from NuGet (just an example)
Can't use the library
From a comment from you on a deleted answer to this question
It's not about this particular reference. I just want to understand why I can't use an arbitrary Windows DLL. (I don't care about multi-platform) – Eduardo Molteni
It appears you are not too concerned why this specific project is not working (the deleted answer you commented on covered that quite well and if it was not deleted I would have up-voted it) but why in general you can't use a .NET Framework DLL in a .NET Core project.
Here is a diagram showing the layout of the ".NET ecosystem"
Things built for .NET Framework can't use DLLs built specifically for .NET Core, and things built for .NET Core can't use DLLs built specifically for .NET Framework because they are two "siblings" in the hierarchy.
Both .NET Framework and .NET Core can use .NET Standard libraries in their projects because .NET Standard is the "parent" of both the framework and core. Many newer NuGet packages now release versions that target .NET Standard so the library can be used with both versions. See the below chart to see what version of the .NET Standard library is compatible with various platforms. netstandard libraries are forward compatible so something that is compatible with 1.5 (like .NET 4.6.2) is also compatible with versions 1.0-1.4

Are .NET Core projects referencing PCLs cross-platform?

I have a .NET Core (ASP.NET Core) project created using Visual Studio 2017 RC (MSBuild).
I also have an old F# project library (traditional .NET Framework Library) that compiles to a dll file. I want to use it in said ASP.NET Core project.
To do that, I added a project reference in the ASP.NET Core project, opened the namespace, and made a few function calls in my controllers; it works perfectly when running the ASP.NET Core server using ISS from VS.
My question is, will this arrangement work if I want to deploy to linux (Ubuntu)? Or does using external PCLs/dlls from .NET Core instantly make it windows-only?
Note that I didn't have to add .NET Framework as a target framework in my csproj (it's MSBuild Core), it just worked.
Since your F# project targets the .NET Framework it will not run cross platform. If you modify your F# project to target the .NET Standard library it will. Here is a video by Immo Landwerth explaining how the .NET Standard Library works.
You should be able to just to reference the .NET standard library and not have to change anything. However the current version, which is 1.6, is missing a lot of API's from .NET Framework. This is fixed in 2.0. Infact since your using .NET Core 1.1 I think you are already using 2.0, but I'm not certain. Here is another video by Immo explaining how it should work.
That being said, I'm not sure what the F# support is like with .NET Standard.

Categories