我正在尝试使用带有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;
}
}
答案 0 :(得分:3)
由于循环依赖性,依赖注入框架无法解析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,可以使用IService
中的JobService
依赖项,但使用Named and Keyed Services提供不同的实现。