I'm making a private nuget-package library with support for dependency injection. If the project using this nuget-package is running .net6 or later, I wish for it to be a .Net6.0 library and to use Microsoft dependency injection. Otherwise I wish for it to be a netstandard2.0 and to use StructureMap.
My .csproj file looks like this (cleaned up unnecessary lines):
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Update="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="StructureMap" Version="4.7.1" />
</ItemGroup>
</Project>
And my extension method to use either Microsoft.Extensions.DependencyInjection or StructureMap looks like this (also removed unnecessary lines here):
using System;
using CustomApiClient.ApiClient;
#if NET6_0_OR_GREATER
using Microsoft.Extensions.DependencyInjection;
#else
using StructureMap;
#endif
namespace CustomApiClient.Extensions
{
public static class DependencyInjectionExtensions
{
#if NET6_0_OR_GREATER
public static IServiceCollection RegisterApiClient(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
services.AddSingleton<IApiHelper, ApiHelper>()
.AddScoped<IClient, Client>();
return services;
}
#else
public static IContainer StructureMapRegisterApiClient(this IContainer container)
{
if (container == null)
{
throw new ArgumentNullException(nameof(container));
}
container.Configure(x =>
{
x.For<IApiHelper>().Use<ApiHelper>().Singleton();
x.For<IClient>().Use<Client>();
});
return container;
}
#endif
}
}
First of all Visual Studio displays the entire #if NET6_0_OR_GREATER part of the extension-method class as greyed out. As well as in the using section in the top. Everything between #else and #endif looks like normal code, with colors and such.
and then I have three errors:
Error CS0234 The type or namespace name 'Extensions' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) ApiClient (net6.0) PATH\DependencyInjectionExtensions.cs 4 Active
Error CS0246 The type or namespace name 'IServiceCollection' could not be found (are you missing a using directive or an assembly reference?) SkolenhetsregistretApiClient (net6.0) PATH\ApiClient\Extensions\DependencyInjectionExtensions.cs 14 Active
If don't do the #if statements in the dependency injection code and I keep all packagereferences in a without conditions, it builds just fine.
I tried swapping the frameworks in but that didn't change anything. It is as if it ignores the net6.0 Framework completely.
Answering myself. Devil is in the details. For reasons unknown my package reference was set to update as this:
<PackageReference Update="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
Instead of Include as this:
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />