Imagine I have:
Now I'm the author of that third-party utility library.
I'd like that mods can consume it without being worried of assembly version conflicts. For example, ModOne loads Utility 1.0.0 and ModTwo loads Utility 2.0.0.
The default in this case is that the most recent version of the assembly (or the first being loaded, I'm not sure) wins and one of the mods will break.
I'm seeking advice on how to solve this without being a nightmare of configuration for mod authors.
I've searched the web a lot, but there's nothing quite clear and definitive for my specific use case.
Two alternatives I'm considering:
<PackageReference>
, then use <Reference>
to specify the publick key token, and then use an alias to force the use of a specific version. Would that even work? I can also skip NuGet and directly provide a downloadable .dll if that helps.UtilityLib.Feature.V2
. It would work as long as it's always the newest assembly version that is loaded, but I don't know if it's always the case, seems dependent on the .NET runtime is use, and I don't know how the game/Unity handles this. No explicit assembly binding redirect is possible to my knowledge because we don't control the config of the game.I seek specific guidance on this problem, as similar questions but for slightly different use cases have already been answered, generally in a vague manner. Not being extremely familiar with .NET, I'm at a loss.
In conclusion: is possible at all to do that in .NET in a deterministic way that doesn't involve heavy workarounds and complicated setup for mod authors, or should I give up?
Just tried approach #1, with a random already-existing strong named assembly.
This is the configuration in one mod:
<ItemGroup>
<PackageReference Include="Dapper.StrongName" Version="1.60.1" GeneratePathProperty="true" Aliases="DapperV1"/>
<Reference Include="Dapper.StrongName, Version=1.60.0.0, Culture=neutral, PublicKeyToken=e3e8412083d25dd3">
<ReferencePath>$(PkgDapper_StrongName)\Dapper.StrongName.dll</ReferencePath>
<HintPath>$(PkgDapper_StrongName)\Dapper.StrongName.dll</HintPath>
</Reference>
</ItemGroup>
The second mod has the same thing with version 2.0+.
Although both assemblies are present in the output dirs, and that linking works correctly in the editor, at runtime it's still only version 2.0 that's loaded for both mods (logging typeof(typeof(DapperV*::Dapper.SqlMapper).Assembly.GetName().FullName)
).
If you could force <bindingRedirect>
we could have an easier solution, but since you are the library that mods consume you don't have the luxury of setting this.
One thing you can do is have truly different assemblies, not differentiated by version, but by name.
In other words, you have a naming scheme that incorporates the version in the assembly name:
AssemblyV10
AssemblyV12
etc. As such no conflicts will be possible and all assemblies will be resolved individually.
I am not sure, however, if NuGet allows to have a package have different versions based on different assembly names, not just different assembly versions.