【问题标题】:Autofac in console applications (convention)控制台应用程序中的 Autofac(约定)
【发布时间】:2017-09-13 18:53:34
【问题描述】:

我想在控制台应用程序中使用 Autofac。这是我真正的第一次使用。在此之前,我只在 ASP.NET MVC 中使用它。在 MVC 项目中,我可以在 Global.asax 中设置 Autofac,将 IService 注入控制器,我们可以说它越来越有效。 在控制台应用程序中,我这样做如下:

internal class Program
{
    private static IContainer Container { get; set;}

    private static void Main(string[] args)
    {
         Container = Container.Configure(); // here I have all necessary objects set
         // now I can use it in Main method as:
         using (var scope = Container.BeginLifetimeScope())
         {
             scope.Resolve<ISomething>();
         }
    }
}

正如你所见,它的用法很简单,只在 Main 方法中。在外部课程中使用它怎么样?假设我想创建类 Cat,并在其中使用 Autofac。我应该从类 Program 传递给构造函数对象 Container 吗?例如:

Cat cat = new Cat(Program.Container, "Molly");

或者我应该在 Cat 类中创建 IContainer?

什么是最好的解决方案?

【问题讨论】:

    标签: c# .net dependency-injection console-application autofac


    【解决方案1】:

    只有您的控制台应用程序真正需要了解 AutoFac,否则您将陷入服务定位器模式,这通常被认为是一种反模式。相反,您的应用程序应遵循以下模式:

    //in your console application
    using (var scope = Container.BeginLifetimeScope())
    {
        IServiceservice = scope.Resolve<IService>();
        service.Execute();
    }
    
    class SomeService : IService
    {
        readonly ISomeDependency _dependency;
    
        public SomeService(ISomeDependency dependency)
        {
            _dependency = dependency;
        }
    
        public void Execute()
        {
            _dependency.DoSomething();
        }
    }
    
    interface IService
    {
        void Execute();
    }
    

    请注意,我从未真正调用过构造函数。我养成了从不“新建”对象的习惯,除非该对象只是一个 POCO(仅包含数据,没有逻辑)。

    请注意,ISomeDependency 本身可以依赖于 0 个或多个其他类,它通过构造函数注入来获取。由于 AutoFac 创建了IService,以及它的所有依赖项,包括ISomeDependency,所有ISomeDependency 的依赖项也将被初始化,以此类推。 Miguel Castro 的Deep Dive into Dependency Injection and Writing Decoupled Quality Code and Testable Software 是一个很好的演示这个概念的视频。

    【讨论】:

    • 梅森,感谢您的宝贵回答。我想从第一篇文章中扩展我的问题。正如您所写,我们可以在主方法内创建任何对象。如果我想在其他课程中使用 Autofac 怎么办?假设我有课public class EmployeeService { public Employee GetEmployee(decimal id) { // here I would like to use some other service: inject using AutoFac. // should I create here again Container object and then: // using (var scope = Container.BeginLifetimeScope()) { ... } } }
    • @cube 我不明白你现在在问什么。是的,你可以通过 AutoFac 创建一个对象的实例,并通过构造函数注入来注入东西。
    • 我对自己的理解感到困惑。但是,您回答了我的疑问。再次感谢您。
    【解决方案2】:

    我使用 autofac 依赖注入配置创建了这个 dotnet 核心控制台应用程序模板,这将节省您在每次设置新项目时进行一些重复性工作的宝贵时间。通过 nuget 安装,希望它对你有用。

    https://medium.com/@mrkevin.wang/create-a-dotnet-core-cosnole-app-template-with-autofac-dependency-injections-60e09f27df17?source=friends_link&sk=d831e88acc36319e2a43e8c7dac70238

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-15
      • 2011-01-22
      相关资源
      最近更新 更多