Jump to content

How to manage optional dependencies


Recommended Posts

I recently added support for ContractConfigurator.  This entailed adding a reference to ContractConfigurator's DLL so that I could pick up some base classes.  I never intended to make ContractConfigurator a straight-up requirement for the mod - more I wanted to make it so that if you had ContractConfigurator, you'd get some extra content.

Generally speaking, .Net doesn't load dependent dll's until a class that actually uses that DLL gets loaded...  So I thought that because the contract classes have no Unity stuff in them and nothing in the rest of my DLL references the contract classes that I'd be okay.

But... Apparently not.  I should perhaps have figured this since Unity is reflecting over all the types:

[ERR 13:27:03.459] ADDON BINDER: Cannot resolve assembly: ContractConfigurator, Culture=neutral, PublicKeyToken=null

[ERR 13:27:03.464] AssemblyLoader: Exception loading 'ProgressiveColonizationSystem': System.Reflection.ReflectionTypeLoadException: Exception of type 'System.Reflection.ReflectionTypeLoadException' was thrown.
  at (wrapper managed-to-native) System.Reflection.Assembly.GetTypes(System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in <ad04dee02e7e4a85a1299c7ee81c79f6>:0 
  at AssemblyLoader.LoadAssemblies () [0x000e6] in <06f13185617646e5bc801baeab53ab75>:0 

Additional information about this exception:

Seems like I got a couple of choices, and I thought I'd see if anybody has an opinion or maybe a better alternative.

  1. I could create a second mod for the contracts, and have that have a dependency on ContractConfigurator and my mod.
  2. I could create a second DLL which depends on my mod and ContractConfigurator.  This one will not load correctly if CC is not present.

I'm not fond of #2 because that means my mod will generate a nastygram in the log for folks without ContractsConfigurator.  That wouldn't hardly be the first one, but it's bad form.  I'm not fond of #1 because I feel like it makes for more work for the user (heh, and some more work for me too!)

Link to comment
Share on other sites

7 hours ago, peteletroll said:

The clean solution is to use reflection: big topic!

Wouldn't be so clean for this dependency - for ContractsConfigurator you need to create subclasses.

Link to comment
Share on other sites

  • 3 months later...
On 4/4/2021 at 12:13 PM, peteletroll said:

The clean solution is to use reflection: big topic!

Reflexion quickly become a mess to work with, it is prone to breakage when the target mod is updated, and it comes with a very noticable performance cost.

The best way to handle this is to make a separate binary (dll) that reference both mods, and to conditonally load it from your main mod when the other mod is detected.

Example : https://github.com/Kerbalism/Kerbalism/blob/master/src/KerbalismBootstrap/Bootstrap.cs

Edited by Gotmachine
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...