Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建DirectoryEntry的实例以在测试中使用_C#_Reflection_Active Directory - Fatal编程技术网

C# 创建DirectoryEntry的实例以在测试中使用

C# 创建DirectoryEntry的实例以在测试中使用,c#,reflection,active-directory,C#,Reflection,Active Directory,我正在尝试创建DirectoryEntry的实例,以便可以使用它测试将传递给DirectoryEntry的一些代码。然而,尽管做了很多尝试,我还是找不到实例化DE并初始化其PropertyCollection的方法 我有下面的代码,它是从做相同的过程,但对SearchResult对象进行修改的。Add方法似乎已被完全禁用,我找不到方法调用PropertyCollection上的构造函数来传递某些属性 using System.Collections; using System.Directory

我正在尝试创建DirectoryEntry的实例,以便可以使用它测试将传递给DirectoryEntry的一些代码。然而,尽管做了很多尝试,我还是找不到实例化DE并初始化其PropertyCollection的方法

我有下面的代码,它是从做相同的过程,但对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本身,但我非常喜欢测试适配器模式。您必须做这样的事情,这是一件令人烦恼的事情,但是代码本身很琐碎,可以将类放在项目文件夹中,以将它们隐藏在主项目之外

例如,我有一个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; } }
}

我本想把这个东西包起来,但希望能有另一个答案。我想我现在可能会放弃并包装它,而不是等待一个完美的解决方案——但如果有一种方法可以正确地做到这一点,那将是一件有趣的事情。@Adam——当涉及到没有实现接口的库代码时,我不认为适配器有任何问题。我经常使用这种模式。亚当,你真的用工作属性实现了吗?我也有同样的问题。
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; } }
}