I have non-disposable class ReadModelRepository
that depends on (but does not own) an instance of the disposable class ReadModelDbContext
. Within a Module
, I want to configure my Autofac 3.0.2 container so that ReadModelDbContext
is resolved (one instance per dependency) only when ReadModelRepository
objects are created.
This is what I currently have:
builder.RegisterType<ReadModelRepository>().As<IReadModelRepository>();
builder.Register(c => new ReadModelDbContext(_connectionStringName)).AsSelf();
However, I do not want any arbitrary class to be able to resolve ReadModelDbContext
using the registration provided by the module. Indeed, it's probable that other classes will need to resolve different ReadModelDbContext
instances.
To solve this, I could use WithParameter
, as in this snippet:
builder
.RegisterType<ReadModelRepository> ().As<IReadModelRepository> ()
.WithParameter (
(p, c) => p.ParameterType == typeof (ReadModelDbContext),
(p, c) => new ReadModelDbContext (_connectionStringName));
However, I also need Autofac to automatically dispose the ReadModelDbContext
when the lifetime scope resolving the ReadModelRepository
(or actually that of its resolving component) ends. Using WithParameter
, this doesn't seem to work.
So, in essence, I'd like to register a dependency only in the context of an outer component, with Dispose
being called when the lifetime scope of the outermost component ends. Is this possible?
After some time, I've actually adopted a different approach: I register the inner component (ReadModelDbContext
) with a private key:
var privateKey = new object();
builder.Register(c => new ReadModelDbContext(_connectionStringName)).Keyed<ReadModelDbContext>(privateKey);
builder.Register(ctx => new ReadModelRepository(ctx.ResolveKeyed<ReadModelDbContext>(privateKey))).As<IReadModelRepository>();
Since nobody else has the key, this effectively makes the ReadModelDbContext
registration private to the ReadModelRepository
.