using Autofac.Features.OwnedInstances;
public static void Main()
var builder = new ContainerBuilder();
builder.RegisterAssemblyModules(typeof(HandlerModule).Assembly);
builder.RegisterType<LifetimeScopeTester>()
.InstancePerMatchingLifetimeScope("pipline");
var container = builder.Build();
var pingHandler = container.Resolve<IHandle<PingRequest, PingResponse>>();
pingHandler.Handle(new PingRequest());
public class HandlerModule : Autofac.Module
protected override void Load(ContainerBuilder builder)
builder.RegisterAssemblyTypes(ThisAssembly)
.As(type => type.GetInterfaces()
.Where(interfaceType => interfaceType.IsClosedTypeOf(typeof(IHandle<,>)))
.Select(interfaceType => new KeyedService("IHandle", interfaceType)));
builder.RegisterGenericDecorator(
typeof(SecondDecoratorHandler<,>),
.Keyed("SecondDecoratorHandler", typeof(IHandle<,>));
builder.RegisterGenericDecorator(
typeof(FirstDecoratorHandler<,>),
.Keyed("FirstDecoratorHandler", typeof(IHandle<,>));
builder.RegisterGeneric(typeof(LifetimeScopeHandler<,>))
.WithParameter((pi, c) => pi.Name == "decoratedHandler",
ILifetimeScope scope = c.Resolve<ILifetimeScope>();
ILifetimeScope piplineScope = scope.BeginLifetimeScope("pipline");
var o = piplineScope.ResolveKeyed("FirstDecoratorHandler", pi.ParameterType);
scope.Disposer.AddInstanceForDisposal(piplineScope);
public class LifetimeScopeTester { }
public interface IHandle<in TRequest, out TResponse> where TRequest : class, IRequest<TResponse>
TResponse Handle(TRequest request);
public interface IRequest<TResponse>
public class PingRequest : IRequest<PingResponse>
public class PingResponse
public class PingHandler : IHandle<PingRequest, PingResponse>
public PingResponse Handle(PingRequest request)
Console.WriteLine("PingHandler");
return new PingResponse();
public class FirstDecoratorHandler<TRequest, TResponse> : IHandle<TRequest, TResponse> where TRequest : class, IRequest<TResponse>
private readonly IHandle<TRequest, TResponse> _decoratedHandler;
private readonly LifetimeScopeTester _lifetimeScopeTester;
public FirstDecoratorHandler(IHandle<TRequest, TResponse> decoratedHandler, LifetimeScopeTester lifetimeScopeTester)
_decoratedHandler = decoratedHandler;
_lifetimeScopeTester = lifetimeScopeTester;
public TResponse Handle(TRequest request)
Console.WriteLine("FirstDecoratorHandler - LifetimeScopeTester[{0}]", _lifetimeScopeTester.GetHashCode());
return _decoratedHandler.Handle(request);
public class SecondDecoratorHandler<TRequest, TResponse> : IHandle<TRequest, TResponse> where TRequest : class, IRequest<TResponse>
private readonly IHandle<TRequest, TResponse> _decoratedHandler;
private readonly LifetimeScopeTester _lifetimeScopeTester;
public SecondDecoratorHandler(IHandle<TRequest, TResponse> decoratedHandler, LifetimeScopeTester lifetimeScopeTester)
_decoratedHandler = decoratedHandler;
_lifetimeScopeTester = lifetimeScopeTester;
public TResponse Handle(TRequest request)
Console.WriteLine("SecondDecoratorHandler - LifetimeScopeTester[{0}]", _lifetimeScopeTester.GetHashCode());
return _decoratedHandler.Handle(request);
public class LifetimeScopeHandler<TRequest, TResponse> : IHandle<TRequest, TResponse> where TRequest : class, IRequest<TResponse>
private readonly IHandle<TRequest, TResponse> _decoratedHandler;
public LifetimeScopeHandler(IHandle<TRequest, TResponse> decoratedHandler)
this._decoratedHandler = decoratedHandler;
public TResponse Handle(TRequest request)
Console.WriteLine("LifetimeScopeDecoratorHandler");
TResponse response = this._decoratedHandler.Handle(request);