假设我有一个简单的控制台应用程序:
public static class Program
{
private static ILog Log { get; set; }
public static void Main()
{
Log.Write("Hello, world!");
}
}
我可以使用Autofac注入Log实例并确保Log属性在运行时不为null的最简单方法是什么?问题是我无法通过Main()传递它,我试图避免使用容器的服务位置(仅仅因为)。
答案 0 :(得分:11)
你应该做的是从你的主要提取所有逻辑到一个类。该类可以具有带依赖性的构造函数。您在main中解析此类并调用它。然后,该类应被视为整个应用程序。 Program
课程中发生的所有事情现在都可以被视为您的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!");
}
}
请注意,container.Resolve<ApplicationLogic>()
不只解析ApplicationLogic
类,它会解析整个对象图,包括 all of ApplicationLogic
的依赖关系,以及这些依赖关系的依赖关系等,无论图形有多深。您唯一负责的是在ConfigureContainer()
方法中注册这些依赖项。因此,有一个超过1 Resolve()
方法调用控制台应用程序是不常见的,如果存在,则应始终在组合根目录内调用或连接它们。
答案 1 :(得分:2)
您必须在某处配置容器。在控制台应用中,Main()
通常就是那个地方。
答案 2 :(得分:1)
必须将 builder.RegisterType.AsSelf(); 更改为 builder.RegisterType()。AsSelf(); ,以使其对我有用
答案 3 :(得分:0)
我已经创建了一个启动文件来注册所有autofac内容,以使其更加整洁。
还在nuget中创建了一个模板,您可以使用dotnet install直接安装该模板。
这是我的文章,用于描述模板中确切包含的内容,希望可以帮助您更清楚地将autofac与控制台应用程序配合使用。