Без использования генерации Годе, вы не можете сделать много против этого. Возможно, вы могли бы улучшить синтаксис.
А как насчет использования метода расширения?
class static MyHelper
{
Wrap<T>(this object service, Action<T> action)
{
// check attribute and wrap call
}
}
использование:
RawFoo foo = ...
foo.Wrap(x => x.doStuffWithData(parameters...));
Это тривиально, но вы не можете убедиться, что Wrap был использован.
Вы можете реализовать универсальный декоратор. Этот декоратор будет использоваться один раз, чтобы обернуть сервис, и тогда вы не сможете вызвать его без обертки.
class Decorator<T>
{
private T implementor;
Decorator(T implementor)
{
this.implementor = implementor;
}
void Perform<T>(Action<T> action)
{
// check attribute here to know if wrapping is needed
if (interactsWithData)
{
MyHelper.PerformCall( () => { action(implementor) });
}
else
{
action(implementor);
}
}
}
static class DecoratorExtensions
{
public static Decorator<T> CreateDecorator<T>(T service)
{
return new Decorator<T>(service);
}
}
Использование:
// after wrapping, it can't be used the wrong way anymore.
ExtendedFoo foo = rawFoo.CreateDecorator();
foo.Perform(x => x.doStuffWithData(parameters...));