Skip to content

Instantly share code, notes, and snippets.

@danielwertheim
Last active April 5, 2017 03:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielwertheim/014c936dc13d6108d0b6 to your computer and use it in GitHub Desktop.
Save danielwertheim/014c936dc13d6108d0b6 to your computer and use it in GitHub Desktop.
How to bootstrap Autofac and Routemeister to get per request lifetime scopes. Blog: http://danielwertheim.se/routemeister-and-autofac/
using System;
using System.Threading.Tasks;
using Autofac;
using Routemeister;
using Routemeister.Routers;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterAssemblyModules(typeof(Program).Assembly);
var container = builder.Build();
var router = container.Resolve<IAsyncMessageRouter>();
router.RouteAsync(new MyMessage()).Wait();
router.RouteAsync(new MyMessage()).Wait();
}
}
public interface ISomeMessageHandler<in TMessage>
{
Task HandleAsync(TMessage message);
}
public class MyMessage { }
public class ConcreteHandler :
ISomeMessageHandler<MyMessage>,
IDisposable
{
private readonly SomeDependency _dependency;
public ConcreteHandler(SomeDependency dependency)
{
_dependency = dependency;
}
public async Task HandleAsync(MyMessage message)
{
await _dependency.DoWorkAsync();
}
public void Dispose()
{
Console.WriteLine("I am being released");
}
}
public class SomeDependency : IDisposable
{
public Task DoWorkAsync()
{
Console.WriteLine("Doing work with underlying connection");
return Task.FromResult(0);
}
public void Dispose()
{
Console.WriteLine("I'm cleaning the underlying connection.");
}
}
internal static class MessageEnvelopeExtensions
{
internal static void SetScope(this MessageEnvelope envelope, ILifetimeScope scope)
{
envelope.SetState("scope", scope);
}
internal static ILifetimeScope GetScope(this MessageEnvelope envelope)
{
return envelope.GetState("scope") as ILifetimeScope;
}
}
public class OurModule : Module
{
protected override void Load(ContainerBuilder builder)
{
//MessageRoutes
builder.Register(ctx =>
{
var factory = new MessageRouteFactory();
return factory.Create(
typeof(Program).Assembly,
typeof(ISomeMessageHandler<>));
})
.SingleInstance();
//Router
builder.Register(ctx =>
{
var routes = ctx.Resolve<MessageRoutes>();
var parentScope = ctx.Resolve<ILifetimeScope>();
var router = new MiddlewareEnabledAsyncMessageRouter(
(type, envelope) => envelope.GetScope().Resolve(type),
routes);
router.Use(next => envelope =>
{
using (var childScope = parentScope.BeginLifetimeScope())
{
envelope.SetScope(childScope);
return next(envelope);
}
});
return router;
})
.As<IAsyncMessageRouter>()
.SingleInstance();
builder.RegisterType<SomeDependency>();
builder.RegisterType<ConcreteHandler>();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment