Создание экземпляра DirectoryEntry для использования в тесте

Я пытаюсь создать экземпляр DirectoryEntry, чтобы использовать его для тестирования некоторого кода, которому будет передано DirectoryEntry. Однако, несмотря на множество попыток, я не могу найти способ создать экземпляр DE и инициализировать его PropertyCollection.

У меня есть следующий код, который был взят и изменен из другого ответа на SO , который делал тот же процесс, но для объекта SearchResult. Кажется, что метод Add был полностью отключен, и я не могу найти способ вызвать конструктор в PropertyCollection для передачи некоторых свойств.

using System.Collections;
using System.DirectoryServices;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;

public static class DirectoryEntryFactory
{
    const BindingFlags nonPublicInstance = BindingFlags.NonPublic | BindingFlags.Instance;
    const BindingFlags publicInstance = BindingFlags.Public | BindingFlags.Instance;

    public static DirectoryEntry Construct(T anonInstance)
    {
        var e = GetUninitializedObject();

        SetPropertiesField(e);

        var dictionary = (IDictionary)e.Properties;
        var type = typeof(T);
        var propertyInfos = type.GetProperties(publicInstance);

        foreach (var propertyInfo in propertyInfos)
        {
            var value = propertyInfo.GetValue(anonInstance, null);
            var valueCollection = GetUninitializedObject();
            var innerList = GetInnerList(valueCollection);
            innerList.Add(value);

            var lowerKey = propertyInfo.Name.ToLower(CultureInfo.InvariantCulture);

            // These both throw exceptions saying you can't add to a PropertyCollection
            //(typeof(PropertyCollection)).InvokeMember("System.Collections.IDictionary.Add", nonPublicInstance | BindingFlags.InvokeMethod, null, dictionary, new object[] { propertyInfo.Name, value });
            //dictionary.Add(lowerKey, propertyCollection);
        }

        return e;
    }

    private static ArrayList GetInnerList(object propertyCollection)
    {
        var propertyInfo = typeof(PropertyValueCollection).GetProperty("InnerList", nonPublicInstance);
        return (ArrayList)propertyInfo.GetValue(propertyCollection, null);
    }

    private static void SetPropertiesField(DirectoryEntry e)
    {
        var propertiesField = typeof(DirectoryEntry).GetField("propertyCollection", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        propertiesField.SetValue(e, GetUninitializedObject());
    }

    private static T GetUninitializedObject()
    {
        return (T)FormatterServices.GetUninitializedObject(typeof(T));
    }
}

предполагается использовать

DirectoryEntry e = DirectoryEntryFactory.Construct(new { attr1 = "Hello", attr2 = "World"});

Я надеюсь, что я что-то пропустил поскольку я новичок в использовании отражения в гневе.

5
задан Community 23 May 2017 в 12:30
поделиться