我看过这个问题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/