Open StipoR opened 1 year ago
I have the very similar problem, but with interface IDigest. I created 6 libraries as separated projects (Standard 2.0, Standard 2.1, .Net Core 3.1, .Net Core 5.0, .Net Core 6.0, .Net Core 7.0) with the same implementation of IDigest interface. Then I created console app .Net Core 7.0 and added project reference to each of them (one link at a time). Console app worked only with 6.0 and 7.0 libraries. With others it throwed exception
Then I created console app .Net Core 5.0 and it worked well at least with Standard 2.0 and .Net Core 5.0 libraries.
When I used Portable.BouncyCastle 1.9.0 I didn't have such a problem.
This is also the case for a program targeting net6.0 that references a project targeting netstandard2.1 that in turn references BouncyCastle.Cryptography, although the preprocessor directive states that with NETSTANDARD2_1_OR_GREATER
the void BlockUpdate(ReadOnlySpan<byte> input)
overload would be included. The reason is that the BouncyCastle.Cryptography package only includes DLLs for net6.0 and netstandard2.0 but not netstandard2.1. Therefore the netstandard2.1 project uses the BouncyCastle netstandard2.0 library without the overload.
Description
When using a project or a package that targets
netstandard2.0
, references BouncyCastle.Cryptography package, and implements some interfaces from BouncyCastle.Cryptography, such as ISigner, in a project that targetsnet6.0
, System.TypeLoadException is thrown with the message: Method does not have an implementation.Reproduction Steps
Visual Studio solution that reproduces the issue: BouncyCastleCryptographyInterfaceIssue.zip
ClassLibrary1.csproj:
ClassLibrary1.MySigner.cs:
ConsoleApp1.csproj:
ConsoleApp1.Program.cs:
Expected behavior
MyAlgorithmName
is output to the Console.Actual behavior
An exception is thrown:
Regression?
Probably yes, after the member Org.BouncyCastle.Crypto.ISigner.BlockUpdate(ReadOnlySpan input) was added and after other conditional compilation members were added to other interfaces.
Known Workarounds
netstandard2.0
andnet6.0
, but that is not possible if a package is coming from a third party.netstandard2.0
by adding the following to the ConsoleApp1.csproj:But this is ugly because users of a third party package must take care of its BouncyCastle.Cryptography package dependency although they are not using the BouncyCastle.Cryptography package directly in their code.
Other information
The issue is happening because there are several interfaces in BouncyCastle.Cryptography package (such as Org.BouncyCastle.Crypto.ISigner that add a member conditionally when targeting
net6.0
, thus changing the interface contract from the compatiblenetstandard2.0
targeted framework.The Change rules for compatibility state:
The solution is to either remove the problematic interface members (conditionally added ones, such as Org.BouncyCastle.Crypto.ISigner.BlockUpdate(ReadOnlySpan input) ) (this would be a breaking change of BouncyCastle.Cryptography API) or provide a default implementation for them as explained in the Tutorial: Update interfaces with default interface methods.
For example, the fix for the Org.BouncyCastle.Crypto.ISigner.BlockUpdate(ReadOnlySpan input) would be: