What you should do is extract all logic from your main into a class. This class can have a constructor with dependencies. You resolve this class in the main and call it. This class should then be considered to be the entire application. Everything that happens inside the Program
class can now be considered your Composition Root.
// ** Begin composition root
public static class Program
{
public static void Main(string[] args)
{
var container = ConfigureContainer();
var application = container.Resolve<ApplicationLogic>();
application.Run(args); // Pass runtime data to application here
}
private static IContainer ConfigureContainer()
{
var builder = new ContainerBuilder();
builder.RegisterType<ApplicationLogic>.AsSelf();
builder.RegisterType<Log>().As<ILog>();
// Register all dependencies (and dependencies of those dependencies, etc)
return builder.Build();
}
}
// ** End composition root
public class ApplicationLogic
{
private readonly ILog log;
public ApplicationLogic(ILog log) => this.log = log;
public void Run(string[] args) => this.log.Write("Hello, world!");
}
Note that container.Resolve<ApplicationLogic>()
doesn't just resolve the ApplicationLogic
class, it resolves the entire object graph including all of ApplicationLogic
's dependencies, and dependencies of those dependencies, etc. no matter how deep the graph is. The only thing you are responsible for is registering those dependencies in the ConfigureContainer()
method. Therefore, it is somewhat unusual to have any more than 1 Resolve()
method call a console application, and if there are, they should always be called or wired up inside the Composition Root.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…