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

Assembly.GetExecutingAssembly, AppDomain.CurrentDomain and similar #1784

Closed
tomasherceg opened this Issue May 17, 2015 · 44 comments

Comments

Projects
None yet
@tomasherceg

tomasherceg commented May 17, 2015

Are there any plans to include the following classes and methods in near future? I am porting my framework (http://github.com/riganti/redwood) to .NET Core and I miss these methods.

  • Assembly.GetReferencedAssemblies
  • Assembly.GetExecutingAssembly
  • Assembly.GetEntryAssembly
  • Assembly.GetCallingAssembly
  • Assembly.CreateInstance
  • Assembly.Load which takes byte array or a stream
  • AppDomain.CurrentDomain.GetAssemblies
  • AppDomain.CurrentDomain.AssemblyResolve

Or is there another way in the new .NET Core how to list all loaded assemblies, get the assembly of method that is being executed or a calling method etc.?

@HellBrick

This comment has been minimized.

Show comment
Hide comment
@HellBrick

HellBrick May 17, 2015

+1, at least for some of them. Personally, I use Assembly.GetEntryAssembly() (for logging and other diagnostics purposes) and AppDomain.CurrentDomain.GetAssemblies() (for discovering modules in the loaded assemblies) fairly often.

HellBrick commented May 17, 2015

+1, at least for some of them. Personally, I use Assembly.GetEntryAssembly() (for logging and other diagnostics purposes) and AppDomain.CurrentDomain.GetAssemblies() (for discovering modules in the loaded assemblies) fairly often.

@tomasherceg

This comment has been minimized.

Show comment
Hide comment
@tomasherceg

tomasherceg May 17, 2015

Maybe the more important question is: "Is it correct to use the old reflection API, or is there a better API to do the tasks?"
I have saw ILibraryManager etc. however there are not much information about this yet.

tomasherceg commented May 17, 2015

Maybe the more important question is: "Is it correct to use the old reflection API, or is there a better API to do the tasks?"
I have saw ILibraryManager etc. however there are not much information about this yet.

@HellBrick

This comment has been minimized.

Show comment
Hide comment
@HellBrick

HellBrick May 17, 2015

I decided to take a look at the way ASP.NET MVC looks up controller classes. It indeed uses ILibraryManager to get the names of the assemblies that reference MVC stuff, does Assembly.Load() for them and then uses Assembly.DefinedTypes to search for the types of interest. See DefaultAssemblyProvider and DefaultControllerTypeProvider for details.

I just haven't figured out where to get an instance of ILibraryManager yet ;)

HellBrick commented May 17, 2015

I decided to take a look at the way ASP.NET MVC looks up controller classes. It indeed uses ILibraryManager to get the names of the assemblies that reference MVC stuff, does Assembly.Load() for them and then uses Assembly.DefinedTypes to search for the types of interest. See DefaultAssemblyProvider and DefaultControllerTypeProvider for details.

I just haven't figured out where to get an instance of ILibraryManager yet ;)

@HellBrick

This comment has been minimized.

Show comment
Hide comment
@HellBrick

HellBrick May 17, 2015

Got it, at least partially:

internal static class ServiceProviderExtensions
{
    public static T GetService<T>( this IServiceProvider serviceProvider )
    {
        return (T) serviceProvider.GetService( typeof( T ) );
    }
}

public class Program
{
    private readonly IServiceProvider _serviceProvider;

    public Program( IServiceProvider serviceProvider )
    {
        _serviceProvider = serviceProvider;
    }

    public void Main( string[] args )
    {
        var libraryManager = _serviceProvider.GetService<ILibraryManager>();

        // and this is at least some kind of info about the entry point
        var applicationEnvironment = _serviceProvider.GetService<IApplicationEnvironment>();
        string appName = applicationEnvironment.ApplicationName;        
    }
}

I wonder if there is some static property somewhere that gets this default instance of IServiceProvider though, because I can see how passing something like ILibraryManager all the way from the entry point to wherever it's actually needed can be a bit annoying.

HellBrick commented May 17, 2015

Got it, at least partially:

internal static class ServiceProviderExtensions
{
    public static T GetService<T>( this IServiceProvider serviceProvider )
    {
        return (T) serviceProvider.GetService( typeof( T ) );
    }
}

public class Program
{
    private readonly IServiceProvider _serviceProvider;

    public Program( IServiceProvider serviceProvider )
    {
        _serviceProvider = serviceProvider;
    }

    public void Main( string[] args )
    {
        var libraryManager = _serviceProvider.GetService<ILibraryManager>();

        // and this is at least some kind of info about the entry point
        var applicationEnvironment = _serviceProvider.GetService<IApplicationEnvironment>();
        string appName = applicationEnvironment.ApplicationName;        
    }
}

I wonder if there is some static property somewhere that gets this default instance of IServiceProvider though, because I can see how passing something like ILibraryManager all the way from the entry point to wherever it's actually needed can be a bit annoying.

@tomasherceg

This comment has been minimized.

Show comment
Hide comment
@tomasherceg

tomasherceg May 17, 2015

I wouldn't mind passing the ILibraryManager instance to the place where I need it - I use IoC/DI containers in my apps so I am used to the pattern that each class requires all its dependencies. That's not such a problem, the container solves the thing for you.

However thanks for the sample how they do it in MVC - I have tried it but throws some weird exceptions. I'll need to dig into it in more detail.

tomasherceg commented May 17, 2015

I wouldn't mind passing the ILibraryManager instance to the place where I need it - I use IoC/DI containers in my apps so I am used to the pattern that each class requires all its dependencies. That's not such a problem, the container solves the thing for you.

However thanks for the sample how they do it in MVC - I have tried it but throws some weird exceptions. I'll need to dig into it in more detail.

@akoeplinger

This comment has been minimized.

Show comment
Hide comment
@akoeplinger

akoeplinger May 17, 2015

Member

ILibraryManager is a DNX concept and it is indeed passed via DI there, but it's not available on plain .NET Core.

Member

akoeplinger commented May 17, 2015

ILibraryManager is a DNX concept and it is indeed passed via DI there, but it's not available on plain .NET Core.

@tomasherceg

This comment has been minimized.

Show comment
Hide comment
@tomasherceg

tomasherceg May 18, 2015

I know - there are two parts of this question.
The first part is how to do it in pure .NET Core and if there are some plans to add the API mentioned before.
The second part is how to deal with this right now in ASP.NET application that will be running on DNX.

I believe I can solve the second part and use the ILibraryManager, however I'd like to know the answer to the original question - whether it is planned to add the API soon or how shall we deal with with the problem.

tomasherceg commented May 18, 2015

I know - there are two parts of this question.
The first part is how to do it in pure .NET Core and if there are some plans to add the API mentioned before.
The second part is how to deal with this right now in ASP.NET application that will be running on DNX.

I believe I can solve the second part and use the ILibraryManager, however I'd like to know the answer to the original question - whether it is planned to add the API soon or how shall we deal with with the problem.

@xanather

This comment has been minimized.

Show comment
Hide comment
@xanather

xanather May 28, 2015

I was surprised when these API's didn't exist in .NET Core. Why not? Some project are looking to support .NET Core, will it eventually be added or do we need to implement it ourselves here?

Edit: If it's not going to added I think it should be stated here to prevent future confusion from others trying to port things over.

xanather commented May 28, 2015

I was surprised when these API's didn't exist in .NET Core. Why not? Some project are looking to support .NET Core, will it eventually be added or do we need to implement it ourselves here?

Edit: If it's not going to added I think it should be stated here to prevent future confusion from others trying to port things over.

@xanather

This comment has been minimized.

Show comment
Hide comment
@xanather

xanather May 28, 2015

Using type.GetTypeInfo() helps with this issue for obtaining an Assembly object instances if anyone else comes along it.

xanather commented May 28, 2015

Using type.GetTypeInfo() helps with this issue for obtaining an Assembly object instances if anyone else comes along it.

@exyi

This comment has been minimized.

Show comment
Hide comment
@exyi

exyi Jun 26, 2015

It's quite strange that Assembly.Load(byte[]) exists in CoreCLR project: https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Reflection/Assembly.cs#L392
Can someone explain me why it's there and we can't use it?

exyi commented Jun 26, 2015

It's quite strange that Assembly.Load(byte[]) exists in CoreCLR project: https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Reflection/Assembly.cs#L392
Can someone explain me why it's there and we can't use it?

@nguerrera

This comment has been minimized.

Show comment
Hide comment
@nguerrera

nguerrera Jun 26, 2015

Member

cc @gkhanna79

@exyi It actually gets modified to be internal in the build process. It is complicated by various factors around how this code gets shared in many different configurations.

.NET Core does expose a mechanism to load byte arrays. Take a look at the System.Runtime.Loader package which provides AssemblyLoadContext

Note that the design there is to allow an app-model host such as DNX a way to take care of resolution in the way that is appropriate for its environment. So if you are running in DNX, you'll want to go through their loader API, which is implemented using AssemblyLoadContext.

As for the other APIs requested:

  • GetReferencedAssemblies is not something that I recall discussing so I'll have to check with others on the team.
  • GetEntryAssembly is very sensitive to the App Model. Do you really want the AssemblyInfo or are you looking for the application base path? You can use AppContext.BaseDirectory for the latter.
  • GetCallingAssembly has all sorts of problems. For one, it is not well defined due to inlining (see Remarks). For another, code that changes behavior based on the calling assembly is extremely hard to reason about. If you're using it for diangostics, consider the drastically lighter weight Caller Information.
  • GetExecutingAssembly is something we will likely bring back. On current platforms due to lack of optimization, it ends up being much slower than the equivalent typeof(CurrentType).GetTypeInfo().Assembly. However, it is possible to fix the code generation and we will consider doing that for more compatibility with existing source code. In the meantime, just do the transformation yourself and your code will speed up on all platforms.
  • AssemblyResolve is replaced by AssemblyLoadContext (see above)
  • AppDomain.GetAssemblies could theoretically become AssemblyLoadContext.GetAssemblies(), but I'll defer to @gkhanna79 on whether that would be a good idea.
Member

nguerrera commented Jun 26, 2015

cc @gkhanna79

@exyi It actually gets modified to be internal in the build process. It is complicated by various factors around how this code gets shared in many different configurations.

.NET Core does expose a mechanism to load byte arrays. Take a look at the System.Runtime.Loader package which provides AssemblyLoadContext

Note that the design there is to allow an app-model host such as DNX a way to take care of resolution in the way that is appropriate for its environment. So if you are running in DNX, you'll want to go through their loader API, which is implemented using AssemblyLoadContext.

As for the other APIs requested:

  • GetReferencedAssemblies is not something that I recall discussing so I'll have to check with others on the team.
  • GetEntryAssembly is very sensitive to the App Model. Do you really want the AssemblyInfo or are you looking for the application base path? You can use AppContext.BaseDirectory for the latter.
  • GetCallingAssembly has all sorts of problems. For one, it is not well defined due to inlining (see Remarks). For another, code that changes behavior based on the calling assembly is extremely hard to reason about. If you're using it for diangostics, consider the drastically lighter weight Caller Information.
  • GetExecutingAssembly is something we will likely bring back. On current platforms due to lack of optimization, it ends up being much slower than the equivalent typeof(CurrentType).GetTypeInfo().Assembly. However, it is possible to fix the code generation and we will consider doing that for more compatibility with existing source code. In the meantime, just do the transformation yourself and your code will speed up on all platforms.
  • AssemblyResolve is replaced by AssemblyLoadContext (see above)
  • AppDomain.GetAssemblies could theoretically become AssemblyLoadContext.GetAssemblies(), but I'll defer to @gkhanna79 on whether that would be a good idea.
@HellBrick

This comment has been minimized.

Show comment
Hide comment
@HellBrick

HellBrick Jun 27, 2015

@nguerrera

GetEntryAssembly is very sensitive to the App Model. Do you really want the AssemblyInfo or are you looking for the application base path? You can use AppContext.BaseDirectory for the latter.

What I really want is the name of the assembly that is the logical entry point of my code that's being run. If the code is being run in a simple console app, then I want the name of the console app assembly. If the code is being run in a test harness, then I want the name of the test assembly my test is located in. If the code is being run in an IIS-hosted website, I want the name of the website assembly. That's really more than GetEntryAssembly allows today, so I have to jump through some hoops to do it at the moment (some dirty hacks based on examining the call stack).

And even though I said I want the name of the assembly, I can easily imagine scenarios where I would also need its version, so I guess having the full AssemblyInfo can be useful here.

HellBrick commented Jun 27, 2015

@nguerrera

GetEntryAssembly is very sensitive to the App Model. Do you really want the AssemblyInfo or are you looking for the application base path? You can use AppContext.BaseDirectory for the latter.

What I really want is the name of the assembly that is the logical entry point of my code that's being run. If the code is being run in a simple console app, then I want the name of the console app assembly. If the code is being run in a test harness, then I want the name of the test assembly my test is located in. If the code is being run in an IIS-hosted website, I want the name of the website assembly. That's really more than GetEntryAssembly allows today, so I have to jump through some hoops to do it at the moment (some dirty hacks based on examining the call stack).

And even though I said I want the name of the assembly, I can easily imagine scenarios where I would also need its version, so I guess having the full AssemblyInfo can be useful here.

@weshaggard

This comment has been minimized.

Show comment
Hide comment
@weshaggard

weshaggard Nov 18, 2015

Member

@pallavit can you please make sure these are covered by your API gap list.

Member

weshaggard commented Nov 18, 2015

@pallavit can you please make sure these are covered by your API gap list.

@gkhanna79

This comment has been minimized.

Show comment
Hide comment
@gkhanna79

gkhanna79 Nov 24, 2015

Member

Yes, AppDomain.GetAssemblies can have its semantic equivalent in AssemblyLoadContext.GetAssemblies.

Member

gkhanna79 commented Nov 24, 2015

Yes, AppDomain.GetAssemblies can have its semantic equivalent in AssemblyLoadContext.GetAssemblies.

@davidfowl

This comment has been minimized.

Show comment
Hide comment
@davidfowl

davidfowl Dec 12, 2015

Contributor

What's the deal with this bug? These APIs are sorely needed.

Contributor

davidfowl commented Dec 12, 2015

What's the deal with this bug? These APIs are sorely needed.

@JaCraig

This comment has been minimized.

Show comment
Hide comment
@JaCraig

JaCraig Dec 29, 2015

Any update on GetReferencedAssemblies? Makes life when dealing with Roslyn a bit easier at times. Last comment on it is from June with no real update afterwords.

JaCraig commented Dec 29, 2015

Any update on GetReferencedAssemblies? Makes life when dealing with Roslyn a bit easier at times. Last comment on it is from June with no real update afterwords.

@CoreyKaylor

This comment has been minimized.

Show comment
Hide comment
@CoreyKaylor

CoreyKaylor Jan 6, 2016

Porting a project and some of those methods are desperately needed. Assembly.GetReferencedAssemblies and Assembly.GetExecutingAssembly specifically for me.

CoreyKaylor commented Jan 6, 2016

Porting a project and some of those methods are desperately needed. Assembly.GetReferencedAssemblies and Assembly.GetExecutingAssembly specifically for me.

@weshaggard

This comment has been minimized.

Show comment
Hide comment
@weshaggard

weshaggard Jan 6, 2016

Member

Assembly.GetExecutingAssembly has an easy replacement of typeof().GetTypeInfo().Assembly. That said we are looking into these APIs and considering bringing a number of them to .NET Core.

Member

weshaggard commented Jan 6, 2016

Assembly.GetExecutingAssembly has an easy replacement of typeof().GetTypeInfo().Assembly. That said we are looking into these APIs and considering bringing a number of them to .NET Core.

@CoreyKaylor

This comment has been minimized.

Show comment
Hide comment
@CoreyKaylor

CoreyKaylor Jan 6, 2016

@weshaggard that isn't equivalent, it assumes you have access to a type in the executing assembly.

CoreyKaylor commented Jan 6, 2016

@weshaggard that isn't equivalent, it assumes you have access to a type in the executing assembly.

@weshaggard

This comment has been minimized.

Show comment
Hide comment
@weshaggard

weshaggard Jan 6, 2016

Member

@CoreyKaylor Yes it does but you are in the executing assembly so just take the type of the method you are making this call from. There should be no cases where you cannot access the type of the assembly you are trying to execute this method call in.

Member

weshaggard commented Jan 6, 2016

@CoreyKaylor Yes it does but you are in the executing assembly so just take the type of the method you are making this call from. There should be no cases where you cannot access the type of the assembly you are trying to execute this method call in.

@CoreyKaylor

This comment has been minimized.

Show comment
Hide comment
@CoreyKaylor

CoreyKaylor Jan 6, 2016

@weshaggard Ah dang, you're right. I was getting it mixed up with another method. 😇

CoreyKaylor commented Jan 6, 2016

@weshaggard Ah dang, you're right. I was getting it mixed up with another method. 😇

@weshaggard

This comment has been minimized.

Show comment
Hide comment
@weshaggard

weshaggard Jan 7, 2016

Member

@CoreyKaylor no worries I often get it missed up with Assembly.GetEntryAssembly(), so I had to take a double take as well :)

Member

weshaggard commented Jan 7, 2016

@CoreyKaylor no worries I often get it missed up with Assembly.GetEntryAssembly(), so I had to take a double take as well :)

@enricosada enricosada referenced this issue Feb 24, 2016

Closed

use dotnet cli to build NETCore #395

4 of 5 tasks complete

haf referenced this issue in SuaveIO/suave Feb 25, 2016

@ryanmolden

This comment has been minimized.

Show comment
Hide comment
@ryanmolden

ryanmolden Mar 11, 2016

@weshaggard

Assembly.GetExecutingAssembly has an easy replacement of typeof().GetTypeInfo().Assembly. That said we are looking into these APIs and considering bringing a number of them to .NET Core.

I am seeing that Location on said Assembly object is coming back as the empty string. This seems very odd. How can I find the on disk location of the assembly in which code is executing? I am on 1.0.0-rc2-16351 and CodeBase doesn't seem to exist (at least the compiler says that, though the online source code seems to make it appear it should).

ryanmolden commented Mar 11, 2016

@weshaggard

Assembly.GetExecutingAssembly has an easy replacement of typeof().GetTypeInfo().Assembly. That said we are looking into these APIs and considering bringing a number of them to .NET Core.

I am seeing that Location on said Assembly object is coming back as the empty string. This seems very odd. How can I find the on disk location of the assembly in which code is executing? I am on 1.0.0-rc2-16351 and CodeBase doesn't seem to exist (at least the compiler says that, though the online source code seems to make it appear it should).

@davidfowl

This comment has been minimized.

Show comment
Hide comment
@davidfowl

davidfowl Mar 11, 2016

Contributor

That's because when using DNX, the assembly is compiled in memory

Contributor

davidfowl commented Mar 11, 2016

That's because when using DNX, the assembly is compiled in memory

@ryanmolden

This comment has been minimized.

Show comment
Hide comment
@ryanmolden

ryanmolden Mar 11, 2016

@davidfowl That would explain it. In our scenario we have two machines with the same version of DNX and the same coreCLR version and yet one of them reports our unit test directory as AppContext.BaseDirectory and the other reports the directory dnx.exe is in as AppContext.BaseDirectory. The same script runs on both machines to invoke dnx and I do not believe we did any special setup on the one that is working (the one that shows the unit test directory as our BaseDirectory).

I tried using appbase explicitly but dnx chokes on it no matter where I put it in the command line, it ends up thinking our command (test) is a dll we want it to load.

Ideas on this? This is the reason we wanted Location/CodeBase.

ryanmolden commented Mar 11, 2016

@davidfowl That would explain it. In our scenario we have two machines with the same version of DNX and the same coreCLR version and yet one of them reports our unit test directory as AppContext.BaseDirectory and the other reports the directory dnx.exe is in as AppContext.BaseDirectory. The same script runs on both machines to invoke dnx and I do not believe we did any special setup on the one that is working (the one that shows the unit test directory as our BaseDirectory).

I tried using appbase explicitly but dnx chokes on it no matter where I put it in the command line, it ends up thinking our command (test) is a dll we want it to load.

Ideas on this? This is the reason we wanted Location/CodeBase.

@andschwa

This comment has been minimized.

Show comment
Hide comment
@andschwa

andschwa Apr 15, 2016

Member

@weshaggard How is this issue closed? As @davidfowl stated, there is still no way to get a list of loaded assemblies, and this is blocking multiple partner teams. Am I missing something?

Member

andschwa commented Apr 15, 2016

@weshaggard How is this issue closed? As @davidfowl stated, there is still no way to get a list of loaded assemblies, and this is blocking multiple partner teams. Am I missing something?

@gkhanna79

This comment has been minimized.

Show comment
Hide comment
@gkhanna79

gkhanna79 Apr 15, 2016

Member

there is still no way to get a list of loaded assemblies

The runtime does not support this functionality. More importantly, there is no good way to answer this in face of multiple load contexts that could be active within the AppDomain, not all of which your code would own. Thus, returning assemblies from those to you does not make sense.

Do note that LoadContext, from the perspective of assembly isolation, is the equivalent of what AppDomain provided. If you are interested in tracking the assemblies loaded by your own load context, you should be able to create a tracking list as they get loaded via your load context.

Member

gkhanna79 commented Apr 15, 2016

there is still no way to get a list of loaded assemblies

The runtime does not support this functionality. More importantly, there is no good way to answer this in face of multiple load contexts that could be active within the AppDomain, not all of which your code would own. Thus, returning assemblies from those to you does not make sense.

Do note that LoadContext, from the perspective of assembly isolation, is the equivalent of what AppDomain provided. If you are interested in tracking the assemblies loaded by your own load context, you should be able to create a tracking list as they get loaded via your load context.

@andschwa

This comment has been minimized.

Show comment
Hide comment
@andschwa

andschwa Apr 15, 2016

Member

@gkhanna79 That presents one major problem:

The corehost used by .NET Core apps adds all local assemblies to the TPA, see dotnet/cli#2044.

The local assemblies include the assemblies that we would otherwise need to load via the LoadContext. But loading them is blocked by design, since they're in the TPA.

These two design decisions seem incompatible. We want to track our assemblies via our load context, we also want to track the default assemblies from .NET Core; it does not seem that there is a solution to this.

@daxian-dbw, can you weigh in on the problem here?

Edit: I have to admit I am pretty new to this whole domain; there may be an obvious solution we're missing.

Member

andschwa commented Apr 15, 2016

@gkhanna79 That presents one major problem:

The corehost used by .NET Core apps adds all local assemblies to the TPA, see dotnet/cli#2044.

The local assemblies include the assemblies that we would otherwise need to load via the LoadContext. But loading them is blocked by design, since they're in the TPA.

These two design decisions seem incompatible. We want to track our assemblies via our load context, we also want to track the default assemblies from .NET Core; it does not seem that there is a solution to this.

@daxian-dbw, can you weigh in on the problem here?

Edit: I have to admit I am pretty new to this whole domain; there may be an obvious solution we're missing.

@andschwa

This comment has been minimized.

Show comment
Hide comment
@andschwa

andschwa Apr 15, 2016

Member

If we did what @davidfowl suggests here and make the TPA list unspecial, we could then get happily by with our current design, and load the app's assemblies through our custom ALC, even though they're in the TPA. Is this a solution?

Member

andschwa commented Apr 15, 2016

If we did what @davidfowl suggests here and make the TPA list unspecial, we could then get happily by with our current design, and load the app's assemblies through our custom ALC, even though they're in the TPA. Is this a solution?

@gkhanna79

This comment has been minimized.

Show comment
Hide comment
@gkhanna79

gkhanna79 Apr 15, 2016

Member

The local assemblies include the assemblies that we would otherwise need to load via the LoadContext.

Is this unique to your scenario? Or, do you expect everyone to implement a load context to resolve the local assemblies?

Member

gkhanna79 commented Apr 15, 2016

The local assemblies include the assemblies that we would otherwise need to load via the LoadContext.

Is this unique to your scenario? Or, do you expect everyone to implement a load context to resolve the local assemblies?

@andschwa

This comment has been minimized.

Show comment
Hide comment
@andschwa

andschwa Apr 15, 2016

Member

This doesn't seem unique to our scenario; it is the scenario presented by .NET CLI in dotnet publish. A flat list of all dependencies, including your projects'.

@gkhanna79 Your comment after that in the referenced issue about TPA:

It is a simpler model, and invariant, that any assembly that needs to be loaded from path/ni should not be in the app-base (since that set is semantically loaded in default context).

How is this model intended to work with .NET CLI's implemented publishing scheme?

Member

andschwa commented Apr 15, 2016

This doesn't seem unique to our scenario; it is the scenario presented by .NET CLI in dotnet publish. A flat list of all dependencies, including your projects'.

@gkhanna79 Your comment after that in the referenced issue about TPA:

It is a simpler model, and invariant, that any assembly that needs to be loaded from path/ni should not be in the app-base (since that set is semantically loaded in default context).

How is this model intended to work with .NET CLI's implemented publishing scheme?

@gkhanna79

This comment has been minimized.

Show comment
Hide comment
@gkhanna79

gkhanna79 Apr 15, 2016

Member

This doesn't seem unique to our scenario;

I guess I am missing something since expecting every .NET Core app to implement a load context to resolve their applocal assemblies does not appear to be the default experience. Can you please elaborate on why that is the case?

How is this model intended to work with .NET CLI's implemented publishing scheme?

CLI's publishing model works on the basis of computing package graphs, captured in project.lock.json, and does not depend upon Load Context. It works even today - Why do you think it requires load context (which is an execution time artifact to support loading assemblies in isolation)?

Member

gkhanna79 commented Apr 15, 2016

This doesn't seem unique to our scenario;

I guess I am missing something since expecting every .NET Core app to implement a load context to resolve their applocal assemblies does not appear to be the default experience. Can you please elaborate on why that is the case?

How is this model intended to work with .NET CLI's implemented publishing scheme?

CLI's publishing model works on the basis of computing package graphs, captured in project.lock.json, and does not depend upon Load Context. It works even today - Why do you think it requires load context (which is an execution time artifact to support loading assemblies in isolation)?

@andschwa

This comment has been minimized.

Show comment
Hide comment
@andschwa

andschwa Apr 15, 2016

Member

CLI's publishing model works on the basis of computing package graphs, captured in project.lock.json, and does not depend upon Load Context. It works even today - Why do you think it requires load context (which is an execution time artifact to support loading assemblies in isolation)?

Sorry, I miscommunicated. I mean that CLI's published output, that is, the artifacts that comprise your app, places all the dependent assemblies (including your own projects' libraries) in one flat list, and that the provided corehost then places all of these in the TPA, which breaks the ability to use a custom AssemblyLoadContext to load them instead. From what I can tell, loading the assemblies through the custom context is the only provided way to obtain a list of assemblies. So this is incompatible.

I guess I am missing something since expecting every .NET Core app to implement a load context to resolve their applocal assemblies does not appear to be the default experience. Can you please elaborate on why that is the case?

Then I need @daxian-dbw to explain this better. I do not think every .NET Core app will need to load their app local assemblies through a custom load context; but I think some apps have the requirement of doing so, if they want to be able get a list of those assemblies, since there is no GetAssemblies.

Additionally, besides the project's assemblies, how can we get a list of all the .NET runtime assemblies (System.Console etc.)? Our current work around of the lack of GetAssemblies is to have a precompiled hard-coded dictionary of these assemblies (@daxian-dbw, please correct me if I'm wrong here).

Member

andschwa commented Apr 15, 2016

CLI's publishing model works on the basis of computing package graphs, captured in project.lock.json, and does not depend upon Load Context. It works even today - Why do you think it requires load context (which is an execution time artifact to support loading assemblies in isolation)?

Sorry, I miscommunicated. I mean that CLI's published output, that is, the artifacts that comprise your app, places all the dependent assemblies (including your own projects' libraries) in one flat list, and that the provided corehost then places all of these in the TPA, which breaks the ability to use a custom AssemblyLoadContext to load them instead. From what I can tell, loading the assemblies through the custom context is the only provided way to obtain a list of assemblies. So this is incompatible.

I guess I am missing something since expecting every .NET Core app to implement a load context to resolve their applocal assemblies does not appear to be the default experience. Can you please elaborate on why that is the case?

Then I need @daxian-dbw to explain this better. I do not think every .NET Core app will need to load their app local assemblies through a custom load context; but I think some apps have the requirement of doing so, if they want to be able get a list of those assemblies, since there is no GetAssemblies.

Additionally, besides the project's assemblies, how can we get a list of all the .NET runtime assemblies (System.Console etc.)? Our current work around of the lack of GetAssemblies is to have a precompiled hard-coded dictionary of these assemblies (@daxian-dbw, please correct me if I'm wrong here).

@gkhanna79

This comment has been minimized.

Show comment
Hide comment
@gkhanna79

gkhanna79 Apr 15, 2016

Member

which breaks the ability to use a custom AssemblyLoadContext to load them instead.

Expecting every .NET Core app to resolve its local assemblies, whether by using a custom load context or wiring up the Resolving event of Default context, does not seem the right step ahead to address the issue.

A more appropriate way, to address the issue at hand, would be to consider getting the list of assemblies for a given load context, and not the AppDomain. This would, however, not return the list of assemblies that were loaded in load context A but returned as a reference to load context B, when enumerating assemblies loaded in B. As you can imagine, this requires the users to understand how load context really works.

loading the assemblies through the custom context is the only provided way to obtain a list of assemblies

For the list of local assemblies, until there is a formal solution for this, can you not enumerate the AppLocal folder? Or, do you need more than just the list?

but I think some apps have the requirement of doing so, if they want to be able get a list of those assemblies, since there is no GetAssemblies.

If these assemblies are in a subfolder, then they can be loaded via a custom load context. That said, in your scenario, are the assemblies you wish to load (and present locally) also present in the app's app.deps.json?

Member

gkhanna79 commented Apr 15, 2016

which breaks the ability to use a custom AssemblyLoadContext to load them instead.

Expecting every .NET Core app to resolve its local assemblies, whether by using a custom load context or wiring up the Resolving event of Default context, does not seem the right step ahead to address the issue.

A more appropriate way, to address the issue at hand, would be to consider getting the list of assemblies for a given load context, and not the AppDomain. This would, however, not return the list of assemblies that were loaded in load context A but returned as a reference to load context B, when enumerating assemblies loaded in B. As you can imagine, this requires the users to understand how load context really works.

loading the assemblies through the custom context is the only provided way to obtain a list of assemblies

For the list of local assemblies, until there is a formal solution for this, can you not enumerate the AppLocal folder? Or, do you need more than just the list?

but I think some apps have the requirement of doing so, if they want to be able get a list of those assemblies, since there is no GetAssemblies.

If these assemblies are in a subfolder, then they can be loaded via a custom load context. That said, in your scenario, are the assemblies you wish to load (and present locally) also present in the app's app.deps.json?

@andschwa

This comment has been minimized.

Show comment
Hide comment
@andschwa

andschwa Apr 15, 2016

Member

For the list of local assemblies, until there is a formal solution for this, can you not enumerate the AppLocal folder? Or, do you need more than just the list?

I believe we need more than the list, but I really need @daxian-dbw to explain further.

If these assemblies are in a subfolder, then they can be loaded via a custom load context.

dotnet publish does not produce a subfolder for them; AFAICT .NET CLI intends for there to be a flat list of all the assemblies the project needs.

That said, in your scenario, are the assemblies you wish to load (and present locally) also present in the app's app.deps.json?

Yes, the assemblies are in the app.deps.json file; however, I have no real control over this, as .NET CLI produces it automatically.

Member

andschwa commented Apr 15, 2016

For the list of local assemblies, until there is a formal solution for this, can you not enumerate the AppLocal folder? Or, do you need more than just the list?

I believe we need more than the list, but I really need @daxian-dbw to explain further.

If these assemblies are in a subfolder, then they can be loaded via a custom load context.

dotnet publish does not produce a subfolder for them; AFAICT .NET CLI intends for there to be a flat list of all the assemblies the project needs.

That said, in your scenario, are the assemblies you wish to load (and present locally) also present in the app's app.deps.json?

Yes, the assemblies are in the app.deps.json file; however, I have no real control over this, as .NET CLI produces it automatically.

@MarinAtanasov

This comment has been minimized.

Show comment
Hide comment
@MarinAtanasov

MarinAtanasov May 12, 2016

Any update on Assembly.GetReferencedAssemblies ?
This is something that I really need.

MarinAtanasov commented May 12, 2016

Any update on Assembly.GetReferencedAssemblies ?
This is something that I really need.

@weshaggard

This comment has been minimized.

Show comment
Hide comment
Member

weshaggard commented May 12, 2016

@niemyjski

This comment has been minimized.

Show comment
Hide comment
@niemyjski

niemyjski commented May 25, 2016

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment