c# - 了解 Ninject 的好处

标签 c# dependency-injection inversion-of-control ninject

我看过这个问题Still need help understanding why Ninject might be better than manual DI但我仍然对 Ninject 的用处感到困惑......

我明白这段代码...

class Samurai
{
    readonly IWeapon weapon;

    [Inject]
    public Samurai(IWeapon weapon)
    {
        this.weapon = weapon;
    }

    public void Attack(string target) 
    {
        this.weapon.Hit(target);
    }
}

... 将产生以下“(基本上)看起来像这样的动态方法:”

delegate(IWeapon weapon)
{
    return new Samurai(weapon);
}

这到底有什么用?没有 Ninject,我仍然可以这样做(根据 Ninject 文档“手动依赖注入(inject)”- 无 Ninject):

class Program
{
    public static void Main() 
    {
        var warrior1 = new Samurai(new Shuriken());
        var warrior2 = new Samurai(new Sword());
        warrior1.Attack("the evildoers");
        warrior2.Attack("the evildoers");
    }
}

使用 Ninject 为我提供了哪些我仅遵循松散耦合的基本原则无法做到的事情?感谢您帮助我理解。

最佳答案

Darin 的回答涵盖了使用 DI 框架的最重要的好处,但这里有一些我发现在使用 DI 容器时有用的东西。假设您有一个具有这些服务依赖项的对象:

public class Order : IOrder
{
    public Order(IOrderService orderSvc, ICustomerService custSvc)
    {
        // constructor logic
    }
}

您的代码可能如下所示:

var order = new Order(new OrderService(), new CustomerService()); // manual
or
var order = kernel.Resolve<IOrder>(); // using a DI container

这工作正常。现在,突然之间,您的要求发生了变化。订单现在需要送货服务:

public Order(IOrderService orderSvc, 
    ICustomerService custSvc, IShippingService svc)
{
    // constructor logic
}

假设您在整个程序中有 10 个不同的地方手动创建订单。如果您自己处理注入(inject),则必须在创建订单的代码中找到所有 10 个位置并修改它们。这样做 10 次可能需要大量工作!

var order = new Order(new OrderService(), new CustomerService(), new ShippingService());

但是,对于 DI 容器,一旦您注册了绑定(bind),您在所有这 10 个地方的代码如下所示:

var order = kernel.Resolve<IOrder>();

看看和以前一样吗?您无需更改任何内容!无论您添加 1 个还是 100 个依赖项,您解决订单的所有这 10 个地方都不会改变**。因此它可以帮助您避免在需要新的依赖项时修改现有代码。

** 情况并非总是如此,但这是一个简化的示例,用于展示没有人谈论太多的额外好处之一。

关于c# - 了解 Ninject 的好处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18773327/

相关文章:

c# - 调试混合的 Delphi( native )和 C# 代码,得到 "binary was built without debug information"

c# - 如何注册通用服务

design-patterns - 直接在方法代码中调用 DI 容器(MVC Actions)

inversion-of-control - 从 XML 文件加载 Unity 映射

rust - 尝试在 Rust 中进行控制反转时未实现 `Send`

c# - 服务定位器模式——如何处理同一服务接口(interface)的多个实现

c# - 一次性问题

C# 编译器数字文字

c# - mysql 权限错误。涉及SELECT命令

java - 框架中的应用程序特定注入(inject)