One of the nice features of Autofac is the support for decorators.
A decorator class implements the same interface as the class it “wraps”. With a decorator you can add functionality to a class without changing it’s signature.
Let’s walk through an example step by step:
Here is the class and it’s corresponding interface I want to decorate:
public class ConsoleLogger: ILogger | |
{ | |
public Task LogInformation(string message) | |
{ | |
Console.WriteLine(message); | |
} | |
} |
public interface ILogger | |
{ | |
Task LogInformation(string message); | |
} |
Nothing special at the Autofac level yet:
builder.RegisterType<ConsoleLogger>().As<ILogger>(); |
Let’s now extend the behavior of this class through a decorator. What if we want to benchmark the execution time of the LogMessage() method? The decorator class should implement the same interface AND inject the interface at the same time:
public class BenchmarkDecorator:ILogger | |
{ | |
private readonly ILogger _decoratedLogger; | |
public BenchmarkDecorator(ILogger logger) | |
{ | |
_decoratedLogger=logger; | |
} | |
public async Task LogMessage(string message) | |
{ | |
//Add your benchmark logic here | |
await _decoratedLogger.LogMessage(message); | |
//And here :-) | |
} | |
} |
Now we need to register the decorator in Autofac:
builder.RegisterDecorator<ILoggerDecorator,ILogger(); |
Remark: When using generics, it is also possible to register an open generic decorator. Therefore you need to use the RegisterGenericDecorator() overload
More information: https://autofaccn.readthedocs.io/en/latest/advanced/adapters-decorators.html