Skip to content

Improve auto-discovery of configuration assemblies in bundled mode #304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from

Conversation

0xced
Copy link
Member

@0xced 0xced commented Mar 27, 2022

Neither the dependency context nor scanning DLL files on disk works with bundled (single-file) applications.

Given that the configuration assemblies have actually been loaded, using AppDomain.CurrentDomain.GetAssemblies() works for both bundled and non bundled applications.

@0xced 0xced force-pushed the auto-discovery-single-exe branch from e2a7573 to d874b52 Compare March 27, 2022 22:16
Neither the dependency context nor scanning DLL files on disk works with bundled (single-file) applications.

Given that the configuration assemblies have actually been loaded, using `AppDomain.CurrentDomain.GetAssemblies()` works for both bundled and non bundled applications.
@0xced 0xced force-pushed the auto-discovery-single-exe branch from d874b52 to cad35a0 Compare March 27, 2022 22:18
@nblumhardt
Copy link
Member

Thanks for tackling this, @0xced! 👏

Just a thought, since it's necessary in this mode to list assemblies specifically, could we get away from needing any scanning code at all (in 'bundled' mode), and just list all dependencies in the ReadFrom.Configuration() call?

E.g. for your example:

loggerConfiguration.ReadFrom.Configuration(
    context.Configuration,
    usingAssemblies: new[]
    {
        typeof(ConsoleLoggerConfigurationExtensions).Assembly,
        typeof(SeqLoggerConfigurationExtensions).Assembly
    })

0xced added 3 commits March 28, 2022 10:19
By reading the deps json directly from the application host the with the help of the`Microsoft.NET.HostModel` package.
* Test with both IncludeAllContentForSelfExtract as true and false
* Don't show a window when building the single file app
* Make sure the test pass on all tested platforms by adding a global.json file
This is a proof-of-concept implementation (using an internal method of the Microsoft.NET.HostModel package) to ensure that all tests pass also on Windows.
@0xced
Copy link
Member Author

0xced commented Mar 28, 2022

You're absolutely right about explicitly passing the assemblies to the Configuration method, this is a much better (and simpler) approach!

But I think we can do even better and having the configuration assemblies automatically discovered even in bundled mode. I tried something in d8d162c which works fine on macOS but fails on Windows.

I implemented a proof-of-concept workaround in 3d2e5df which relies on an internal method of the Microsoft.NET.HostModel package. I'll rewrite it properly and once its done the Microsoft.NET.HostModel package dependency can be dropped altogether. So please don't merge this pull request as is, you could even turn it into a draft pull request for good measure.

Ideally, this logic should be implemented in the Microsoft.Extensions.DependencyModel project directly. I'll probably try to submit a pull request there so that eventually using DependencyContext.Default will work properly for both bundled and non bundled applications. That probably won't happen before .NET 7 or more realistically .NET 8, though.

0xced added 2 commits April 4, 2022 17:08
Also fix possible concurrency issue by using different bin and obj directories.
As [stated by Vitek Karas][1]:
> Also note that the `Microsoft.NET.HostModel` package is not intended as a public API, it's only intended use is from the SDK.

[1]: dotnet/runtime#67386 (comment)
@0xced 0xced force-pushed the auto-discovery-single-exe branch from 0f21889 to 11bc6de Compare April 4, 2022 15:10
@0xced
Copy link
Member Author

0xced commented Apr 5, 2022

I have rewritten the code (in 11bc6de) to read the bundled deps.json without taking a dependency on Microsoft.NET.HostModel, which as stated by Vitek Karas is not intended as a public API.

The hardest part was to write the SingleFileApp test in a safe way if run concurrently across different target frameworks by not sharing the obj directories when compiling the TestSingleFileApp project.

This pull request is now ready for review.

@nblumhardt
Copy link
Member

Hi @0xced - thanks for the follow-up!

I'd be a little anxious to take this kind of dependency on the (undocumented?) bundle manifest and (loosely documented but possibly changeable?) .deps file formats; my guess is that the Microsoft.NET.HostModel API is not-for-public-consumption because the underlying infrastructure is subject to change 🤔

Still does make a nice job of addressing a tricky scenario, though - I might need to give it a bit more thought. @serilog/reviewers-configuration any sense of what would be best, here?

@0xced
Copy link
Member Author

0xced commented Apr 8, 2022

Toying around with single file apps and the deps.json file was a fun and very educative experiment. I learned a ton of things about single file apps by reading the design documents and the CoreCLR source code. But eventually it should really be implemented at the Microsoft.Extensions.DependencyModel level. I have even created a repository and written technical notes and thoughts in the README: https://github.com/0xced/SingleFileAppDependencyContext I took some code written for Serilog.Settings.Configuration (in this very pull request) and pushed the experiment a bit further. I hope this will serve as a good basis for discussing a stable implementation with the .NET Runtime team.

In the end the best solution to avoid listing assemblies in the configuration file is probably what you proposed in your initial reply, i.e. explicitly passing a list of assemblies to the Configuration method. Simple, straightforward!

Would you be interested in a pull request to implement this new Configuration overload? I guess it will be more work to update the documentation than to write the code itself. 😁

@skomis-mm
Copy link
Contributor

skomis-mm commented Apr 10, 2022

Great work, @0xced 👍

IMO the risk of breaking changes in the bundle structure should be low.
Design of the bundle marker is public. Also, this comment says it can be used from the source code 🤔

@nblumhardt
Copy link
Member

Okay, great to know! 😎

I'm not well-placed to review this currently, but gets a 👍 from me in case @skomis-mm or another maintainer is able to dig in deeply enough.

@0xced
Copy link
Member Author

0xced commented May 9, 2022

Closing this pull request in favor of #310.

Leaving https://github.com/0xced/SingleFileAppDependencyContext as a record of the work I did that should eventually be part of Microsoft.Extensions.DependencyModel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants