嵌套类中的依赖注入

Posted

技术标签:

【中文标题】嵌套类中的依赖注入【英文标题】:Dependency Injection in nested classes 【发布时间】:2021-11-23 20:20:34 【问题描述】:

刚开始使用依赖注入和接口,我遇到了不知道如何解决的情况。

我正在构建一个控制台应用程序,我需要在其中使用 serilog,并从 appsettings.json 获取设置

我有 3 个 .cs 文件。

Program.cs:

static void Main(string[] args)

    Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

    var builder = new ConfigurationBuilder();

    BuildConfig(builder);

    Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(builder.Build())
        .Enrich.FromLogContext()
        .CreateLogger();

    Log.Logger.Information("Starting Datacollection");

    var host = Host.CreateDefaultBuilder()
        .ConfigureServices((context, services) =>
        
            services.AddTransient<IMyClass, MyClass>();
        )
        .UseSerilog()
        .Build();

    var svcMyClass = ActivatorUtilities.CreateInstance<MyClass>(host.Services);



    svcMyClass.MyMethod();


IMyClass.cs:

public interface IMyClass

    void MyMethod();

MyClass.cs:

public class MyClass : IMyClass

    private readonly ILogger<MyClass> _log;
    private readonly IConfiguration _config;

    public MyClass(ILogger<MyClass> log, IConfiguration config)
    
        _log = log;
        _config = config;
    

    public void MyMethod()
    
        
        //Do something

    

所有这些都很好用。我可以使用 _log 和 _config 从 MyClass 中访问 Serilog 和配置。

但是现在需要从 MyMethod 中调用新类 (MyClass2) 中的方法,并且 MyClass2 中的方法需要能够使用 Serilog 和配置文件。

最好的方法是什么?

【问题讨论】:

您能否发布一下您现在的问题以及您尝试的代码。 “从 MyMethod 中调用新类 (MyClass2) 的方法”没有多大意义。 【参考方案1】:

这仍然取决于您如何实施解决方案。

    如果您计划实现 IMyClass2 接口并且 MyClass2 实现这个。然后这个 IMyClass2 正在服务集合中注册。
public interface IMyClass2

   void Test();


public class MyClass2 : IMyClass2

private readonly ILogger<MyClass> _log;
private readonly IConfiguration _config;

public MyClass2(ILogger<MyClass> log, IConfiguration config)

    _log = log;
    _config = config;


  public void Test() 

现在在 MyClass 中,您可以将 IMyClass2 作为对 MyClass 的依赖注入,MyClass2 将处理它对记录器和配置的依赖。

从我的角度来看,这是一个好方法,因为您不必担心 MyClass2 依赖性。

    另一件事是,如果您不想使用依赖方式,则可以直接创建 MyClass2 的实例并传递依赖关系,但在这种情况下,您必须在方法调用中传递或需要使用 ActivatorUtilities。

注意:这完全是我的意见,可能会有所不同。

【讨论】:

【参考方案2】:

您将 MyClass2 注入到 MyClass 中以访问 MyClass2 的方法。

要访问 MyClass2 中的 Serilog 和配置文件,您必须将它们单独注入到该类中,然后 MyClass2 方法才能利用它们。

总而言之,仅仅因为您将 MyClass2 注入到一个注入了 Serilog(或任何其他依赖项)的类中,并不意味着 MyClass2 也可以使用这些依赖项。

您将不得不单独注入。

public interface IMyClass2

    void Process();


public class MyClass2 : IMyClass2

    private readonly ILogger<MyClass> _log;
    private readonly IConfiguration _config;

    public MyClass(ILogger<MyClass> log, IConfiguration config)
    
        _log = log;
        _config = config;
    

    public void Process()
    
        ...
    


public class MyClass : IMyClass

    ...
    private readonly IMyClass2 _myClass2;
    
    public MyClass(..., IMyClass2 myClass2)
    
        ...
        _myClass2 = myClass2
    

    public void MyMethod()
    
        var result = _myClass2.Process();
    


【讨论】:

【参考方案3】:

我认为您必须将您的类添加到 asp.net 服务,然后注入它而不是创建它的实例。第一步,如果您使用的是旧版本的 dotnet,请打开您的 Startup.cs 文件并添加:

builder.Services.AddScoped<IMyClass, MyClass>();

如果您使用的是较新版本,则应在 Program.cs 中添加此服务(启动和程序类在新版本的 dotnet 中合并)

在那之后,无论何时

public class Class 

    private readonly IMyClass _class;

    public Class(IMyClass myClass)
    
        _class = myClass;
    

你可以像这样在任何你想要的地方调用你的方法:_class.MyMethod();

【讨论】:

以上是关于嵌套类中的依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件

有啥方法可以将提供者依赖注入到 Flutter 中的普通类中?

抽象类中的依赖注入,ASP.NET Core

Spring依赖注入

PHP中的服务容器与依赖注入的思想

PHP中的服务容器与依赖注入的思想