5

I'd like to automagically execute some code before certain class constructor gets executed (to load some externall assmebly that class requires), all in C#, .NET 2.0

EDIT:

public class MyClass 
{
    ThisTypeFromExternalAssembly variable;
}

And what I really need is to have assembly loader that is 'attached' somehow to MyClass, to load externall assembly when it is needed. This must happen before constructor, but I would not like to need to call some Init() before constructing MyClass() object

Nick
  • 25,026
  • 7
  • 51
  • 83
  • 1
    Can't you do that (load ext libraries) directly in the class constructor? – Maxim Gueivandov Mar 01 '11 at 13:14
  • I can't: class can not be constructed without externall assembly, And I would not like to do adtional init before using this class. – Adam Kłobukowski Mar 01 '11 at 14:02
  • 2
    The AssemblyResolve event already does this. You just need to make sure that you subscribe to the event *before* the JIT compiler needs the type. In other words, you cannot refer to *any* of the assembly's types in your startup method. If subscribing the event is the "Init" method you want to avoid then, no, you cannot do without that. These are otherwise rather silly gyrations just to avoid copying two files instead of one. – Hans Passant Mar 01 '11 at 14:33

4 Answers4

6

You can use the static initialiser for the class:

static ClassName( )
{

}

This will be called before any instances of ClassName are constructed.

Given the update you would do:

public class MyClass
{
    ThisTypeFromExternalAssembly variable;

    static MyClass( )
    {
        InitialiseExternalLibrary( );
    }

    public MyClass( )
    {
         variable = new ThisTypeFromExternalAssembly( );
    }
}
Nick
  • 25,026
  • 7
  • 51
  • 83
  • @Nick as far as know static contructor is called once ( when type system needs to create first time from this object and which is unpredictable). so if you need to execute some code after every instantination this probably wont work. – adt Mar 01 '11 at 13:45
  • @adt, I guess the O.P.'s question is a bit ambiguous. Does he want the code to be called every time before a constructor gets called? Or just the first time before any instances of the class are constructed? – Nick Mar 01 '11 at 13:46
  • Tried that, didn't work. I have exception becouse of unreolved class dependency. – Adam Kłobukowski Mar 01 '11 at 13:47
  • Hey Adam, could you post your updated code and where the exception is getting thrown? – Nick Mar 01 '11 at 13:48
  • And Adam you want to interfere everytime class instantinated or just once? – adt Mar 01 '11 at 13:50
  • This is a singleton class and is created only once. – Adam Kłobukowski Mar 01 '11 at 14:04
  • Example code is really simple: `code` public class MyClass { ThisTypeFromExternalAssembly variable; } `code` And wha I really need is to have assembly loader that is 'attached' somehow to MyClass, to load externall assembly when it is needed. This must happen before constructor, but I would not like to need to call some Init() before constructing MyClass() object. – Adam Kłobukowski Mar 01 '11 at 14:04
  • Well, go ahead and post it then! – Nick Mar 01 '11 at 14:07
  • Sorry, I'm new on StackOverflow and sometimes press enter to fast. – Adam Kłobukowski Mar 01 '11 at 14:09
4

Could you use a static constructor for this?

class SimpleClass
{
    // Static constructor
    static SimpleClass()
    {
        //...
    }
}

From the MSDN article:

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.

Dave
  • 6,905
  • 2
  • 32
  • 35
  • @Alex: That's just how I roll :P – Dave Mar 01 '11 at 13:16
  • 1
    OP already mentionned a "class constructor"... Class constructor, AFAIK, is a synonym of "static constructor", as opposed to "instance constructor". The question, as I see it, is why he can't use it directly. – Maxim Gueivandov Mar 01 '11 at 13:23
3

If it's to load an assembly, that sounds like you just want to do it once, in which case a static constructor may be appropriate:

public class Foo
{
    static Foo()
    {
        // Load assembly here
    }
}

Note that if this fails (throws an exception), the type will be unusable in that AppDomain.

Is there any reason why you're not just using normal type resolution to load the assembly though? Wouldn't the assembly be loaded automatically when you need to use part of it? Could you give more details about the problem you're trying to solve?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I want to include dll in exe using following method http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx Baseline is this: I have a framework that depends on the 'session' object (you use the whole framework by this object), but this object alreade depends on code in dll i want to include. I'd prefer not to add any special init for the framework, thats why I'd like to execute code before the session object is constructed. – Adam Kłobukowski Mar 01 '11 at 13:50
0

you might want to use an aop framework like postsharp, which allows to interfere function call by using attributes .

http://www.sharpcrafters.com/solutions/monitoring#tracing

Postsharp: how does it work?

http://www.codeproject.com/KB/cs/ps-custom-attributes-1.aspx

Community
  • 1
  • 1
adt
  • 4,320
  • 5
  • 35
  • 54