I have a library project that extends some functionality on EntityFrameworkCore. I'm looking to support both 2.* and 3.*. My project is setup like so:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
[...]
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.6" />
</ItemGroup>
[...]
</PropertyGroup>
</Project>
In the code I'm using the function EntityTypeExtensions.FindProperty(...). The signature of this function changes between 2.2.6 and 3.0.0.
The project's code (incorrectly?) uses the signature for 2.2.6. This compiles properly (which shouldn't be the case?) in both target frameworks.
I have a unit test project that multi-targets and has conditional references, much like the original project:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;netcoreapp2.0</TargetFrameworks>
[...]
</PropertyGroup>
[...]
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.2.6" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.0.0" />
</ItemGroup>
[...]
</Project>
All unit tests (incorrectly?) pass in both target frameworks.
Note that even though it builds and tests pass, when the library is used in a netcore3 project (which references efcore 3.0.0 directly) it throws the following exception. Which seems completely reasonable, I just don't understand why it allowed me to get to this point.
System.MissingMethodException: Method not found: 'Microsoft.EntityFrameworkCore.Metadata.IProperty Microsoft.EntityFrameworkCore.EntityTypeExtensions.FindProperty(Microsoft.EntityFrameworkCore.Metadata.IEntityType, System.Reflection.PropertyInfo)'.
Questions:
- Is there a way around this so it gets picked up as an error/warning/something, at least, during the build?
- Is the solution to this to use preprocessor directives around the call to
.FindProperty(...)and based on the framework make the correct method call? Isn't there a way to do this based on the version ofefcoreinstead of the dependency? - Is there a way to unit test this properly with the different packages? Right now as it is, I expected the unit tests to fail in one of the versions since the method does not exist.