Injecting Services at Runtime

Lamar's predecessor StructureMap allowed you to override service registrations in nested containers in a general way. Some .Net application frameworks depend on this functionality to inject some kind of contextual service into a nested container. ASP.Net Core's HttpContext is an example. MassTransit's ConsumeContext is another.

Using that as an example, let's say that our application framework has this context type that the framework creates and wants to inject directly into nested containers for some kind of operation:

// This class is specific to some kind of short lived 
// process and lives in a nested container
public class ExecutionContext
{
    public Guid Id { get; set; } = Guid.NewGuid();
}

snippet source | anchor

We might well have a service in our code that is resolved from a Lamar container that depends on that ExecutionContext interface:

public class ContextUsingService
{
    public ExecutionContext Context { get; }

    public ContextUsingService(ExecutionContext context)
    {
        Context = context;
    }
}

snippet source | anchor

The first thing we have to do is make a registration in Lamar upfront that lets the container know that ExecutionContext is going to be injected at runtime:

var container = new Container(_ =>
{
    _.Injectable<ExecutionContext>();
});

snippet source | anchor

At runtime, we can inject ExecutionContext like this:

var context = new ExecutionContext();

var nested = container.GetNestedContainer();
nested.Inject(context);

snippet source | anchor

Finally, when we resolve a service that depends on ExecutionContext from the nested container we built above, we can see that it has a reference to our context object:

var service = nested.GetInstance<ContextUsingService>();
service.Context.ShouldBeSameAs(context);

snippet source | anchor