-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Resolving packaged assembly path fail when published #3033
Comments
Is this issue tracker at all read, and are issues considered? Don't see a single comment on any issue posted last couple of weeks... 😕 |
My guess is that you have to preserve the compilation assets when you publish or they won't be there. I don't think published apps probe the actual Nuget cache. |
Yeah, that is kind of what I observe here, but I can't get my head around is why it would make a difference if the application is published or not. Just to be clear, here's the pseudo-code summary of what this issue is about: void Main() {
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath("path\to\assembly.dll");
var dependencyContext = DependencyContext.Load(assembly);
var assemblyResolver = new CompositeCompilationAssemblyResolver(
new ICompilationAssemblyResolver[] {
new AppBaseCompilationAssemblyResolver(Path.GetDirectoryName("path\to\assembly.dll")),
new ReferenceAssemblyPathResolver(),
new PackageCompilationAssemblyResolver()
});
assemblyResolver.TryResolveAssemblyPaths(
new CompilationLibrary(/*package reference*/),
assemblies
);
} I just can't see anywhere in there where there would be something that makes it dependent on if that running entrypoint would execute in a development- or published context? After all, it's not the reference of the published application I'm trying to resolve, but for a given, dynamically loaded assembly. |
@per-samuelsson any update? Did you ensure the asset is copied locally during publish? |
Appreciate you trying to help here - thanks!
I'm afraid not, no. Mainly because ...
... I don't even know what that mean? What asset is that, how do I copy it in a predictable manner when publishing, and of most interest: is that something that should be done during publishing apps normally? |
This should be investigated for 2.1. |
Ok, I finally got back to this. The reason this doesn't work is exactly what @Petermarcu said above:
To give a little bit of background information: When .NET Core apps are run during The way this works is there is a {
"runtimeOptions": {
"additionalProbingPaths": [
"C:\\Users\\eerhardt\\.dotnet\\store\\|arch|\\|tfm|",
"C:\\Users\\eerhardt\\.nuget\\packages",
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackagesFallback",
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
]
}
} You can see my NuGet cache is in this list. Of course, when I When you Now, to see why your code works during dev-time scenarios, know that this list of probing directories gets passed from the At publish-time, the NuGet cache location is no longer passed into So to solve this, you need to think about how you want to resolve these dependent assemblies. Options I can see are:
Either way, the resolvers need to know where to resolve the Ninject assembly from, they can't do it without the required information. Closing as this is by design. |
Wow, best answer ever. With historic design considerations even. Thanks! WTBS, I need to consider this some more, because I do get how published apps necessarily must differ (after all - that's what publishing kind of is about), but what I found so weird here is that it's the loading assembly that is published, not the loaded one. The loaded one still lives as a non-published app, and I still can't get why the dependency context for that should be affected by the fact that the app doing Anyway, it very well might be something I'm missing, so let me consider it all again before I give some final comment. Again, thanks. |
I think I finally see the glitch now. Take a look at this simplified (pseudo) sample: Main() {
// NOTE, important:
Console.Write("Hello, I'm the published app");
// New custom context in where I want to load other assemblies, plug-in stylish
// Basically just extend AssemblyLoadContext and provide no custom loading.
var context = new CustomContext();
// Loading an application that is NOT published. This assembly is now
// loaded in the custom context. Next to this assembly is a `.dev.json`.
var assembly = context.LoadFromAssemblyPath("path\to\appassembly.dll");
// Loading dependency context for the custom loaded assembly. And repeating,
// that assembly is NOT one that is published.
var depContext = DependencyContext.Load(assembly);
// Here's the glitch: the ICompilationAssemblyResolver I need here is one that
// resolved based on the CUSTOM loaded assembly. While instead resolver
// I get using this
var assemblyResolver = new PackageCompilationAssemblyResolver();
// ... is a resolver based on the CURRENT application, i.e. the one published.
// And hence when I later do sequence such as
var compilationLibrary = depContext.GetCompilationLibraryFor("Ninject");
resolver.TryResolveAssemblyPaths(compilationLibrary, out paths);
// ... that resolving operate on the premises of this application, not the one
// I have loaded. I got tricked by that we got the compilation library from the
// DependencyContext we got from the custom loaded application, but that
// don't mean resolving happen in that context.
} So, what I'm after is a way to resolve references based on a dependency context loaded from a custom assembly. If that one is published, I'm fine not finding package references (make total sense). |
If you really want to make this work as you describe, then you probably want to go with my option 2 above - write your own
|
Yes, copy that, and expected that already from the start. But think I got fooled by
I probably will need to do something like that, yeah. Thanks. I have some memory reading some article somewhere some year or so ago that there are ready-to-use readers for those runtime- and deps JSON files, so I find that, maybe it's not going to be super-tricky after all. Again, really appreciate your feedback and help. Thanks! |
I'm using
TryResolveAssemblyPaths
on a composite assembly resolver to resolve path for a reference in the NuGet cache and I observe it fail only when resolving application is published.On the contrary, running the same code using
dotnet run my.csproj
successfully resolve the reference.As short working sample is provided to predictably reproduce. Basic setup is:
AssemblyContext.LoadFromAssemblyPath
to load target and try resolving reference to Ninject package using composite resolver.Program.cs should be pretty straightforward to study.
Steps to reproduce
run_published.bat
or, if not on Windows:Expected behavior
Sample Program.cs output 1, i.e. finding the path to the package.
Actual behavior
Sample sample Program.cs output 0, i.e. assembly path not found.
Environment data
Extra
Running the exact same thing without publishing produce expected result. There is a
run.bat
in sample that illustrate this.The text was updated successfully, but these errors were encountered: