Search code examples
c#.netdependenciesshared-librariesassemblies

Is it possible to develop a .NET library with optional reference/dependency and still benefit from IntelliSense/typing?


Let's say I want to write a library and it should invoke OptionalLibClass.Run() if such method is available. However the assembly is big (like SkiaSharp) so I do not want to include it with my library, in case the end developer only need other features.

I know it's possible to use System.Reflection but you lose the benefit of Intellisense and static typing as well as getting a performance hit (though pretty minor IMO, usually it's not a problem).

Expectation:

  • Add OptionalLib as a reference. Still it should be optional: user should not have to install OptionalLib if they install MyLib from Nuget for example.

  • Write the following code in the library:

using OptionalLib; // .NET should be able to see this namespace
// ...

if (OptionalLibAvailable()) // How to implement OptionalLibAvailable?
{
    OptionalLibClass.Run() // IntelliSense should be able to show me OptionalLibClass
}
  • End user (developer) doesn't need to do anything beside referring to OptionalLib if they want to.

Note that there may be multiple optional libs.

Possible Workaround:

While typing the questions, I thought of a few solutions though they are not as simple as I would like:

  • Make an interface IOptionalRun for example. However, end user has to provide their own implementation.

  • Following above workaround, add a separate MyLib (without OptionalLib) and MyLib.OptionalLib (with OptionalLib) that provides an IOptionalRun implementation. I think this is the best workaround so far and the closest to my expectation but we still need 2 separate assemblies and the user has to register the interface somehow. This workaround has a problem when there are multiple optional libraries and we want users to have any of their combinations (for example: do A if A is available, B if B is available but C if both A and B are available)

  • Using dynamic: the worst workaround IMO. Technically a shorter System.Reflection solution but still have all its problem.

EDIT: After reading my question again, turn out a solution will probably be the answer to: how to pack/create a Nuget package for a project that contains OptionalLib but it should not be in the dependency list (and don't pack that dll when packing the Nuget package). OptionalLibAvailable can just be a Reflection call to see if OptionalLib assembly is loaded in the current AppDomain.


Solution

  • Edit the properties of that big assembly reference, in the properties window, there is a property Private Assets, set its value to All, then repack your library, you will find that reference has gone from the .nuspec file.