在.NET Core中的依赖项解析

3
我创建了一个示例来测试我对.NET Core上依赖解析的理解(特别是它们的顺序,如果有的话)。
这确实澄清了一些问题,但还有一个未解答的问题。
考虑以下工作服务模板代码:
Foo
public class Foo : IFoo
{
    private readonly IGoo Goo;

    public Foo(IGoo goo)
    {
        Goo = goo;
        Console.WriteLine($"Instance of [{this.GetType().Name}] being created...");
    }
}

public interface IFoo { }


public class Goo : IGoo
{
    private readonly IWoo Woo;
    public Goo(IWoo woo)
    {
        Woo = woo;
        Console.WriteLine($"Instance of [{this.GetType().Name}] being created...");
    }
}

public interface IGoo { }

Woo
public class Woo : IWoo
{
    IFoo Foo;
    public Woo(IFoo foo)
    {
        Foo = foo;
        Console.WriteLine($"Instance of [{this.GetType().Name}] being created...");
    }
}

public interface IWoo { }

工人服务
public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    //private readonly IFoo Foo;
    private readonly IGoo Goo;
    //private readonly IWoo Woo;

    public Worker(ILogger<Worker> logger, /*IFoo foo,*/ IGoo goo/*, IWoo woo*/)
    {
        _logger = logger;
        //Foo = foo;
        Goo = goo;
        //Woo = woo;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);
        }
    }
}

Program.cs


public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
                services.AddSingleton<IFoo, Foo>();
                services.AddSingleton<IGoo, Goo>();
                services.AddSingleton<IWoo, Woo>();
            });
}

起初,我想确保在ConfigureServices内部声明依赖关系的顺序并不重要。
然而,运行上述代码只会打印出Instance of [Goo] being created...
考虑到GooWoo的依赖项,并且已经解析出来,我本应该期望也会打印出Instance of [Woo] being created...
我本应该期望Woo也需要被解析,并且调用它的构造函数。但是这只发生在Goo上,而不是Woo上。
为什么会这样呢?
1个回答

2
因为内置的依赖注入不支持属性注入,所以Woo没有任何需要解析的内容。
public class Woo : IWoo
{
    IFoo Foo;
    public void WooM1(IFoo foo)
    {
        Foo = foo;
        Console.WriteLine($"Instance of [{this.GetType().Name}] being created...");
    }
}

docs中:
内置的服务容器旨在满足框架和大多数消费者应用程序的需求。我们建议使用内置容器,除非您需要它不支持的特定功能,例如:
- 属性注入 - ...
如果您添加了构造函数:
IFoo Foo;

public Woo(IFoo foo)
{
    Foo = foo;
}

然后,如预期那样,您将收到循环依赖异常:
生命周期:Singleton 实现类型:TestWorker.Worker':检测到类型为 'TestWorker.IGoo' 的服务存在循环依赖。

啊...我在第一个示例版本中错误地没有给Woo提供ctor(它有一个实现接口的方法,每个接口都有一个需要实现的方法)。 - Veverke
1
是的,我之前也考虑到了循环依赖的问题。现在我明白了,将Woo不依赖任何其他模块,会尝试先解决Goo,然后再解决Woo(按照这个顺序),这正是我期望的行为。这就是我想要看到的:/ - Veverke
1
是的,我之前尝试过几次,也考虑到了循环依赖的问题。现在我明白了,将Woo保持没有任何依赖会尝试先解决Goo,然后再解决Woo(按照这个顺序),这正是我期望的行为。这就是我想要看到的:/ - Veverke
1
是的,我之前的尝试/操作中也考虑到了循环依赖的问题。现在我明白了,将Woo不依赖任何其他内容,会尝试先解决Goo,然后是Woo(按照这个顺序),这正是我期望的行为。这就是我想要看到的:/ - undefined
谢谢你为我解决问题,让我的道路变得清晰 :-) - Veverke
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接