all groups > dotnet clr > july 2007 >
You're in the

dotnet clr

group:

Programatically disabling lazy loading of assemblies


Programatically disabling lazy loading of assemblies Edgile
7/6/2007 7:32:12 AM
dotnet clr:
Hi,

I would like to enforce loading all referenced assemblies at start up in
order to investigate them via Reflection. However, those referenced
assemblies are loaded by the framework only on demand. Here is a little
example:

namespace TestApp
{
class Program
{
static void Main(string[] args)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Console.WriteLine(assemblies.Length);
object o = Activator.CreateInstance("ClassLibrary1",
"ClassLibrary1.Class1");
assemblies = AppDomain.CurrentDomain.GetAssemblies();
Console.WriteLine(assemblies.Length);
}
}
}

The ClassLibrary1 is a precompiled assembly that is referenced by this
executable.

Before invoking Activator.CreateInstance, ClassLibrary1 is not loaded, it
can be clearly seen from the assemblies.Length property.

Is there a way that I can force the CLR to load all referenced assemblies
somehow?
Re: Programatically disabling lazy loading of assemblies Edgile
7/6/2007 2:20:01 PM
Hello Marc,

This was quite a fast response. Thanx! However, it seems to me that it does
not work. Here is the code:

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Assembly assembly = Assembly.GetEntryAssembly();
AssemblyName[] refs = assembly.GetReferencedAssemblies();
Console.WriteLine(refs.Length);
}
}
}

This application references some .NET libraries (by default System.Xml,
System.Data) including my own ClassLibrary1.dll. However, the resulted
AssemblyName array contains one single element: mscorlib
Is this a bug in the framework or do I do something wrong?

Re: Programatically disabling lazy loading of assemblies Marc Gravell
7/6/2007 3:51:56 PM
Just walk them... watch out for the cyclic reference at the bottom ;-p

static void Main() {
List<string> considered = new List<string>();
EnumerateAssemblies(Assembly.GetEntryAssembly(), considered);
}

static void EnumerateAssemblies(Assembly assembly, List<string>
considered) {
foreach (AssemblyName name in
assembly.GetReferencedAssemblies()) {
try {
string sName = name.FullName;
if (considered.Contains(sName)) continue;
considered.Add(sName);
Assembly refAssembly = Assembly.Load(name);
if (refAssembly != null) {
EnumerateAssemblies(refAssembly, considered);
}
} catch {} // lazy swallow... best endeavors
}
}

Marc

Re: Programatically disabling lazy loading of assemblies Marc Gravell
7/7/2007 2:30:27 PM
[quoted text, click to view]

Interesting; I've just done a test, and it looks like the compiler
removes the references that aren't actually used by your code - i.e.
commenting out blocks of code can reduce the
assembly.GetReferencedAssembles() count... As such, I imagine that
adding some more code might make it start working. I am, however,
confused as to why you didn't see "System"... using copy/paste on your
code (in 2.0) gives me both System and mscorlib....

Marc
Re: Programatically disabling lazy loading of assemblies Edgile
7/8/2007 12:04:00 AM
Just to increase confusion:

static void Main(string[] args)
{
Assembly assembly = Assembly.GetEntryAssembly();
AssemblyName[] refs = assembly.GetReferencedAssemblies();
Console.WriteLine(refs.Length);
Type t = Type.GetType("ClassLibrary1.Class1, ClassLibrary1");
object o = Activator.CreateInstance(t);
refs = assembly.GetReferencedAssemblies();
Console.WriteLine(refs.Length);
}

The type and the instance retrieved perfectly, while ClassLibrary1 still not
visible among referenced assemblies. It is not "dynamically referenced", it
just behaves odd hiding ClassLibrary1.

Is there any other suggestion, how to preload assemblies? My current
"solution" is browsing the files of the execution folder. It works fine as
long as I have read permission on the disk (as I have no interest in the
GAC), but on a web server having disk read permission is not an guarantee.



[quoted text, click to view]
Re: Programatically disabling lazy loading of assemblies Edgile
7/8/2007 12:16:01 AM
[quoted text, click to view]

I believe the same reason you wrote above. They were not in use. I have no
clue why you have seen them (both 2.0), I have repeated the test on two
separate machines. They were consistent, only mscorlib was visible.
However, my personal interest is in my plugin system. I want to browse the
plugins via my plugin handler, both are referenced by a neutral host app. As
binding is prescribed in config files loaded during runtime, it has a fair
chance that types from the plugins will be used completely dynamically
Re: Programatically disabling lazy loading of assemblies Marc Gravell
7/8/2007 12:38:15 AM
[quoted text, click to view]

Inside the web-apps own scope, I would imagine that you'd have read
(but not write) access, otherwise the system is going to struggle;
especially if you just drop them in the "bin" folder. But you could
designate a "plugin" directory to which access is granted?

AddThis Social Bookmark Button