Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create library targeting .Net Framework 4.5 and .Net Standard

I have a .NET library (Products.SDK) which i need to make it compatible with both .NET Framework 4.5 and .NET Standard 1.4.

(later on i will also create a NuGet package out of this library)

My question is:

How do i write the code in this library? Considering that both frameworks are using different libraries / dependencies?

  1. Will i have two separate projects under the same solution?

    Products.SDK.sln

    • Products.SDK.NetFramework
    • Products.SDK.NetStandard
  2. Will i have only one project, and use #if preprocessor directives do define different classes inside the library?

    namespace Products.SDK
    {
        #if NETSTANDARD1_3
            public class ProductsApi
            {
                public string ApiUrl { get; set; }
            }
        #else
            public class ProductsApi
            {
                public string ApiUrl { get; set; }
            }
        #endif
    }
    

If option #1 is correct, how do i make sure that both projects gets compiled using the same Name / Namespace (Products.SDK)

I do think that option #2 is better, but i am not sure this is the correct way.

PS:

I specify the target frameworks in the .csproj file

  <PropertyGroup>
    <TargetFrameworks>netstandard1.4;net45</TargetFrameworks>
  </PropertyGroup>
like image 523
Catalin Avatar asked Jan 30 '23 18:01

Catalin


1 Answers

You use option two - but only use #if in places where you really need it. The example you gave had the same code in both branches.

My Noda Time project takes exactly this approach, and we've had very few problems due to that.

Where possible, make the public API of your code the same for both platforms, with only implementation details differing. In particular, if you do need to expose some parts of your API only on one platform, I'd hope that it would be only for net45. If you end up with something like this:

  • public class A - only on net45
  • public class B - only on netstandard
  • public class C - both

then you're going to end up with significant problems later on, if you have multiple other projects depending on this. Suppose project X targets netstandard1.4 and uses B, then project Y targets net45 and uses A - then an application Z running on .NET 4.7 and depending on both X and Y is going to have problems.

It's definitely worth trying to avoid conditional code altogether. In many cases you may find that while there's a slightly simpler piece of code that will work on just net45, there's still code that will work on both netstandard and net45. (Reflection springs to mind, where you'll want to use TypeInfo on netstandard, in places where you could just use Type in net45. You can use TypeInfo in both though.)

like image 147
Jon Skeet Avatar answered Feb 02 '23 09:02

Jon Skeet