Tuesday, July 27, 2010

Getting the value of a property through reflection.

For a project I am working on I needed to retrieve the value of a property.  Problem was I had a string that told me the name of the property.  Most .NET people out there would say just use reflection stupid.  Which is what I did but it was a learning experience for me. This is my first foray into reflection.  Here is the code.

public static object GetPropertyValue(object ObjectInstance, string WantedProperty)
        {
            var aviableProperties = ObjectInstance.GetType().GetProperties();
            var workingProperty = aviableProperties.FirstOrDefault(c => c.Name == WantedProperty);
            if (workingProperty != null)
            {
                return workingProperty.GetValue(ObjectInstance, null);
            }
            throw new ApplicationException(string.Format("The Property {0} was not found in the class.", WantedProperty));
        }

Tuesday, July 13, 2010

ValidationAttribute verses the contextual validation

This last week I got tasked with building some validation for the customer object in our new system here at work. Since we are using MVC2 I can use DataAnnotations to do this. Which in most situations would just mean I throw on some attributes like [Required(ErrorMessage="No soup for you")] But not where I work we can’t have one set of required fields no. Each country has a different set of required fields. This means that I not only need to know what the data I am validating is but what context it is validate in.

This means I can’t use

public bool IsValid(object value)

since it has no idea of context. However there is a second overload of IsValid that will work. It took me a bit to understand how this works but it is very nice.

protected ValidationResult IsValid(object value, ValidationContext validationContext)

the ValidationContext gives you access to the object that’s data member you are validating. By using the ObjectType and ObjectInstances of the property you can get access to all the data members of the current object.

Using the above functions It is easy to create a validator that checks to see if a country should or shouldn’t be validate for a given data member and then validate it if I need to.

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class RequiredForCountry : ValidationAttribute
{
public string CountryIds { get; set; }
public int TermId { get; set; }

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (string.IsNullOrEmpty(this.CountryIds))
{
throw new System.ApplicationException(string.Format(
"The property {0} is not set up correctly in class {1}",
validationContext.MemberName,
validationContext.ObjectType.FullName));
}
var countryId = GetCountryID(validationContext);
if (CountryIds.Contains(countryId.ToString()))
{
if (value == null)
return new ValidationResult(TermId.ToString());
var strCheck = value as string;
if (strCheck != null && strCheck == string.Empty)
return new ValidationResult(TermId.ToString());
}
return ValidationResult.Success;
}

private int GetCountryID(ValidationContext context)
{
switch (context.ObjectType.Name)
{
case "Customer":
return (context.ObjectInstance as ICustomer).MainAddress.Country.Id;
case "Order":
return (context.ObjectInstance as IOrder).Country.Id;
default:
return -1; // eventually this will throw an error
}
}
}

While the above code isn’t the prettiest code I have ever written it gets the job done and allows me to not have to write custom validation for every country.

Wednesday, June 30, 2010

Proper Use of Properties

Today we are talking about properties.  How to use them and more importantly how not to use them.

When dealing with properties like they wore written before 3.5 you should have some thing that looks like this.

private string _test;
public string Test
{
    get { return this._test; }
    set { this._test = value; }
}



I love properties like this it’s only slightly less cool then using the 3.5 version of a property. The thing I don’t like about a property like this is when a programmer decides he doesn’t need to user the property and accesses the _test variable directly inside of the class to make a change.  So like this




this._test = "some string";



I consider this bad programming.  It makes maintaining code much more difficult and adds an unnecessary level of complexity. You have to look at two things now to see how a value gets set or modified.  To do all the access through the property takes about the same amount of work and ends up in a much cleaner code file.




this.Test = "Some string";



Is actually one less key stroke and is so much easier to work with.

Tuesday, June 29, 2010

This code just rocks.

Usually I post examples of code that sucks.  Today I am posting an example of code that just rocks.  Why does it rock because it solves a problem in a very elegant way.  I have had to write code to do the same thing several times but mine never looks or works as this example. The code comes from ravenDB’s server. It handles the case where you need to run in elevated privileges but the program wasn’t started at such a state.


private static void AdminRequired(Action actionThatMayRequiresAdminPrivileges, string cmdLine)
{
    var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
    if (principal.IsInRole(WindowsBuiltInRole.Administrator) == false)
    {
        if (RunAgainAsAdmin(cmdLine))
            return;
    }
    actionThatMayRequiresAdminPrivileges();
}

private static bool RunAgainAsAdmin(string cmdLine)
{
    try
    {
        var process = Process.Start(new ProcessStartInfo
        {
            Arguments = cmdLine,
            FileName = Assembly.GetExecutingAssembly().Location,
            Verb = "runas",
        });
        if (process != null)
            process.WaitForExit();
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

Wednesday, January 20, 2010

Wow this one takes the cake.

So of late I have been working on a older system created in .NET by a delphi programmer. It has some very interesting behaviors.

private string Xml { set { this.Address = value; } }

public FooClass(PaymentInfo info)
: base(info)
{
this.Xml = string.Format("Some random string goes here" . .

The problems with this are many. The least of which would be the fact they created a property Xml that just sets another property Address. Why would you do this. You can just call Address.