我正在嘗試創建一個DirectoryEntry實例,以便我可以使用它來測試一些將通過DirectoryEntry的代碼。但是,儘管嘗試了很多,但我找不到實例化DE並初始化它的PropertyCollection的方法。創建一個用於測試的DirectoryEntry實例
我有以下代碼,它是從another answer on 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>(T anonInstance)
{
var e = GetUninitializedObject<DirectoryEntry>();
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<PropertyValueCollection>();
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<PropertyCollection>());
}
private static T GetUninitializedObject<T>()
{
return (T)FormatterServices.GetUninitializedObject(typeof(T));
}
}
使用旨在
DirectoryEntry e = DirectoryEntryFactory.Construct(new { attr1 = "Hello", attr2 = "World"});
我希望我已經錯過了一些東西,因爲我是很新,在憤怒中使用反射。
亞當,你實際上管理與作業性的實施來實現這一點?我有同樣的問題[這裏](http://stackoverflow.com/questions/18056483/mocking-the-properties-property-of-directoryentry)。 – 2013-08-05 12:01:48