問題緣由
最近在寫 .NET Core 的時候遇到了一個問題
1 |
A circular dependency was detected for the service of type 'WebApplication1.Service.A1Service' |
A1Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class A1Service { private readonly string guid = null; private readonly A2Service _a2Service = null; public A1Service(A2Service a2Service) { _a2Service = a2Service; if (guid == null) { guid = Guid.NewGuid().ToString(); } } public void Run() { Console.WriteLine("A1Service: " + guid); } public void RunOther() { _a2Service.Run(); } } |
這是網路教學文章上常見的從建構子中依賴注入 A2Service
的程式
接著我們再來看看另外一支程式
A2Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class A2Service { private readonly string guid = null; private readonly A1Service _a1Service = null; public A2Service(A1Service a1Service) { _a1Service = a1Service; if (guid == null) { guid = Guid.NewGuid().ToString(); } } public void Run() { Console.WriteLine("A2Service: " + guid); } public void RunOther() { _a1Service.Run(); } } |
這裡就發生了一個循環依賴的問題 A1Service
在建構子中注入了 A2Service
,而 A2Service
也在建構子中注入了 A1Service
,造成兩個物件互相依賴造成 Exception
解決方法
改成不直接在建構子中注入 Service ,改注入 IServiceProvider
,再利用 GetService
這個方法來取得物件,這樣就可以順利解決這個問題囉。
A3Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class A3Service { private readonly string guid = null; private readonly IServiceProvider _serviceProvider = null; public A3Service(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; if (guid == null) { guid = Guid.NewGuid().ToString(); } } public void Run() { Console.WriteLine("A3Service: " + guid); } public void RunOther() { _serviceProvider.GetService<A4Service>().Run(); } } |
A4Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class A4Service { private readonly string guid = null; private readonly IServiceProvider _serviceProvider = null; public A4Service(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; if (guid == null) { guid = Guid.NewGuid().ToString(); } } public void Run() { Console.WriteLine("A4Service: " + guid); } public void RunOther() { _serviceProvider.GetService<A3Service>().Run(); } } |