I have a bunch of methods with varying signatures. These methods interact with a fragile data connection, so we often use a helper class to perform retries/reconnects, etc. Like so:
MyHelper.PerformCall( () => { doStuffWithData(parameters...) });
And this works fine, but it can make the code a little cluttery. What I would prefer to do is decorate the methods that interact with the data connection like so:
[InteractsWithData] protected string doStuffWithData(parameters...) { // do stuff... }
And then essentially, whenever doStuffWithData
is called, the body of that method would be passed in as an Action
to MyHelper.PerformCall()
. How do I do this?
The Decorator pattern is best when the decorators modify the behavior of the methods in the interface. A decorator can add methods, but added methods don't carry through when you wrap in another decorator.
Disadvantages. High degree of flexibility. High complexity of software (especially decorator interface) Expansion of function of classes without inheritance. Not beginner-friendly.
In Python, a function decorator is effectively a function wrapper. A function decorator extends the functionality of a function by wrapping around it without modifying its original intended behavior.
The decorator pattern can be used to extend (decorate) the functionality of a certain object statically, or in some cases at run-time, independently of other instances of the same class, provided some groundwork is done at design time. This is achieved by designing a new Decorator class that wraps the original class.
.NET Attributes are meta-data, not decorators / active components that automatically get invoked. There is no way to achieve this behaviour.
You could use attributes to implement decorators by putting the decorator code in the Attribute class and call the method with a helper method that invokes the method in the Attribute class using Reflection. But I'm not sure this would be a big improvement over just calling the "decorator-method" directly.
"Decorator-Attribute":
[AttributeUsage(AttributeTargets.Method)] public class MyDecorator : Attribute { public void PerformCall(Action action) { // invoke action (or not) } }
Method:
[MyDecorator] void MyMethod() { }
Usage:
InvokeWithDecorator(() => MyMethod());
Helper method:
void InvokeWithDecorator(Expression<Func<?>> expression) { // complicated stuff to look up attribute using reflection }
Have a look at frameworks for Aspect Oriented Programming in C#. These may offer what you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With