使用ServiceCollection的dotnet core 2.0控制台应用程序中的循环依赖

时间:2017-11-04 23:30:01

标签: c# .net-core

我正在尝试使用带有Dotnet核心2.0 Microsoft.Extensions.DependencyInjection nuget包的IServiceCollection来设置一个简单的依赖注入。我是新手,所以我从一个小实验开始:

public interface IService
{
}

public class JobService : IService
{
    public IService m_service { get; set; }
    public JobService(IService service)
    {
        m_service = service;
    }
}

class Program
{
    static void Main(string[] args)
    {
        IServiceCollection serviceCollection = new ServiceCollection();
        ConfigureService(serviceCollection);
        var serviceProvider = serviceCollection.BuildServiceProvider();
        //exception on next line
        var service = serviceProvider.GetService<App>();
        Console.WriteLine("Hello World!");
    }

    private static void ConfigureService(IServiceCollection serviceCollection)
    {
        serviceCollection.AddTransient<IService, JobService>();
        serviceCollection.AddTransient<App>();
    }
}

上面应该用容器注册所有类型,但在运行时,我得到:

  

System.InvalidOperationException:'检测到'TestCore.IService'类型服务的循环依赖关系。'

我的实现中没有看到循环依赖。有人能指出这种循环依赖来自何处?

至于服务,它应该注入我做的App类:

public class App
{
    private IService m_service;
    public App(IService service)
    {
        m_service = service;
    }
}

1 个答案:

答案 0 :(得分:3)

由于循环依赖性,依赖注入框架无法解析IService的依赖关系。 这是因为IServiceJobService)的实现本身依赖于IService(即自身)的实现。不可能实例化JobService,因为它依赖于自身。 DI框架识别出这一点并抛出您所看到的异常。 为了避免这种情况,您需要使JobService依赖于不同接口的实现:

public interface IService
{
}

public interface IAnotherService
{
}

public class JobService : IService
{
    public IAnotherService m_service { get; set; }
    public JobService(IAnotherService service)
    {
        m_service = service;
    }
}

public class AnotherService : IAnotherService
{
}

class Program
{
    static void Main(string[] args)
    {
        IServiceCollection serviceCollection = new ServiceCollection();
        ConfigureService(serviceCollection);
        var serviceProvider = serviceCollection.BuildServiceProvider();
        //exception on next line
        var service = serviceProvider.GetService<App>();
        Console.WriteLine("Hello World!");
    }

    private static void ConfigureService(IServiceCollection serviceCollection)
    {
        serviceCollection.AddTransient<IAnotherService, AnotherService>();
        serviceCollection.AddTransient<IService, JobService>();
        serviceCollection.AddTransient<App>();
    }
}

编辑/旁白:如果您使用的是Autofac,可以使用IService中的JobService依赖项,但使用Named and Keyed Services提供不同的实现。