views:

87

answers:

1

Hi, I need some help trying to come up with a way to set this line of code using reflection:

this.extensionCache.properties[attribute]
                          = new ExtensionCacheValue((object[]) value);

this.extensionCache is a internal private Field in the base class im inheriting from.

I can get at the extensionCache field with the following code:

FieldInfo field = typeof(Principal).GetField("extensionCache",BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

But I can't figure out how to call the properties method with a index then set it to a instance of a class that I have no visibility over.

extensionCache is of the following type:

internal class ExtensionCache
{
    private Dictionary<string, ExtensionCacheValue> cache
                   = new Dictionary<string, ExtensionCacheValue>();

    internal ExtensionCache()
    {
    }

    internal bool TryGetValue(string attr, out ExtensionCacheValue o)
    {
        return this.cache.TryGetValue(attr, out o);
    }

    // Properties
    internal Dictionary<string, ExtensionCacheValue> properties
    {
        get
        {
            return this.cache;
        }
    }
}

Here is the Value Class

internal ExtensionCacheValue(object[] value)
{
    this.value = value;
    this.filterOnly = false;
}

If some backgroud helps im trying to extend System.DirectoryServices.AccountManagement.Principal which is where all these methods live.

See Method: ExtensionSet

Thanks for your help.

+2  A: 

First off; reflection to this level is usually a code smell; take care...

Take it one step at a time; first, we need to get the ExtensionCache:

FieldInfo field = typeof(Principal).GetField("extensionCache",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
object extCache = field.GetValue(obj);

Then we need the properties:

field = extCache.GetType().GetField("properties",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
IDictionary dict = (IDictionary) field.GetValue(extCache);

you can now use the indexer on dict, with the new value:

dict[attribute] = ...

The next problem is how to create an ExtensionCacheValue; I assume you don't have access to this type (as internal)...

Type type = extCache.GetType().Assembly.GetType(
      "Some.Namespace.ExtensionCacheValue");
object[] args = {value}; // needed to double-wrap the array
object newVal = Activator.CreateInstance(type, args);
...
dict[attribute] = newVal;

Any of that help?

Marc Gravell