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