2012-06-04 48 views
3

我構建了一個四層系統,MVC3作爲主要前端,但包含由服務層異步運行並報告進度的長時間運行任務,MVV將使用Ajax顯示。我使用Autofac進行依賴注入(DI),主要是因爲界面和文檔很好,而且速度很快(請參閱Philip Mateescu在DI speed上的優秀研究)。Autofac - 混合InstancePerHttpRequest和異步作用域

我的問題是關於如何設置Autofac來處理注入項目的兩個範圍,即MVC3依賴性必須是PerHttpRequest,但異步任務依賴性需要是InstancePerLifetimeScope。

顯然,服務層將需要使用單獨的DI來解決長時間運行的任務的依賴關係。這樣做的最好方法是什麼?

+0

我不確定你問題的第二部分是非常清楚的。你能提供一些代碼片段或額外的說明嗎? –

+0

嗨特拉維斯,謝謝你看這個和抱歉,第二個問題有點含糊。我在其他地方找到了更多的信息,因此刪除了我的第二個問題,因爲它有點太複雜,無法在幾行中列出。我已經將原始信息留下了,因爲它可能對其他人有用。謝謝。 –

回答

7

更新 - 2014年6月

我已經更新了這個答案,因爲使用AutoFac最好的做法已經轉移,再加上MVC的變化。這個變化是,AutoFac中的最佳實踐是現在通過使用.InstancePerLifetimeScope()後綴來定義任何需要在訪問的整個生命週期中持續存在的實例,在MVC中爲HttpRequest。請參閱下面的例子:

builder.RegisterType<MyDbContext>().As<IMyDbContext>().InstancePerLifetimeScope(); 

做完,你不再需要指定要創建裏面的任務,新的壽命範圍的名稱(見原來的答覆,這已經被更新,下同)。

這裏有一些其他注意事項有關MVC任務,你可能會發現有用:

  • 如果您使用的是新的異步/等待那麼做並不需要一個新的生命週期範圍。 Aysnc/await保持當前上下文,並簡單地釋放線程以提高負載下Web的性能。
  • 如果你確實想在後臺運行某些東西,那麼請注意 - 有一些問題。我建議你從async的專家Stephen Cleary那裏讀到這個helpful blog post
  • 一個真正有用的組合是將SignalR與MVC結合使用來報告進度並允許用戶取消。這對我來說很好。

原帖,但更新(注:你必須註冊一生作用域實例如上圖所示)

我已經找到了如何處理異步任務與依賴雖然谷歌Autofac組。事實證明,您可以訪問MVC級容器,然後創建解決方案的新生命週期範圍。有很多方法可以做到這一點,但Alex Meyer-Gleaves(誰是專家)的answer提供了答案。 Alex建議下面的代碼用於運行具有不同範圍的任務。

public void Run<T>(Action<T> action) 
{ 
    Task.Factory.StartNew(delegate 
    { 
    using (var container = AutofacDependencyResolver.Current 
          .ApplicationContainer.BeginLifetimeScope()) 
    { 
     var service = container.Resolve<T>(); 
     action(service); 
    } 
    }); 
} 

有一個更詳細的博客文章here鏈接在亞歷克斯的帖子的主題,這也是非常有用的。

+0

請在這裏添加答案作爲答案,而不是編輯您的問題。這是堆棧溢出問題和答案格式的最佳方式。謝謝。 –

+0

感謝Jon Smith。您將不會碰巧在InstancePerLifetimeScope最佳實踐中使用MVC + Autofac進行鏈接。我看了[這裏](https://code.google.com/p/autofac/wiki/BestPractices),但沒有快樂...... –

+1

嗨@Johnny Reilly。它在Wiki中的「控制範圍和生命週期 - >實例範圍」下。 https://code.google.com/p/autofac/wiki/InstanceScope。希望有所幫助。 –