c# – 仍然需要帮助理解为什么Ninject可能比手动DI更好

前端之家收集整理的这篇文章主要介绍了c# – 仍然需要帮助理解为什么Ninject可能比手动DI更好前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是问题 Why do I need an IoC container as opposed to straightforward DI code?的扩展

我一直在学习Ninject,并提出了以下示例,该示例通过手动方式进行DI和Ninject做DI的方式:

class Program
{
    static void Main(string[] args)
    {
        NinjectWay();
        ManualWay();
        Console.ReadKey();
    }

    private static void ManualWay()
    {
        Console.WriteLine("ManualWay***********************");
        IWeapon sword = new Sword();
        Samurai samurai = new Samurai(sword);

        Console.WriteLine(samurai.Attack("ManualWay..."));

        // change weapon
        IWeapon dagger = new Dagger();
        samurai.Weapon = dagger;

        Console.WriteLine(samurai.Attack("ManualWay..."));

        IWeapon weapon = new Shuriken();
        IWarrior ninja = new Ninja(weapon);
        Console.WriteLine("Manual way.. inject shuriken when a ninja. " + ninja.Weapon.Name);

        IWarrior ninja2 = new Ninja(weapon);
    }

    private static void NinjectWay()
    {
        Console.WriteLine("NinjectWay***********************");
        IKernel kernel = new StandardKernel();
        kernel.Bind<IWeapon>().To<Sword>();
        var samurai = kernel.Get<Samurai>();

        Console.WriteLine(samurai.Attack("NinjectWay..."));

        kernel.Rebind<IWeapon>().To<Dagger>();
        samurai = kernel.Get<Samurai>();

        Console.WriteLine(samurai.Attack("NinjectWay..."));

        kernel.Bind<IWeapon>().To<Shuriken>().WhenInjectedInto<Ninja>();
        var ninja = kernel.Get<Ninja>();
        ninja.OffHandWeapon = new ShortSword();

        Console.WriteLine("Conditional Injection..."+ninja.Weapon.Name);
        Console.WriteLine("Conditional Injection: OffhandWeapon = " + ninja.OffHandWeapon.Name);

        var ninja2 = kernel.Get<Ninja>();
        Console.WriteLine("Conditional Injection..." + ninja2.Weapon.Name);
        Console.WriteLine("Conditional Injection: OffhandWeapon = " + ninja2.OffHandWeapon.Name);

        Console.WriteLine("");
    }
}

我听说当项目规模增加时会带来好处,但我没有看到它.帮助我更好地理解这一点.在C#/ Ninject中提供更多示例,帮助我了解真正显而易见的好处.

解决方法

与其他答案不同,Ninject主要不是让您的代码更易于测试.它的依赖注入使您的代码更易于测试!通过在facotries中创建所有内容,可以在没有IoC容器的情况下使用依赖注入.但可以肯定的是,能够轻松更换某些部件进行集成测试(不要在单元测试中使用Ninject)是一个很好的副作用.

像Ninject这样的IoC容器主要是将您的类集成到一个可用的软件中.在小型项目中,这可以通过一些工厂轻松完成.但随着应用程序的增长,工厂变得越来越复杂.想象一下,有一个应用程序有各种服务,其中一些是重用的,其他的是为每种用法新创建的.一些服务也被几个组件使用.

如果您使用的是IoC容器,则必须准确定义一次如何获取服务实例以及它的生命周期.另一方面,在工厂中,您必须指定如何为每个需要实例的类获取实例(例如,新的MyServiceFactory().CreateInstance()).此外,您必须手动控制生命周期.

这意味着随着项目的增长,IoC容器的配置与项目大小一起呈线性增长.但另一方面,工厂变得更加指数化,就像在整个应用程序中使用的服务(例如用户身份验证)一样.

顺便说一句:你的例子并不是很好,因为重新绑定不是一个常见的行动.通常,配置仅在应用程序启动时完成一次.

猜你在找的C#相关文章