I have created a few extension methods to get the direct reports of a UserPrincipal
as UserPrincipal
s themselves. This saves the user of the API quite a bit of typing.
public static IEnumerable<UserPrincipal> GetDirectReportUserPrincipals(
this UserPrincipal userPrincipal)
{
var directReportDistinguishedNames =
userPrincipal.GetDirectReportDistinguishedNames();
var directReportDistinguishedNamesArray =
directReportDistinguishedNames as string[] ??
directReportDistinguishedNames.ToArray();
if (directReportDistinguishedNamesArray.IsNullOrEmpty())
return null;
return userPrincipal.Context.FindUsersByDistinguishedNames(
directReportDistinguishedNamesArray);
}
public static IEnumerable<string> GetDirectReportDistinguishedNames(
this UserPrincipal userPrincipal)
{
return userPrincipal.GetProperty(DirectReports).Cast<string>()
.Where(
directReportDistinguishedName =>
!directReportDistinguishedName.IsNullOrWhiteSpace())
.ToList();
}
public static PropertyValueCollection GetProperty(
this Principal principal, string propertyName)
{
return principal.GetAsDirectoryEntry().Properties[propertyName];
}
public static DirectoryEntry GetAsDirectoryEntry(
this Principal principal)
{
return principal.GetUnderlyingObject() as DirectoryEntry;
}
public static UserPrincipal FindUserByDistinguishedName(
this PrincipalContext principalContext, string distinguishedName)
{
return UserPrincipal.FindByIdentity(
principalContext,
IdentityType.DistinguishedName,
distinguishedName);
}
public static IEnumerable<UserPrincipal> FindUsersByDistinguishedNames(
this PrincipalContext principalContext,
IEnumerable<string> distinguishedNames)
{
return distinguishedNames.Select(
principalContext.FindUserByDistinguishedName).ToList();
}
Yes, it does take all of those to do this one task, but the task itself can be called with
userPrincipal.GetDirectReportUserPrincipals();
instead of
- Converting user principal to dictionary entry.
- Getting direct reports property of dictionary entry.
- Casting property to string enumerable.
- Using each string (distinguished name) to search for a user principal.
Some of these do feel odd, like they are too Linq-heavy or just unnatural ways of accomplishing the goal. The top method GetDirectReportUserPrincipals
has an array cast to avoid "multiple enumeration" as ReSharper says. Is that really necessary?