2014-10-27 79 views
0

我在基本級別上使用autofac來處理依賴注入。我此刻的配置很簡單:在WebAPI perRequest中按需使用Autofac的解析器來處理循環錯誤

builder.RegisterType<TestDbContext>().As<DbContext, TestDbContext>().InstancePerRequest(); 
builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerRequest(); 
builder.RegisterType<TestRepository>().As<ITestRepository>().InstancePerRequest(); 

我的問題是一種涉及到:'Autofac Circular Component Dependency Detected' Error

我不想讓Curcular組件相關的錯誤,所以我不包括IUserRepositoryITestRepository構造(它包含在其他方面)。

我想使用上述問題答案中的第二個建議。我如何編碼我的TestRepository按需使用UserRepository?我已經使用BeginLifetimeScope具有以下嘗試嘗試:

public class TestRepository : ITestRepository 
{ 
    public TestRepository() 
    { 
    } 

    public void Test() 
    { 
     using (var scope = AutofacConfig.Container.BeginLifetimeScope()) 
     { 
      var scopeUserRepo = scope.Resolve<IUserRepository>(); 
     } 
    } 
} 

,但我得到以下異常:

No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the 
instance was requested. This generally indicates that a component registered as 
per-HTTP request is being requested by a SingleInstance() component (or a similar 
scenario.) Under the web integration always request dependencies from the 
DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the 
container itself. 
+0

您也可以嘗試使用Autofac的函數功能的支持:所以在你的'公共TestRepository(Func鍵 userRepositoryCreator)'和你的'測試()'方法只寫:'var scopeUserRepo = userRepositoryCreator();' – nemesv 2014-10-27 13:01:17

+0

以及我有點想象我的設計模式必須是錯誤的,如果我有那些​​循環錯誤;)雖然有一個簡單的解決方案使用Lazy 但感謝您的建議 – 2014-10-27 13:06:00

回答

1

你不能只是開始的Web API一生範圍。請求生命週期隨請求消息一起提供。通過手動創建這樣的請求生命週期範圍,如果您有每個請求生存期依賴關係,您將無法得到所需的結果 - ,特別是,因爲您創建的範圍不會是相同的範圍作爲實際的請求生存期。你不會得到你應該得到的分享。

There is a detailed FAQ about troubleshooting per-request lifetime scope issues這應該有助於你的方式。您可能也有興趣the documentation on properly handling circular dependencies in Autofac

1

您可以使用ILifetimeScope在構造函數注入:

public class TestRepository : ITestRepository 
{ 
    private ILifetimeScope _scope; 

    public TestRepository(ILifetimeScope scope) 
    { 
     _scope = scope; 
    } 

    public void Test() 
    { 
     var scopeUserRepo = _scope.Resolve<IUserRepository>(); 
    } 
} 
+0

我知道,但我認爲這是最糟糕的情況。我可以在構造函數中使用Lazy ,它也可以工作,但這也不是最好的解決方案。 – 2014-10-28 11:43:36

+0

我只是重寫你以前的代碼,以避免autofac錯誤。我沒有說這是最好的解決方案。正確的解決方案應該是重構你的代碼設計,但是你不會在你的問題中提供它。 – hugoterelle 2014-10-28 11:47:53

+0

是的,我已經想通了,謝謝你的提示 – 2014-10-28 12:53:17