views:

40

answers:

1

I've been trying to figure this out all night, but I guess my knowledge of the .Net Framework just isn't that deep and the problem doesn't exactly Google well, but if I can get a nod in the right direction I'm sure I can implement it, one way or another.

I'd like to be able to declare a property decorated with a custom attribute as such:

public MyClass {

    [ReplaceWithExpressionFrom(typeof(SomeOtherClass))]
    public virtual bool MyProperty { get; }

}

public SomeOtherClass : IExpressionHolder<MyClass, bool> {

    ...
}

public interface IExpressionHolder<TArg, TResult> {
    Expression<Func<TArg, TResult>> Expression { get; }
}

And then somehow - this is the part I'm having trouble figuring - replace the automatically generated implementation of that getter with a piece of custom code, something like:

Type expressionHolderType = LookupAttributeCtorArgTypeInDeclarationOfPropertyWereReplacing();
return ReplaceWithExpressionFromAttribute.GetCompiledExpressionFrom(expressionHolderType)(this);

The main thing I'm not sure how to do is replace the automatic implementation of the get.

The first thing that came to mind was PostSharp, but that's a more complicated dependency than I care for. I'd much prefer a way to code it without using post-processing attached to the build (I think that's the jist of how PostSharp sinks its hooks in anyway).

The other part of this I'm not so sure about is how to retrieve the type parameter passed to the particular instantiation of the ReplaceWithExpressionFrom attribute (where it decorates the property whose body I want to replace; in other words, how do I get typeof(SomeOtherClass) where I'm coding the get body replacement). I plan to cache compiled expressions from concrete instances of IExpressionHolder, as I don't want to do that every time the property gets retrieved.

I figure this has just got to be possible. At the very least I figure I should be able to search an assembly for any method decorated with the attribute and somehow proxy the class or just replace the IL or .. something? And I'd like to make the integration as smooth as possible, so if this can be done without explicitly calling a registration or initialization method somewhere that'd be super great.

Thanks!

+2  A: 

Maybe I'll get a downvote for this, but why do you want a property for this?

What you appear to want is a virtual call. Why not simply subclass MyClass and implement the virtual call?

Or you could use a dictionary of delegates to the appropriate function call.

Spence
Actually, building on previous work, I plan to implement a small framework such that when MyClass.MyProperty, in my example, is used in a LINQ query a provider swaps out the method call with the expression so that it can be converted to SQL.Others have already implemented the meat of this, I'm just trying to implement a cleaner way of attaching it to my domain classes than what all the previous examples had come up with.
qstarin
That's why the implementation of the property needs to be retained as an Expression object. All previous examples required the programmer to code the get to call upon the attribute, so potentially a person could end up with one implementation in the get and another in the Expression used again IQueryable. Not that I'm so much trying to prevent that as I am just trying to make using this cleaner.
qstarin
The main line of previous work I'm trying to extend can be found at http://mathgeekcoder.blogspot.com/2008/07/advanced-domain-model-queries-using_23.html
qstarin
@Spence +1 For even attempting to decipher this problem...
Reddog