Сложный сценарий отражения - PullRequest
1 голос
/ 28 июня 2009

Мне нужна помощь, чтобы найти способ установить эту строку кода с помощью отражения:

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

this.extensionCache - это внутреннее частное поле в базовом классе, которое я наследую от.

Я могу получить в поле extensionCache следующий код:

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

Но я не могу понять, как вызвать метод свойств с индексом, а затем установить для него экземпляр класса, над которым у меня нет видимости.

extensionCache имеет следующий тип:

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;
        }
    }
}

Вот класс значений

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

Если какой-то backgroud помогает мне пытаться расширить System.DirectoryServices.AccountManagement.Principal, где находятся все эти методы.

См. Метод: ExtensionSet

Спасибо за вашу помощь.

1 Ответ

3 голосов
/ 28 июня 2009

Первый раз; отражение до этого уровня обычно является запахом кода; береги себя ...

Сделай это по одному шагу за раз; во-первых, нам нужно получить ExtensionCache:

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

Тогда нам нужно properties:

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

теперь вы можете использовать индексатор на dict с новым значением:

dict[attribute] = ...

Следующая проблема - как создать ExtensionCacheValue; Я предполагаю, что у вас нет доступа к этому типу (как внутренний) ...

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;

Что-нибудь из этой помощи?

...