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?
Will i have two separate projects under the same solution?
Products.SDK.sln
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>
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:
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.)
See more on this question at Stackoverflow