How to set property value through attribute tag name using reflection?

I want to write a reusable library for querying AD using LDAP. I use both ActiveDs COM objects and System.DirectoryServices.

Heavily inspired by Bart de Smet LINQ to AD, I wrote the SchemaAttribute and DirectoryAttributeAttribute classes for use with the DirectorySource (Of T) class (yes, this is VBNET, but any C # code will help, as I am fluent in both languages).

Now when you query AD using LDAP (System.DirectoryServices), you can choose which property / attribute you want to load with the DirectorySearcher class. Then I wrote myself a method that takes the ParramArray of String parameter as its parameter, so I add the LDAP properties to the DirectorySearcher.PropertiesToLoad () method in the foreach () statement. Here's a snippet of code to make it clear (Assuming the ldapProps parameter will always contain the value (s)):

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

Here is part of my User class:

Friend NotInheritable Class User
    Implements IUser

    Private _accountName As String
    Private _firstName As String

    <DirectoryAttributeAttribute("SAMAccountName")> _
    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

    <DirectoryAttributeAttribute("givenName")> _
    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

Now I would like to use the attributes that I put on top of my properties in the User class. I know how to get these attributes, and I know how to get my properties. I am not sure how to make sure that the correct value will be set to the correct value from the SearchResult class for my User class.

EDIT. , DirectorySource (Of T), , , UserFactory, ActiveDirectoryFacade.

SO, , , :
,

, : #,
- , ?

, .NET Framework 2.0 VBNET2005. Bart de Smet LINQ to AD.

.

+5
1

DirectoryServices, , User. , , 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]);
            }
        }
    }

, , , .

+2

All Articles