2010-03-03 3 views
5

LDAP가있는 AD에 대해 쿼리 할 수있는 재사용 가능한 라이브러리를 작성하고 싶습니다. 나는 ActiveDs COM 객체와 System.DirectoryServices를 모두 사용하고있다.리플렉션을 사용하여 속성 태그 이름을 통해 속성 값을 설정하는 방법은 무엇입니까?

Bart de Smet LINQ에 큰 영감을 받아서 SchemaAttribute 클래스와 DirectoryAttributeAttribute 클래스를 작성하여 DirectorySource (Of T) 클래스와 함께 사용했습니다 (예, VBNET이지만 모든 C# 코드는 유창하므로 도움이됩니다.) 두 언어 다).

이제 LDAP (System.DirectoryServices)를 사용하여 AD에 대해 쿼리 할 때 DirectorySearcher 클래스에서로드 할 속성/특성을 선택할 수 있습니다. 그런 다음 String의 ParramArray를 매개 변수로 사용하는 메서드를 직접 작성하여 foreach() 문의 DirectorySearcher.PropertiesToLoad() 메서드에 LDAP 속성을 추가합니다. 여기

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 

내 사용자 클래스의 일부이다 : 다음 코드 조각은 분명히 (ldapProps 매개 변수는 항상 값 (들)을 포함한다고 가정) 할의 지금

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 

를, 내가 좋아하는 것 내 사용자 클래스 속성 위에 놓는 속성의 이점을 누릴 수 있습니다. 이러한 속성을 얻는 방법을 알고 있으며, 내 속성을 얻는 방법을 알고 있습니다. 확실하지 않은 것은 올바른 속성이 SearchResult 클래스에서 사용자 클래스로 올바른 값으로 설정되는지 확인하는 것입니다.

EDIT 시간이 저에게 반해서 DirectorySource (Of T)의 개념을 익히려면 기다릴 수 없습니다. 작동하도록 쓰기 위해 더 많은 코딩이 필요하기 때문에 기다릴 수 없습니다. 이 문제를 해결하기 위해 필자는 ActiveDirectoryFacade를 통해 호출 될 UserFactory 클래스를 작성했습니다. C# setting property values through reflection with attributes
누구나 다른 생각을 가지고 또는이를 확인할 수 있습니다
Reflection, Attributes and Property Selection

편집 이것은 내가 원하는 다음과 같습니다

편집이 SO 질문은 내가 달성하고자하는 것과 매우 가까운 것 같다 맞지?

또한 .NET Framework 2.0 및 VBNET2005에 고정되어 있다고 언급 할 것입니다. 그렇지 않으면 Bart de Smet의 LINQ를 AD 라이브러리에 사용했을 것입니다.

도움 주셔서 감사합니다.

답변

2

저는 DirectoryServices에 익숙하지 않지만 사용자의 질문이 맞으면 사용자 개체의 속성을 설정하기 위해 반사를 사용할 수 있습니다. 올바른 속성을 설정하려면 속성 이름을 사용자 개체 속성의 특성에 저장된 데이터와 일치시켜야합니다.

[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]); 
      } 
     } 
    } 

채우려는 속성의 이름을 변경할 수있는 경우 사전에 속성 매핑을 저장할 수 있습니다.

+0

흥미 롭습니다! 이 방법을 생각했지만 작동시키기위한 간단한 방법을 찾을 수있었습니다. 나는 당신의 접근 방식으로 그것을 작동시킬 수 있다고 생각합니다. 나는 그것을 시험해보고 효과가 있는지 여부를 알려줄 것입니다. 감사! –

관련 문제