How do I pass a parameter to a component in the middle of a resolve chain?¶

For this question, let’s imagine a simple email notification system like this:

// This interface lets you send an email notification to someone.publicinterfaceINotifier{voidSend(stringaddress,stringmessage);}// This implementation of the notifier uses a backing email// repository for doing the heavy lifting.publicclassNotifier:INotifier{privateIEmailServer_server;publicNotifier(IEmailServerserver){this._server=server;}publicvoidSend(stringaddress,stringmessage){this._server.SendMessage(address,"from@domain.com",message);}}// This email server interface is what the notifier will use// to send the email.publicinterfaceIEmailServer{voidSendMessage(stringtoAddress,stringfromAddress,message);}// Notice this implementaton takes a string parameter for the server address -// something we won't know until runtime so we can't explicitly register the// parameter value.publicclassEmailServer:IEmailServer{privatestring_serverAddress;publicEmailServer(stringserverAddress){this._serverAddress=serverAddress;}publicvoidSendMessage(stringtoAddress,stringfromAddress,message){// ...send the message through the specified server address.}}

When you register things in Autofac, you might have registrations that look like this:

Before answering the question, consider that in many respects that asking this question indicates a sort of design problem.

Technically speaking, you’re resolving an INotifier - a component that doesn’t need to know about the runtime parameter with the email server address. The implementation of that INotifier could change. You could register a stub for testing, or switch up how emails get sent so they no longer need to know about the address.

Passing the server address as a parameter to the INotifier breaks the decoupling that interface-based development and inversion of control gives you by assuming that you “know” how the entire dependency chain is being resolved.

The key to solving the problem is to break that “knowledge” so you’re not passing a parameter.