So i was trying to create an instance of a page class that inherits from some vendor code and has a bunch of dependencies in the constructor. Normally i would apply the pattern out of Michael Feather's book called Parameterize Constructor (basically add the dependency as a parameter and then mock it).
However, this was vendor code so i have no choice really and i really wasn't feeling interested in making a whole new chain of inheritance and implementation of interfaces just to seperate the dependencies so i started digging...
anyhow, the gist of it all was that i had a private static member that i wanted to put a value into, but it's on a sealed class and it's private and static so i can't override it and i can't inherit from it.
After reading a little more up on reflection (and examining HttpRuntime in the reflector to figure out the member names) i eventually got something like this put together:
[SetUp]
public void Setup()
{
HttpRuntime theRuntimeInstance = GetTheRuntimeInstance();
SetHttpRuntimePath(theRuntimeInstance, @"c:\dev\ProjectFolder\");
}
private static HttpRuntime GetTheRuntimeInstance()
{
Type HttpRuntimeType = typeof (HttpRuntime);
BindingFlags bindFlags = BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Static;
return HttpRuntimeType.InvokeMember(
"_theRuntime", bindFlags,
null, null, null
) as HttpRuntime;
}
private static void SetHttpRuntimePath(HttpRuntime theRuntimeInstance, string absolutePath)
{
Type HttpRuntimeType = typeof (HttpRuntime);
BindingFlags bindFlags = BindingFlags.NonPublic | BindingFlags.SetField | BindingFlags.Instance;
HttpRuntimeType.InvokeMember("_appDomainAppPath", bindFlags
, null, theRuntimeInstance, new object[] {absolutePath});
HttpRuntimeType.InvokeMember("_appDomainAppVPath", bindFlags
, null, theRuntimeInstance, new object[] {absolutePath});
}
basically, the first method retrieves the singleton instance of the HttpRuntime
then the second method goes and inserts private member values into 2 fields the app domain paths.
With a reflective language, it's not always necissary to break dependencies... although mutating private state like this could probably get you into a lot of 'trouble' and it's certainly not clean to look at!