question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Supporting third party libraries/frameworks

See original GitHub issue

Recently, we had enquiries for a customer who wanted to deploy their own custom framework on client machines. This discussion is about possible solutions for this scenario in .Net Core 3.

Customer requirements

The developer wants to:

  • Implement a suite of several libraries, that are used by several client apps.
  • Deploy one copy of library-suite on client machines in a central location
  • Push updates to the library-suite without having to recompile the client apps
  • Is happy to change their library-suite/apps to target .net core 3

In particular, the customer specifically asked allowing third party frameworks (similar to standard frameworks like Microsoft.AspNetCore.App).

Solution Options

Additional-deps

This is a simple solution to separate some of the app’s dependencies to a separate (possible shared) location. This option involves:

  • App development: Remove references to the library-suite from the apps, instead use a different light-up option such as startup-hook.
  • On client machines: Deploy the library-suite to a shared location, and set up DOTNET_ADDITIONAL_DEPS when apps are run.

Additional-deps have several known limitations, for example, as noted here.

Startup Hook

This option involves dynamically loading the library-suite into apps during application startup.

  • This requires setting DOTNET_STARTUP_HOOKS to appropriate loader code on client machines at app-startup. The loader code can then use custom logic to load the library-suite from a possible shared/versioned location.
  • This may require some coordination with other parties (ex: profiler) that may use the startup-hook (multiple assemblies can be hooked up at startup).

Custom AppHost

The library developer provides a custom host to be used by the app-developers. The custom host will then setup the appropriate library dependencies during app startup, before starting the runtime.

Components

This option is to load the library-suite as a plugin, where:

  • The library-suite exposes a minimal version (similar to reference assemblies) which only exposes the public API, and implements stub code to load the implementation assemblies dynamically.
  • Apps build with a package-reference to the suite. At runtime, the above stub code loads the actual library code (say, using the AssemblyDependencyResolver), from a possibly shared location.

Third-party frameworks

In this option, the library-suite is published as a framework. This naturally achieves the customer requirements because:

  • The library-suite is published as a nuget package that contains:
    • Its reference assemblies
    • A target file that can be imported by the apps to include this suite as an additional target framework
  • Apps import/reference the above nuget package and ship independent of the library-suite’s implementation
  • The implementation assemblies of the library-suite are installed to dotnet/shared/<library-suite>/<version> on client machines. (one-copy shared, versioned location).

The above approach is straight-forward for developers to use. However, support for third-party frameworks is not yet officially available.

I tried out a prototype, and was able to load a custom framework from a shared location (with some work-arounds for issues discussed below).

Pending work

Here’s the known required work, there will likely be more as we productize this feature:

  • Tooling for adding frameworks: It should easy to add a framework to the list of dependent frameworks published in the runtimeconfig.json file (ex: add a framework to RuntimeFramework item). However, currently doesn’t work in the CLI because the property is overwritten by one of the build tasks. This should be a straightforward issue to fix.
  • Mismatched shared framework versions can cause problems: dotnet/core-setup#4947. This is again a bug that should be fixed.

Reservations

While we agree that supporting third-party frameworks is useful for developers, there are some reservations about making this feature publicly available in .Net Core 3. The concerns are:

  • Bugs: We have a controlled environment with known frameworks. Custom frameworks may trigger unforeseen bugs. It is better to let the multiple-frameworks feature bake with existing framework for a release cycle.
  • Framework references: There are unresolved issues with supporting custom framework-references (which are not exposed by using third-party frameworks with package-references).
  • Install location: Unanticipated issues with custom code within dotnet install location (dotnet/shared/…).
  • Design limitation: We have previously excluded custom frameworks from .net core 3. We may redesign the issue in .net core 3.1. But exposing the feature now may create a compatibility requirement, and restrict design options. Note that users may themselves figure out and use custom frameworks – but these are not supported by the dotnet org.

Discussion

Please add your thoughts / considerations about:

  • Exposing the possibility of third-party frameworks to customers, say as a sample.
  • Any other options to solve the customer scenario.
  • Similar usage scenarios

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:8 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
richlandercommented, Aug 16, 2019

I agree with @nguerrera. We haven’t designed a solution for custom frameworks (or whatever you want to call them). In general, we like the scenario, but it’s hard to design and get right. This is the “full complexity of NuGet” comment that @nguerrera made. We have a way to reason about that for the frameworks that we ship, exactly because they have no NuGet dependencies (by design). If custom frameworks had no NuGet dependencies, the feature would be much easier, but it would also be way too limiting for most of the code that people would want to use for the scenario.

This topic was raised way back in .NET Core 1.0. Along the way, we’ve had customers ask for it, multiple Microsoft teams and also from @normj (our friend at AWS). In short, this may be the hardest objectively reasonable un-delivered customer request we have. We can call that a HORUCR!

We plan on enabling the Xamarin frameworks on top of netcoreapp in the .NET 5 project. As we do that, I’m sure we’ll discuss this scenario again. That said, I don’t think any of the basic challenges will disappear.

Another way to think about this is with .NET Framework. It has the GAC, which satisfies the problem of sharing. The GAC, however, is completely disconnected from NuGet. So, when you deploy updates to the GAC, you are in control of validating that the NuGet graph is kept whole. I’m ignoring all the issues with .NET Framework assembly versioning and publisher policy for this discussion. You might wonder why it is so important to keep the NuGet graph whole. It’s our only way to reason about compatibility across indirect package references (meaning a graph).

Some apps and frameworks might be really simple, so all of this discussion is overkill, however, something like Visual Studio and all the plugins (VSIXs) it supports would be a horror show to get right. When we build features, we need to ensure that they work correctly for the edge cases. We strongly try to avoid 80% features/scenarios. Our strongest advo-critics are always in the 20% case and let us know when we mess up.

0reactions
dasMullicommented, Aug 19, 2019

first comment is suggesting we move our assembly from the runtime package store to the GAC

I was mostly referring to other software i have seen / worked with. Many of which have been started in the .NET 2.0 era and use the GAC. I am in no way suggesting that (it would likely make you unhappy, also .NET Core doesn’t have a GAC comparable with the .NET Framework GAC).

Recent versions of the roslyn compiler are able to emit reference assemblies and the functionality has been wired up in MSBuild, see refout.md for details. There is not yet a built-in way to create reference-assembly-only NuGet packages though, this would have to be done manually using targets. Rx.NET already ships NuGet packages with reference and implementation assemblies by using custom targets (see the PR that introduced them).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Do you use 3rd party libraries/frameworks in your projects ...
A framework is a set of code, file structures, configurations, patterns, and strategies to organize your code and provide an infrastructure for the...
Read more >
C2: Leverage Security Frameworks and Libraries
When incorporating third party libraries or frameworks into your software, it is important to consider the following best practices:.
Read more >
Supported 3rd-party libraries
Supported 3rd -party libraries ; Control libraries. Windows Community Toolkit · Syncfusion · Infragistics · Lightning Chart · Live Charts · OxyPlot ;...
Read more >
Should Developers Use Third Party Libraries?
A guide to evaluating the pros and cons of third party libraries to help you decide which are a good fit for your...
Read more >
About the third party frameworks
We are using third party frameworks in our project when developing, usually we have two ways of managing those third part frameworks: Either ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found