So in place of dynamics I created IDirectoryAttributes and DirectoryAttributes. If you've ever worked with IDataReader, it will feel very familiar. Here are the get methods for the interface:
string DistinguishedName { get; }
object GetValue(string attribute);
DirectoryAttribute Get(string attribute);
byte[] GetBytes(string attribute);
string[] GetStrings(string attribute);
string GetString(string attribute);
byte? GetByte(string attribute);
int? GetInt(string attribute);
long? GetLong(string attribute);
double? GetDouble(string attribute);
decimal? GetDecimal(string attribute);
short? GetShort(string attribute);
float? GetFloat(string attribute);
bool? GetBoolean(string attribute);
DateTime? GetDateTime(string attribute, string format = "yyyyMMddHHmmss.0Z");
Guid? GetGuid(string attribute);
SecurityIdentifier GetSecurityIdentifier(string attribute);
IEnumerable<byte[]> GetByteArrays(string attribute);
Pretty standard. Attribute is case insensitive. If it's not found then null will be returned. Since everything is either a string or byte array from the directory, if it fails to convert then a FormatException will be thrown. GetValue will try to guess the type like before and is only here to support the implementation of IEnumerable<string, object>. Of course if there's a datatype here that's missing, just use Get and you'll get direct access to the DirectoryAttribute.
So what about change tracking? Since DirectoryAttributes is just a wrapper for SearchResultEntry, setting values is tracked in an internal dictionary. Just call SetValue(attributeName, value) and it will take care of the rest.
var factory = new LdapConnectionFactory("localhost");
string namingContext = "CN=Users,CN=Employees,DC=Northwind,DC=local";
using (IDirectoryContext context = new DirectoryContext(factory.GetConnection(), true))
{
var query = context.Query(namingContext, objectClass: "Person")
.Where("cn=Andrew Fuller")
.Select("cn");
var user = query.FirstOrDefault();
user.SetValue("employeeid", 1);
var updated = context.Update(user);
Console.WriteLine(updated.GetInt("employeeid"));
Console.WriteLine(updated.GetGuid("objectguid"));
}
That's it. I hope this helps with performance and satisfies anyone who can't / won't map classes.
No comments:
Post a Comment