使用Ninject为依赖注入重构的ASP.NET MVC代码的真实示例

bul*_*ous 12 asp.net-mvc refactoring dependency-injection ninject inversion-of-control

早上好!

昨天我看了Tekpub的惊人视频"依赖注入和控制反转",这让我大吃一惊.我觉得这就是我应该编写代码的方式.我之前看过它,甚至对Ninject进行了一些实验,但我觉得我需要更多的代码示例重构到这个范例中.

他进入的简短MUD示例很棒,但有没有人知道一个站点或项目,他们从一些丑陋但工作的代码开始,然后将其重构为干净的Dependency Injected代码?

虽然我可以很容易地找到使用依赖注入的代码示例,但我很难在代码之前/之后找到它,我觉得这将极大地帮助我开始"在下一级"编程.我需要更多的例子来真正地围绕它.

Dav*_*Fox 5

假设您想要实施拼写更正服务.输入单词/短语,然后弹出单词/短语的更正版本.如果您依赖于一天内停电的大型在线提供商,该怎么办?理想情况下,如果对所述提供程序的请求失败,您将实现备份.在该备份中,您可以致电您的辅助服务并希望他们在线.也许在他们都失败的最后努力中,你实现了一个离线提供程序来根据文件系统上存在的本地字典来纠正拼写.

你如何管理这样的多个提供商?

之前

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您需要实现接口ISpellOnlineService(以及类似的接口)ISpellOfflineService

public interface ISpellOnlineService
{
    public bool Failed { get; set; }
    public string FixText(string text);
}
Run Code Online (Sandbox Code Playgroud)

接下来,实现拼写提供程序(在线和离线,甚至两者的多个实例以获得更大的灵活性)

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

最后,通过重写CreateKernel方法并从中继承MvcApplication来注册您的服务NinjectHttpApplication.显然,使用Ninject,你可以替换Application_Start为这样的覆盖OnApplicationStarted:

**这是在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

是的,这是一个真实世界的例子,因为我已经实现了它(我实际上使用了Castle Windsor,但它与Ninject完全相同 - 只是在上面进行了调整),有3个在线提供商和2个离线提供商.在CreateKernel您可以选择包括逻辑检查数据库,配置文件等,以确定要注册的供应商.例如,也许有一项服务宣布了24小时的停机时间(希望你很幸运能够宣布这一点!)所以在那段时间你想切换到另一个你已经实现了实例的在线提供商.IOnlineSpellService