使用Autofac将依赖项注入控制台应用程序的Main入口点

Ric*_*ard 6 c# autofac

说我有一个简单的控制台应用程序:

public static class Program
{
    private static ILog Log { get; set; }

    public static void Main()
    {
        Log.Write("Hello, world!");
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用Autofac注入Log实例并确保Log属性在运行时不为null的最简单方法是什么?问题是我不能通过Main()传递它,我试图避免使用容器的服务位置(只是因为).

Ste*_*ven 11

你应该做的是从你的主要提取所有逻辑到一个类.这个类可以有一个带依赖关系的构造函数.您在main中解析此类并调用它.然后,该类应被视为整个应用程序.Program课堂内发生的一切现在都可以被视为你的作曲根.

// 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!");
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,container.Resolve<ApplicationLogic>()只是解决ApplicationLogic类,它解决了整个对象图,包括所有ApplicationLogic无论图形有多深的依赖,以及这些依赖的依赖,等等.您唯一负责的是在ConfigureContainer()方法中注册这些依赖项.因此,有一个以上的Resolve()方法调用控制台应用程序是不常见的,如果存在,则应始终在组合根目录内调用或连接它们.