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

时间:2011-06-03 12:46:12

标签: asp.net-mvc dependency-injection refactoring inversion-of-control ninject

早上好!

昨天我观看了Tekpub的精彩视频"Dependency Injection and Inversion of Control",这让我大吃一惊。我觉得这就是我应该编写代码的方式。我之前看过它,甚至尝试了一下Ninject,但我觉得我需要更多的代码示例重构到这个范例中。

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

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

2 个答案:

答案 0 :(得分:5)

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

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

之前

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方法并从NinjectHttpApplication继承MvcApplication来注册您的服务。显然,使用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;
    }
}

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

答案 1 :(得分:4)

MVC StoreFront series涵盖了使用StructureMap的依赖注入。该项目在没有IoC的情况下开始,稍后在第13集中添加:ASP.NET MVC Storefront Part 13: Dependency Injection