How to decorate using custom attributes

I have some functions for which I want to record the time spent on them.

DBResult LongTask(DBCommand command)
{
   ...
}

Is there any way to do this

[LogTimeUsed()]
DBResult LongTask(DBCommand command)
{
   ...
}

So, can I have a class / function somewhere that is called every time this function is called, and can I enter my own code, access the command and DBResult and the log time spent on the operation?

+3
source share
6 answers

There is no built-in way in .NET to do this.

- ( ), - - . . :

// Define an interface for the operation
public interface IMyLongRunningTask
{
    DBResult longTask(DBCommand command);
}

// Define an implementation for the operation:
public class MyLongRunningTask : IMyLongRunningTask
{
    public DBResult longTask(DBCommand command)
    {
        // code here
    }
}

IMyLongRunningTask:

public class MyLongRunningTaskMonitor : IMyLongRunningTask
{
    private readonly IMyLongRunningTask wrappedService;
    private readonly ILogger logger;

    public MyLongRunningTaskMonitor(IMyLongRunningTask wrapped,
        ILogger logger)
    {
        this.wrappedService = wrapped;
        this.logger = logger;
    }

    public DBResult longTask(DBCommand command)
    {
        var watch = Stopwatch.CreateNew();

        var result = this.wrappedService.longTask(command);

        this.logger.Log("longTask executed in " + 
            watch.ElapsedMilliseconds + " ms.");

        return result;
    }
}

, MyLongRunningTaskMonitor IMyLongRunningTask. :

container.Register<IMyLongRunningTask>(() =>
    new MyLongRunningTaskMonitor(
        container.GetInstance<MyLongRunningTask>(),
        container.GetInstance<ILogger>()
    )
);
+3

DynamicProxy.

DynamicProxy - , , /- .

+2

, , - PostSharp

0

The question is finding a way to create a decorator in C # using C # attributes to try to create decorator syntax as shown in python (which is great ... C # community note)

Something similar can be achieved by nesting the "attribute" in the name of your method (for example, LongTask_LogTimeUsed), and then have a small code (template) INSIDE method LongTask, which reads the name of its method, delegating before or after processing, the handlers:

How to get the name of the current method from code

How to get the parameters passed before the pre or post processors, you need to think about it.

0
source

All Articles