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?
1 Answer 1
Why are you ToList
ing your collections when you are returning IEnumerable<T>
? Unless you have a good reason (rare) then leave them as IEnumerable
GetAsDirectoryEntry
seems redundant - and in fact hides the fact that it could be null, whereas somebody calling as
directly will know that null is possible. I note when you call it you do not test for null.
In general I prefer the lamba inputs as short names escpecially when the scope is so small, so do
.Where( dn=>!dn.IsNullOrWhiteSpace())
instead of
.Where(
directReportDistinguishedName =>
!directReportDistinguishedName.IsNullOrWhiteSpace())
Explore related questions
See similar questions with these tags.