Я пытался выяснить это всю ночь, но я думаю, что мои знания о .Net Framework не так уж глубоки, и проблема не совсем в Google, но если я смогу кивнуть в правильное направление, я уверен, что смогу реализовать это, так или иначе.
Я бы хотел иметь возможность объявить свойство, украшенное пользовательским атрибутом, следующим образом:
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; }
}
А потом каким-то образом - это та часть, которую я не могу понять - замените автоматически сгенерированную реализацию этого геттера частью пользовательского кода, что-то вроде:
Type expressionHolderType = LookupAttributeCtorArgTypeInDeclarationOfPropertyWereReplacing();
return ReplaceWithExpressionFromAttribute.GetCompiledExpressionFrom(expressionHolderType)(this);
Главное, я не уверен, как это сделать, это заменить автоматическую реализацию get.
Первое, что пришло на ум, было PostSharp , но это более сложная зависимость, чем я забочусь. Я бы предпочел способ кодировать его без использования постобработки, прикрепленной к сборке (я думаю, в этом и заключается суть того, как PostSharp в любом случае поглощает свои хуки).
Другая часть этого, в которой я не так уверен, заключается в том, как извлечь параметр типа, переданный конкретному экземпляру атрибута ReplaceWithExpressionFrom (где он украшает свойство, тело которого я хочу заменить; другими словами, как сделать Я получаю typeof (SomeOtherClass), где я пишу замену получить тело). Я планирую кэшировать скомпилированные выражения из конкретных экземпляров IExpressionHolder, поскольку я не хочу делать это каждый раз, когда свойство извлекается.
Я полагаю, что это просто получил , чтобы быть возможным. По крайней мере, я полагаю, что я должен быть в состоянии найти сборку для любого метода, украшенного атрибутом, и каким-то образом прокси-классом или просто заменить IL или .. что-то? И я хотел бы сделать интеграцию настолько гладкой, насколько это возможно, поэтому, если это можно сделать без явного вызова метода регистрации или инициализации, который был бы великолепен.
Спасибо!