创建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"}); 

我希望我错过了一些东西,因为我很擅长在愤怒中使用reflection。

我对DirectoryEntry本身并不熟悉,但我很喜欢Adapter模式进行测试。 你必须做这样的事情是一件烦恼,但是代码本身是微不足道的,并且可以将类放在项目文件夹中以隐藏它们远离主项目。

例如,我有一个FileInfoAdapter和DirectoryInfoAdapter来包装那些触及文件系统的类。

FileInfoAdapter:

 public class FileInfoAdapter : IFileInfo { private readonly FileSystemInfo _fi; public FileInfoAdapter(string fileName) : this(new FileInfo(fileName)) { } public FileInfoAdapter(FileSystemInfo fi) { _fi = fi; } public string Name { get { return _fi.Name; } } public string FullName { get { return _fi.FullName; } } public bool Exists { get { return _fi.Exists; } } }