Asp.net-Mvc

使用 Ninject 為依賴注入重構 ASP.NET MVC 程式碼的真實範例

  • June 3, 2011

早上好!

昨天我看了 Tekpub 的精彩影片“依賴注入和控制反轉”,這讓我大吃一驚。我覺得這就是我應該編寫程式碼的方式。我以前看過它,甚至對 Ninject 進行了一些試驗,但我覺得我需要更多的程式碼範例來重構這個範式。

他介紹的簡短 MUD 範例很棒,但是有沒有人知道他們從一些醜陋但有效的程式碼開始的站點或項目,然後將其重構為乾淨的依賴注入程式碼?

雖然我可以很容易地找到使用依賴注入的程式碼範例,但我很難找到程式碼之前/之後的程式碼,我覺得這將極大地幫助我“在下一個級別”開始程式。我需要更多的例子來真正理解它。

假設您想實現拼寫更正服務。輸入一個單詞/片語並彈出該單詞/片語的更正版本。如果您依賴一個停工一天的大型線上提供商怎麼辦。理想情況下,如果對所述提供者的請求失敗,您將實施備份。在該備份中,您可能會呼叫輔助服務並希望它們線上。也許在他們都出現故障的情況下最後的努力中,您實現了一個離線提供程序,以根據文件系統上存在的本地字典來糾正拼寫。

您如何管理這樣的多個提供商?

public class SpellCheck
{
   public string FixText(string text)
   {
       string CorrectedText = string.Empty;
       // create HTTP request to Online Provider #1
       // return CorrectedText;
   }
}

public class SpellCheck
{
   private readonly IOnlineSpellService _onlineSpell;
   private readonly IOfflineSpellService _offlineSpell;

   public SpellCheck(IOnlineSpellService onlineSpell, 
       IOfflineSpellService offlineSpell)
   {
       this._onlineSpell = onlineSpell;
       this._offlineSpell = offlineSpell;
   }

   // same method as before, just a slightly different implementation
   public string FixText(string text)
   {
       string fixedText = _onlineSpell.FixText(text);
       if(_onlineSpell.Failed)
           fixedText = _offlineSpell.FixText(text);

       return fixedText;
   }
}

當然,您需要實現介面ISpellOnlineService(以及類似的介面)ISpellOfflineService

public interface ISpellOnlineService
{
   public bool Failed { get; set; }
   public string FixText(string text);
}

接下來,實施您的拼寫提供程序(線上和離線,甚至兩者的多個實例以獲得更大的靈活性

public class OnlineProviderNo1 : IOnlineSpellService
{
   public string FixText(string text)
   {
       // implement online logic
       this.Failed = false;
   }
}

最後,通過覆蓋CreateKernel方法和子類化您的 MvcApplication 來註冊您的服務NinjectHttpApplication。顯然,使用 Ninject 替換Application_StartOnApplicationStarted這樣的覆蓋:

**這在 global.asax 中完成

public class MvcApplication : NinjectHttpApplication
{
   // ...

   protected override void OnApplicationStarted()
   {
       base.OnApplicationStarted();

       AreaRegistration.RegisterAllAreas();
       RegisterGlobalFilters(GlobalFilters.Filters);
       RegisterRoutes(RouteTable.Routes);
   }

   protected override IKernel CreateKernel()
   {
       var kernel = new StandardKernel();
       kernel.Bind<IOnlineSpellService>().To<OnlineProviderNo1>();
       kernel.Bind<IOfflineSpellService>().To<OfflineProviderNoX>();

       return kernel;
   }
}

是的,這是一個真實的範例,因為我已經實現了它(我實際上使用了 Castle Windsor,但它與 Ninject 的概念相同——只是在上面進行了改編),其中包含 3 個線上提供商和 2 個離線提供商。CreateKernel您可以選擇包含邏輯來檢查數據庫、配置文件等以確定要註冊的提供程序。例如,也許一項服務宣布了 24 小時的停機時間(希望你很幸運能夠宣布這一點!),所以在此期間你想切換到另一個你已經為其實現了一個實例的線上提供商IOnlineSpellService

引用自:https://stackoverflow.com/questions/6227259