DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • ITBench, Part 1: Next-Gen Benchmarking for IT Automation Evaluation
  • How To Introduce a New API Quickly Using Quarkus and ChatGPT
  • Vision AI on Apple Silicon: A Practical Guide to MLX-VLM
  • Feature Flag Framework in Salesforce Using LaunchDarkly

Trending

  • How to Introduce a New API Quickly Using Micronaut
  • Introducing Graph Concepts in Java With Eclipse JNoSQL, Part 2: Understanding Neo4j
  • Monoliths, REST, and Spring Boot Sidecars: A Real Modernization Playbook
  • Securing the Future: Best Practices for Privacy and Data Governance in LLMOps
  1. DZone
  2. Coding
  3. Frameworks
  4. Converting a Big Project to .NET Standard Without a Big Bang

Converting a Big Project to .NET Standard Without a Big Bang

Avoid complications when converting .NET Full Framework to .NET Standard.

By 
Ricci Gian Maria user avatar
Ricci Gian Maria
·
Aug. 08, 19 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
11.3K Views

Join the DZone community and get the full member experience.

Join For Free

when you have a big project in .net full framework and you want to convert to .net standard/core, usually multitargeting can be a viable solution to avoid a big bang conversion. you start with the very first assembly in the chain of dependency, the one that does not depend on any other assembly in the project. then, you can check compatibility with .net standard for all referenced nuget packages. once the first project is done, you can proceed with the remaining steps in the process.

the very first step is converting all project files to new project format , leave all project to target full framework, then you can use a nice technique called multitargeting starting with the aforementioned first assembly of the chain.

to enable it, edit the project files, and change targetframework to targetframework s (mind the finals) and specify that you want that project compiled for full framework and .net standard. including .net standard in the list of target frameworks requires removal of all code that is dependent on the full framework, but this i s not always obtainable in a single big bang conversion, because the amount of code could be really high.

multi targeting in action

multitargeting in action


to ease the transition, i usually add some constants, so i’ll be able to use the #ifdef directive to isolate some piece of code only when the project is targeting full framework.

<propertygroup condition=" '$(targetframework)' == 'netstandard2.0'">
  <defineconstants>netcore;netstandard;netstandard2_0</defineconstants>
  </propertygroup>

<propertygroupcondition=" '$(targetframework)' == 'net461'">
    <defineconstants>net45;netfull</defineconstants></propertygroup>


after multitarget is enabled and netstandard is one of the targets, the project usually stops compiling because it usually contains some code that depends on the full framework. there are two distinct problems:

  1. you have  nuget packages that do not support netstandard.

  2. there are references to full framework assembly.

to solve the problem, you must use conditional referencing, setting the references only for a specific framework version.

conditional reference in action

conditional reference in action


as you can see in the figure above, i can reference different nuget packages or assemblies depending on the version of the framework used. the nice part is being able to reference different versions of a library (e.g. system.buffers) for full framework or .net standard framework.

at this point, the project usually stops compiling because the code references classes that are not available in .net standard. for example, you can verify that the .net standard misses references like system.runtime.caching and system.runtime.remoting. for all the code that uses references not available for .net standard projects, just use a #ifdef netfull to compile those classes only with the full framework. this is not a complete solution, but, in the end, you will have your project that is still fully functional with the .net full framework and a nice list of #ifdef netfull that identifies the only parts that are not available in .net standard. now, you can continue working as usual, while slowly removing and upgrading all the code to .net standard.

now, repeat the process for every project in the solution. usually, there are two scenarios:

  1. the vast majority of the code is full functional with .net standard, and there are very few points in the code where you use #ifdef netfull.

  2. some of the classes/functionality only available in the full framework are extensively used in all of your code; the amount of code with #ifdef netfull is becoming too big.

the first point is good. you can continue working with the full framework. then, convert the remaining code at your pace. if you find yourself in the second scenario — as an example, if some code uses msmq —you should isolate the full-framework-dependent code in a single class. then, use inversion of control to inject the concrete class. as an example, instead of having multiple points in the code that use msmq, simply abstract all the code in an iqueue interface and create an msmqqueue class, and you have a single point of code that is not available for .net standard. you can then write code that uses rabbit mq, and the problem is gone with a simple class rewrite.

let's do an example: i have an inmemorycachehelper to abstract the usage of memorycache. since memorycache class from system.runtime.caching is not available in .net standard, i simply protect the class with #if netfull conditional compiling.

conditional compilation, this is version of the class for net full.

conditional compilation with .net full


looking in the documentation, there is a nuget package called microsoft.extensions.caching.memory meant to be a replacement for the memorycache standard full framework class. i can use these nuget packages to create an implementation of inmemorycachehelper compatible with .net standard.

remember that you need to reference the full framework version (1) for net461 compilation, but reference nuget package for the .net standard version. this can be done manually editing references in csproj file in the following figure:

reference the correct assembly or nuget package based on framework version.

referencing the correct assembly or nuget package


now, you can come back to the inmemorycachehelper class, add an #else branch to the #ifdef netfull directive, and start writing a version of the class that uses microsoft.extensions.caching.memory. you will have all of your code that is able to target both .net full and .net core. you can rewrite the entire class, or you can use the same class and use #if netfull inside each method. i prefer the first approach, but this is what happens when i edit the .net standard version of the class.

no highlight and no intellisense because we are in a conditional compilation branch that evaluates to false.

no highting or intellisense


because we are in a branch of conditional compilation that evaluates to false, vs does not offer highlighting or intellisense. at this point, you should be aware that when you use multitargeting, the order of the frameworks in the project file matters. the first framework in <targetframeworks> node is the one that vs would use to evaluate conditional compilation. this means that when you are working with code that should target both the full framework and .net standard, you need to change the order to fit your needs.

in this example, i needed to change <targetframeworks>net461;netstandard2.0;</targetframeworks> to <targetframeworks>netstandard2.0;net461</targetframeworks> to save the project file and unload and reload the project (sometimes you need to force a project reload) and visual studio will consider .net standard2.0 during code editing.

reversing the order of the frameworks, will enable intellisense for netstandard branch of the conditional compilation directive.

reversing the order of frameworks


now, you can edit the .net standard version of your class and convert one by one all parts of the code that does not natively run on netstandard.

happy coding.

Framework

Published at DZone with permission of Ricci Gian Maria, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • ITBench, Part 1: Next-Gen Benchmarking for IT Automation Evaluation
  • How To Introduce a New API Quickly Using Quarkus and ChatGPT
  • Vision AI on Apple Silicon: A Practical Guide to MLX-VLM
  • Feature Flag Framework in Salesforce Using LaunchDarkly

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!