Friday, April 13, 2007

Calling static class A's static methods from a singleton class C where C does not reference A?

Whoa.. I ran across this little scenario the other day.

In the application I'm currently working on we have a static class with static methods that are used for some logging purposes throughout the rest of the app. (The static methods link to a back-end singleton class). This logging class lives within our objects. We also have a bunch of interfaces for these objects that are passed around in the rest of the app. Our objects hold a reference to the interfaces but the interfaces do not hold a ref to our objects. We have another Singleton class in a plugins project that only gets passed interfaces (the plugins also hold a ref to the interfaces, but not the objects). We needed to be able to do some logging (preferably using the already implemented object) from this singleton but ran into this fun little scenario.

So basically (If you didn't want to read the above paragraph)

Class A(singleton) has a reference to Class B(interfaces)

Class C(objects) has a reference to B

A does not ref C and C does not ref A

How does A call a static class' static methods of C?

Well, here goes.. Our singleton (class A) gets started up and no one ever calls methods against it.. It just runs and periodically does some checking. We need to log though using class B..

When we do our startup and begin the singleton of A we pass in the methods needed from C. We added an Init method that is called at startup that takes local delegate types with matching signatures of class C's methods. Then we keep local copies of these an can call them whenever we need to, thus calling into class C's methods that we don't really have access to...

Some sample code:

public static class C {
public static LogA(string s) {}
public static LogB(string s, int i) {}
...
}
public class A {
//Some singleton stuff here//
public delegate void LogADelegate(string s);
public delegate void LogBDelegate(string s, int i);

LogADelegate _logA;
LogBDelegate _logB;

public void Init(LogADelegate a, LogBDelegate b) {
_logA = a;
_logB = b;
//more init code//
}
}
//Code from a startup class
A.Init(C.LogA, C.LogB);

The neat thing is that your passing a static method and storing it and using it as though it where an instance method.
One other quick neat thing is if you have multiple overrides of LogA

public static LogA(string s) {}
public static LogA(string a, string b) {}
public static LogA(string s, int i) {}

The compiler automatically infers which one to pass when calling the Init() function based on the delegate's signature.


I thought it was pretty neat anyways ;)

No comments: