Outshined <so*****@micros oft.com> wrote:
As I mentioned, I am building a class library, contained within its own
assembly. If possible, I want to have my library be independent and not
force people to explicitly initialize it before using classes from it. Ergo
my interest in executing initialization when this class library assembly is
loaded. But in order to handle the AppDomain AssemblyLoad event, I must
first register the handler somehow, using the following line:
AppDomain.Assem blyLoad += new
AssemblyLoadEve ntHandler(MyAss emblyLoadEventH andler);
Can this registration occur inside the class library assembly, or must it be
outside - somewhere in the calling application.
I believe it must be outside.
Is there a single class which is always going to be used before the
registration is needed? If there is, you could put a call in its static
initializer to do the registration.
I wouldn't mind having that sample code! fu******@yahoo. com
Unfortunately the sample won't handle the above. I don't know of
anything which you can put in an assembly to say, "When this assembly
is loaded, call <x>."
Here it is though, for better or worse. Note that in real code you
would of course handle exceptions, use namespaces, etc.
Driver.cs:
using System;
using System.Reflecti on;
using System.Threadin g;
public class Driver
{
static void Main()
{
// Make sure we load the assembly containing the custom
attribute
// first! (Loading another assembly within the
AssemblyLoadEve nt is
// probably not a good idea.)
Type t = typeof(Initiali zeOnLoadAttribu te);
// Now add the handler
Thread.GetDomai n().AssemblyLoa d+=new AssemblyLoadEve ntHandler
(InitializeType sOnLoad);
Assembly.LoadFr om ("library.dll") ;
}
static void InitializeTypes OnLoad(object sender,
AssemblyLoadEve ntArgs args)
{
Assembly loaded = args.LoadedAsse mbly;
foreach (Type type in loaded.GetTypes ())
{
if (type.IsDefined (typeof(Initial izeOnLoadAttrib ute),
false))
{
ConstructorInfo initializer = type.TypeInitia lizer;
if (initializer!=n ull)
initializer.Inv oke(null, null);
}
}
}
}
Common.cs:
using System;
[AttributeUsage( AttributeTarget s.Class)]
public class InitializeOnLoa dAttribute : Attribute
{
}
Library.cs:
public class ClassNeedingReg istration
{
// Note - this must *not* have =false at the end,
// otherwise it will be set to false every time the type
// initializer is run, before the test for it being false.
// We want the default value (false), but only the first time...
static bool initialized;
static ClassNeedingReg istration()
{
if (!initialized)
{
initialized=tru e;
Console.WriteLi ne ("Registerin g class.");
}
}
}
public class ClassNotNeeding Registration
{
static ClassNotNeeding Registration()
{
Console.WriteLi ne (
"This class does not need to be registered.");
}
}
Compiling:
csc /target:library /out:common.dll Common.cs
csc /target:library /out:library.dll /r:common.dll Library.cs
csc /r:common.dll Driver.cs
Running:
Driver.exe produces output of:
Registering class.
(It only prints it once, even if you call the type initializer multiple
times. It could well be that some of your classes won't need the kind
of guard I've put around it to make sure it only effectively gets
executed once, but I thought I'd show you the pattern anyway.)
--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too