I am trying to implement logging capabilites into my application using Autofac's IInterceptor
interface provided by Autofac.Extras.DynamicProxy
. This is what I got so far.
A service which actions should get logged:
[Intercept("log-calls")]
public class FooService : IFooService
{
public int Add(int lhs, int rhs)
{
return lhs + rhs;
}
}
My IInterceptor
implementation:
public class Logger : IInterceptor
{
private readonly ILogger logger;
public Logger(ILogger logger)
{
this.logger = logger;
}
public void Intercept(IInvocation invocation)
{
var name = $"{invocation.Method.DeclaringType}.{invocation.Method.Name}";
var args = string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()));
this.logger.Write($"Calling: {name}");
this.logger.Write($"Args: {args}");
var watch = Stopwatch.StartNew();
invocation.Proceed();
watch.Stop();
var executionTime = watch.ElapsedMilliseconds;
this.logger.Write($"Done: result was {invocation.ReturnValue}");
this.logger.Write($"Execution Time: {executionTime}ms");
}
}
A test showing it's usage:
[Fact]
public void Should_Intercept_Method_Call()
{
// Arrange
var builder = new ContainerBuilder();
// ITestOutputhelper instance in this case
builder.Register(c => new Logger(this.logger))
.Named<IInterceptor>("log-calls");
builder.RegisterType<FooService>()
.As<IFooService>()
.EnableInterfaceInterceptors();
var container = builder.Build();
using var scope = container.BeginLifetimeScope();
var service = scope.Resolve<IFooService>();
// Act
_ = service.Add(2, 3);
// ...
}
Result:
Calling: ClassLibrary1.IFooService.Add
Args: 2, 3
Done: result was 5
Execution Time: 0ms
I am used to output messages (to debug console and textfile) that shows me what is going on in my application. Things like "SomeService has exported 42 items" or "AnotherService has finished reading 20 items to the database" and so on.
Now I am wondering how I could mimic this behavior without having to inject my ILogger
instance again everywhere. The AOP-way of logging is kind a static in terms of messages we can provide.
I hope its clear what I am trying to achieve.
if your want to no
[Intercept("log-calls")]
on class, you can try runtime aop framework like Norns.Urd or others which provide GlobalInterceptoryou just need add LoggerInterceptor once, like this: