Type checking propertyLambdas in RegisterProperty

Type checking propertyLambdas in RegisterProperty

Old forum URL: forums.lhotka.net/forums/t/9763.aspx


almostchristian posted on Monday, November 15, 2010

Hi,

I've mentioned before that I am working on an extension to CSLA 4.0 that combines the fetch and persistence functionality of the properties by overloading the RegisterProperty

public class Currency : LinqReadOnlyBase<Currency, CurrencyMaster>    { 
        protected static readonly PropertyInfo<string> CurrencyIDProperty = RegisterProperty<string>(c => c.CurrencyID, r => r.CurrencyID); 

In the example above, CurrencyMaster is the class generated by Linq to SQL from the CurrencyMaster table. The snippet r=>r.CurrencyID, returns the column, r being of type CurrencyMaster

I followed the definition of the base RegisterProperty, defining the lambda as Expression<Func<E, object>> with E as the Linq2Sql class. In my unit testing, this has caused some runtime errors related to casting. Why does RegisterProperty have a Type constraint when it is not being used in the lambdas? So I sought a solution to this problem. After scouring the internet for possible solutions, I wasn't able to find one, so I experimented and found a solution works. I've even found some casting errors in my classes which compiled previously since they were downcasts so didn't cause runtime errors (byte to short, is short smaller than byte?). I can't say that the solution looks beautiful but since its a framework code, and it forces a correct behavior, I decided that it should stay. Anyway, here is the code. I hope something like this would be added to the core Csla. The core classes is doing something funky with reflect and I haven't had much time examining it.

private static Dictionary<string, Func<E, object>> FetchFunctionsMap = new Dictionary<string, Func<E, object>>();

protected static PropertyInfo<P> RegisterProperty<P>(Expression<Func<T, object>> propertyLambdaExpression, Expression<Func<E, P>> fetchLambdaExpression)

{

PropertyInfo<P> p = RegisterProperty<P>((Expression<Func<T, object>>)propertyLambdaExpression);

FetchFunctionsMap.Add(p.Name, (e) => (object)fetchLambdaExpression.Compile()(e));

return p;

}

The solution involves creating a new lambda, which calls the passed lambda and casts the result to object.

Copyright (c) Marimer LLC