libphonenumber-csharp
libphonenumber-csharp copied to clipboard
Unable to load PhoneNumbers.dll in signed assembly
When depending on PhoneNumbers.dll through NuGet in a project producing a strong name signed assembly this exception is thrown each time PhoneNumbers.dll would be used:
System.IO.FileLoadException: Could not load file or assembly 'PhoneNumbers, Version=8.8.10.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044) File name: 'PhoneNumbers, Version=8.8.10.0, Culture=neutral, PublicKeyToken=null'
This can be fixed by strong name signing PhoneNumbers.dll see PR #51
This has been brought up a few times. https://github.com/twcclegg/libphonenumber-csharp/issues/18, https://github.com/twcclegg/libphonenumber-csharp/issues/48 and that which it references https://github.com/octokit/octokit.net/issues/405 Given that it has come up a few times now I'm going to take another look at it and make sure it don't cause issue for any existing users.
After more reading I'm thinking that this will do more harm than good and be disruptive to current consumers of the package. https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/strong-name-signing.md https://www.pedrolamas.com/2016/03/01/still-strong-naming-your-assemblies-you-do-know-its-2016-right/
Please note that the author of the second link had second thoughts later in 2018:
https://www.pedrolamas.com/2018/09/11/start-strong-naming-your-assemblies/
Any update? our project need this package to be strongly named as well...
Per https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/strong-naming:
DO NOT add, remove, or change the strong naming key.
Modifying an assembly's strong naming key changes the assembly's identity and breaks compiled code that uses it.
This is why I haven't done this over the past years was basically that, though I hadn't seen it stated in such a succinct way by Microsoft.
If people would get benefit of the library being nuget signed and wants to pay for the cert that could be done.
Thanks @twcclegg, I'm not an expert in this area, but I feel like there is a misunderstanding of that MS documentation.
-
It first recommends people strongly name their package. If people did so, then they can not reference your package.
-
For the "Do Not..." you shared, maybe nuget can handle it automatically? whenever you update a package, it will add a binding redirect if needed, in this case, I gonna assume if the key got added then the package's id will change, nuget should be able to generate a new binding redirect to indict the new id?
Yeah if someone can prove it won't break things, but my reading of the quoted text above is that it's good to strong name libraries when they are first established but that ship as obviously sailed. I had considered publishing a v8.13.16-signed which might work as a prerelease and not break people. They do say not to add .StrongNamed
as a second version.
Hi @twcclegg - Any update on this? We need strongly named version. Thanks
Hi Saba, per the above "if someone can prove it won't break things". I'm happy for contributions to this effort but it is not something I have time for.
I don't need strong name signing personally, but my 2c is it's the right thing to do for libraries.
The msft documentation you linked says:
Because of the viral nature of strong-naming, it is recommended that publicly published .NET libraries are strong-named. Not strong-naming a .NET library excludes anyone who does need to strong-name their application or library from using it. Read more about .NET libraries and strong-naming in the .NET Library Guidance.
Strong name signing is not a security measure, it only provides a unique identity to an assembly.
The pros of strong name signing are:
- Can be installed into GAC, or executed from COM, and it's also a requirement for ClickOnce
- Signed libraries can be used by both signed assemblies and unsigned assemblies, while unsigned libraries can only be used in unsigned assemblies.
- SN is ignored in more modern frameworks (eg. .NET/core) so makes no difference there
- Two different versions of the assembly can now be loaded at the same time
- It's non-trivial for a developer to strong name sign the package themselves: clone the repo, compile it, sign it, then copy the
.dll
into their project. Repeat when there is an update.
The cons:
- You can only depend on libraries which are also SN signed (but I don't think that applies here, as there are no dependencies)
- Binding redirects can suck, but if you're a .Net Framework developer you'll be used to it, and it's not always an issue.
- Replacing a strong name signed dll with a compatible newer version (eg. to fix a bug) may not be possible without also replacing the exe.
How to do it?
- Generate a
.snk
usingsn.exe
and check it in to the root of the repo. - Add
SignAssembly
andAssemblyOriginatorKeyFile
to the csproj
Conclusion:
- Strong name signing is free and easy to do.
- For users of dotnet/core, this has zero impact whatsoever.
- For users of .Net Framework, users requiring strong name signing will now be able to use the library. Users who do not use strong name signing may or may not be slightly inconvenienced depending on their specific setup, but there are common/expected workarounds and processes to deal with this.
In regards to this snippet you copied:
DO NOT add, remove, or change the strong naming key. Modifying an assembly's strong naming key changes the assembly's identity and breaks compiled code that uses it.
Yes, this is true, anybody who is updating the nuget package (eg. from v1 to v2) will need to re-compile their app. But I hardly see this as a problem. Who in their right mind updates a NuGet package by dropping in a new dll, without recompiling their software?