Как установить значение свойства через имя тега атрибута с помощью отражения?

Я хочу записать допускающую повторное использование библиотеку для запросов против AD с LDAP. Я использую и COM-объекты ActiveDs и Систему. DirectoryServices.

Значительно вдохновленный Bart Де-Смет LINQ к AD, я записал SchemaAttribute и DirectoryAttributeAttribute классы для использования с DirectorySource (T) класса (Да, это - VBNET, но любой код C# поможет, поскольку я бегло говорю на обоих языках).

Теперь, при запросах против AD с помощью LDAP (Система. DirectoryServices), можно выбрать, какое свойство/атрибут Вы хотите быть загруженными классом DirectorySearcher. Затем я записал мне метод, который берет ParramArray Строки как ее параметр, так, чтобы я добавил свойства LDAP к DirectorySearcher. PropertiesToLoad () метод в foreach () оператор. Вот часть кода для прояснения (Предполагающий, что ldapProps параметр будет всегда содержать значение (значения)):

Public Function GetUsers(ByVal ParamArray ldapProps() As String) As IList(Of IUser)
    Dim users As IList(Of IUser) = New List(Of IUser)
    Dim user As IUser
    Dim de As DirectoryEntry = New DirectoryEntry(Environment.UserDomainName)
    Dim ds As DirectorySearcher = New DirectorySearcher(de, "(objectClass=user)")

    For Each p As String In ldapProps
        ds.PropertiesToLoad(p)
    Next

    Try
        Dim src As SearchResultCollection = ds.FindAll()
        For Each sr As SearchResult In src
            user = New User()
            // This is where I'm stuck... Depending on the ldapProps required, I will fill only these in my User object.
        Next
End Function

Вот часть моего Пользовательского класса:

Friend NotInheritable Class User
    Implements IUser

    Private _accountName As String
    Private _firstName As String

     _
    Public Property AccountName As String
        Get
            Return _accountName
        End Get
        Set (ByVal value As String)
            If (String.Equals(_accountName, value)) Then Return

            _accountName = value
        End Set
    End Property

     _
    Public Property FirstName As String
        Get
            Return _firstName
        End Get
        Set (ByVal value As String)
            If (String.Equals(_firstName, value)) Then Return

            _firstName = value
        End Set
    End Property
End Class

Теперь, я хотел бы к преимуществу тех атрибутов, которые я поместил сверх своих Пользовательских свойств класса. Я знаю, как получить эти атрибуты, и я знаю, как получить мои свойства. То, что я не уверен, - то, как удостовериться, что правильное свойство будет установлено правильное значение от класса SearchResult до моего Пользовательского класса.

ОТРЕДАКТИРУЙТЕ, Поскольку время играет против меня, я не могу дождаться, чтобы знакомиться с понятием DirectorySource (T), поскольку это требует, чтобы немного больше кодирования для меня записало для получения его работа. Как обходное решение, я пишу класс UserFactory, который назовут через мой ActiveDirectoryFacade.

ОТРЕДАКТИРУЙТЕ Это ТАК, вопрос, кажется, очень близко к тому, что я хочу выполнить:
Отражение, атрибуты и выбор свойства

ОТРЕДАКТИРУЙТЕ Это похоже на то, что я хочу: значения свойств установки C# посредством отражения с атрибутами
Кто-либо имеет другую идею или может подтвердить, что это правильно?

Я также упомяну, что застреваю в Платформе.NET 2.0 и VBNET2005. Иначе я привык бы LINQ Де-Смета Bart для библиотеки AD.

Спасибо за любую справку.

6
задан Community 23 May 2017 в 10:33
поделиться

1 ответ

Я не знаком с DirectoryServices, но если я правильно понял ваш вопрос, вы можете использовать отражения для установки свойств вашего объекта User. Для установки корректных свойств необходимо сопоставить имена свойств с данными, сохраненными в атрибутах свойств объекта Пользователя.

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public class DirectoryAttributeAttribute : Attribute
    {
        public DirectoryAttributeAttribute(string propertyName)
        {
            PropertyName = propertyName;
        }

        public string PropertyName
        {
            get; set;
        }
    }

    public class User
    {
        [DirectoryAttributeAttribute("SAMAccountName")]
        public string AccountName
        {
            get; set;
        }

        [DirectoryAttributeAttribute("givenName")]
        public string FirstName
        {
            get; set;
        }
    }

    // Finds property info by name.
    public static PropertyInfo FindProperty(this Type type, string propertyName)
    {
        foreach (PropertyInfo propertyInfo in type.GetProperties())
        {
            object[] attributes = propertyInfo.GetCustomAttributes(typeof(DirectoryAttributeAttribute, false));

            foreach (DirectoryAttributeAttribute attribute in attributes)
            {
                if (attribute.PropertyName == propertyName)
                {
                    return propertyInfo;
                }
            }
        }

        return null;
    }

    SearchResult searchResult = ...;

    if (searchResult != null)
    {
        User user = new User();

        Type userType = typeof (User);

        foreach (string propertyName in searchResult.Properties.PropertyNames)
        {
            // Find property using reflections.
            PropertyInfo propertyInfo = userType.FindProperty(propertyName);

            if (propertyInfo != null) // User object have property with DirectoryAttributeAttribute and matching name assigned.
            {
                // Set value using reflections.
                propertyInfo.SetValue(user, searchResult.Properties[propertyName]);
            }
        }
    }

Если имена свойств, которые вы собираетесь заполнять, могут измениться, вы можете сохранить сопоставление свойств в словаре.

3
ответ дан 17 December 2019 в 18:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: