I'd like to use an Autofac delegate factory to resolve an object graph where some of the nested objects need to be passed parameters. E.g. If the QuoteService in the Autofac delegate factory example required a url to retrieve data from, or the QuoteService itself had a dependency that required a parameter.
public class WebQuoteService : IQuoteService
{
public WebQuoteService(Uri source)
{
}
}
public class Shareholding
{
public Shareholding(string symbol, uint holding, IQuoteService quoteService)
{
}
}
I'd like to be able to declare and register a delegate like so:
public delegate Owned<Shareholding> ShareholdingFactory(string symbol, uint holding,
Uri source);
builder.RegisterGeneratedFactory<ShareholdingFactory>();
The problem I run into is that Autofac can't resolve the uri parameter of the WebQuoteService.
I've seen a few similar questions & solutions, but nothing particularly neat. Autofac-passing-parameter-to-nested-types suggests registering a lambda to explicitly implement the factory and resolve the nested dependency. I'm sure that would work, but it becomes very messy if the parameter is needed at a deeper level or when there are more dependencies.
The temporary solution I'm using is an improvement on that, resolving the IQuoteService in Shareholding OnPreparing, and forwarding the parameters created by the Autofac generated factory.
builder.RegisterType<Shareholding>().OnPreparing(e =>
{
e.Parameters = e.Parameters.Union(new[]
{
new TypedParameter(typeof (IQuoteService), e.Context.Resolve<IQuoteService>(e.Parameters))
});
});
That works ok and avoids manually resolving other parameters, but I actually need to do it twice to forward the parameters to a second nested level.
I've considered, but not tried to use BeginLifetimeScope(Action<ContainerBuilder>) as suggested by can-components-be-temporarily-registered-in-an-autofac-container. I think I'd have to implement the factory manually, but I could then register the uri so it would work at any nesting level.
What I'd actually like to be able to do is attach to WebQuoteService OnPreparing and access the delegate factory's parameters. Something like this can be made to work with reflection but that's obviously not ideal.
builder.RegisterType<WebQuoteService>().OnPreparing(e =>
{
var parameters = e.Context._context._activationStack.Last().Parameters;
e.Parameters = e.Parameters.Concat(parameters);
});
Can anyone suggest a cleaner alternative to pass parameters to objects nested two levels deep?