我正在尝试使用DotNetCore2.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;
}
}发布于 2017-11-04 23:41:16
由于循环依赖,依赖注入框架无法解决IService的依赖关系。这是因为IService (JobService)的实现本身依赖于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 --您可以使用在JobService中保留IService依赖项,但是使用命名和键控服务提供不同的实现。
https://stackoverflow.com/questions/47116673
复制相似问题