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

发布于 2024-11-13 08:48:42 字数 332 浏览 4 评论 0原文

早上好!

昨天,我观看了 Tekpub 的精彩视频“依赖注入和控制反转”,它让我大吃一惊。我觉得这就是我应该如何编写代码。我之前看过它,甚至尝试过一些 Ninject,但感觉我需要更多的代码示例来重构到这个范例中。

他所涉及的简短的 MUD 示例很棒,但是有人知道有一个网站或项目吗?他们从一些丑陋但有效的代码开始,然后将其重构为干净的依赖注入代码?

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

Good morning!

Yesterday I watched Tekpub's amazing video "Dependency Injection and Inversion of Control" and it blew my mind. I feel like this is how I should be writing code. I have watched it before and even experimented with Ninject a little bit, but feel like I need some more examples of code being refactored into this paradigm.

The brief MUD example he goes into is great, but does anyone know of a site or project where they start with some ugly, but working, code and then refactor it into clean Dependency Injected code?

While I can find examples of code that use Dependency Injection pretty easily, I am having a hard time finding before/after code and I feel like this would greatly help me start programming "at the next level". I need a few more examples to really wrap my head around it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

信愁 2024-11-20 08:48:42

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

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

当然

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;
    }
}

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

Suppose you wanted to implement a spelling correction service. Input a word/phrase and out pops a corrected version of the word/phrase. What if you were depending on a large, online provider that went down for a day. Ideally, you would implement a backup in case the request to said provider failed. In that backup, you might call your secondary service and hope they're online. Maybe in a last ditch effort in the event they're both down, you implement an offline provider to correct spelling based on a local dictionary that exists on the file system.

How do you manage multiple providers like this?

Before

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

After

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;
    }
}

Of course, you'd need to implement the interface ISpellOnlineService (and similar interface for ISpellOfflineService

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

Next, implement your spelling providers (both online and offline, or even multiple instances of both to gain more flexibility)

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

Finally, register your services by overriding the CreateKernel method and subclassing your MvcApplication from NinjectHttpApplication. And apparently with Ninject you replace Application_Start with an override called OnApplicationStarted like so:

**This done in 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;
    }
}

Yes, this is a real world example, as I've implemented it (I actually used Castle Windsor, but it's the identical concept with Ninject--just adapted above) with 3 online providers and 2 offline providers. In CreateKernel you may choose to include logic to examine a database, config file, etc to determine which provider to register. For example, maybe one service has announced 24 hours of downtime (hopefully, you're lucky enough to have that announced!) so during that time you want to switch to another online provider for which you've implemented an instance of IOnlineSpellService

差↓一点笑了 2024-11-20 08:48:42

MVC StoreFront 系列涵盖了使用 StructureMap 的依赖注入。该项目开始时没有 IoC,并在第 13 集中添加了它: ASP.NET MVC Storefront 第 13 部分:依赖注入

The MVC StoreFront series covers dependency injection using StructureMap. The project starts off without IoC and adds it later on in episode #13: ASP.NET MVC Storefront Part 13: Dependency Injection

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文