views:

574

answers:

3

I have a DataContract class that I have to fill by values from the Active Directory of our company.

[DataContract(Namespace = Global.Namespace)]
public class UserProfile
{
    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    public string EmployeeID { get; private set; }

    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    public string GivenName { get; private set; }

    ...

    public static readonly string[] PropertiesToLoad = new[] { "EmployeeID", "GivenName" };
}

I was considering to make a custom attribute to decorate my properties, so that the code that would fill my object from the AD would not need to have the Mapping hardcoded, but much rather I could just decorate the properties to automatically fill the object.

And in the long run, I might also be able to get rid of this "PropertiesToLoad". Do you think that Attributes are a good way of solving this issue? And another question, if I do solve this by Attributes, am I likely to make a huge performance bottle neck or is the use of Attributes not really a performance issue.

+3  A: 

Using reflection and attributes are slower than regular C# compiled as IL, but the question is: how much are you doing it? If you aren't doing lots of this, you won't notice it.

There are ways of boosting the performance of reflection, but they are quite advanced.

That seems a reasonable way of specifying a mapping (and is comparable to most serialization and persistence frameworks - although often a separate API without attributes is offered too).

For (in)appropriate uses, see Eric Lippert's blog.

Marc Gravell
+1  A: 

I like to use attributes for this kind of concern because it helps make it clear in the code that the property is being used in a certain way. There is a trade-off between having the PropertiesToLoad in one place (as it is in the example above) or at the point of property declaration. I tend to find that using attributes helps code maintenance because I don't have to hunt down changes if the property is removed or modified.

As for performance, yes it will cause a performance hit but not huge. It is measurable but unless this is performance critical code, you probably won't notice. And even at that point, I'm guessing you'll find bigger issues. If the attribute reflection becomes an issue, there are way to mitigate the performance impact by using caching or other methods.

Steven Lyons
+1  A: 

I ended up writing the following code.

public class UserProfile
{
    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public string EmployeeID { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public string GivenName { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty("SN")]
    public string Surname { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public string Company { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public string Department { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty("CN")]
    public string UserName { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty("Mail")]
    public string Email { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    [ActiveDirectoryProperty]
    public LanguageType Language { get; set; }


    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    public DateTime? NextPasswordChangeDate { get; set; }
}

I then can use reflection to get the old "PropertiesToLoad" which in itself is mostly harmless, since I use reflection only once to fill an array after that, I don't need to call GetProperties anymore.

The only thing that remains to test is, if I can fill the object from the SearchResult fast enough - but, tbh, the AD query is usually way slower than some in-memory operations, so I am looking forward to the result. :)

Icey