我正在通过将模式划分为其核心方面并一一学习这些方面来自学 MVVM 模式。
我的问题与依赖注入有关。它是什么,为什么/何时应该使用它?我看过 Jason Dolinger 出色的 MVVM 介绍视频,我看到他使用 Unity。问这个问题可能很奇怪,但我如何在不使用 Unity 的情况下实现依赖注入?我基本上想了解依赖注入的概念以及如何使用它而无需实现其他框架/工具(目前)。
谢谢。
我正在通过将模式划分为其核心方面并一一学习这些方面来自学 MVVM 模式。
我的问题与依赖注入有关。它是什么,为什么/何时应该使用它?我看过 Jason Dolinger 出色的 MVVM 介绍视频,我看到他使用 Unity。问这个问题可能很奇怪,但我如何在不使用 Unity 的情况下实现依赖注入?我基本上想了解依赖注入的概念以及如何使用它而无需实现其他框架/工具(目前)。
谢谢。
我认为你想在不使用框架的情况下理解 DI 很好,这个概念并不难理解。
假设您想使用某种形式的交通工具。
interface ITransportation
{
Transport();
}
使用某种交通工具的方法的初始实现可能如下所示:
public void Move()
{
ITransportation car = new Car();
car.Transport();
}
该方法的问题在于它现在依赖于 Car 类。我们应该传递我们的运输对象以增加灵活性。这是控制反转,与 DI 密切相关。
public void Move(ITransportation tr)
{
tr.Transport();
}
如您所见,我们不需要了解任何关于特定 DI 框架的信息。您可能还想查看ninject DI 手动教程。
Just to extend @Andy's answer
Dependency Injection is one of the forms of the Dependency Inversion Principle
To achieve the decoupling of dependencies (as typically found in layered architecture), DI is commonly used for instantiation scenarios such as basic new() and patterns like Factory method. In addition to being able to inject a new dependency instance every time (e.g. like factory), containers can also be set up to inject named instances, singleton instances, etc - i.e. IoC containers usually also take on the responsibility of managing the lifespans of objects as well.
One potential 'mindset shift' is that dependencies now potentially become publicly visible on concrete classes, since DI typically injects via constructors or public Get / Set properties. This may seem strange if you are used to using OO encapsulation, where dependencies of a class are seen as implementation and should be hidden from the 'outside' i.e. class method signatures. However, by implementing Interface / Concrete class separation (as you should, not only for decoupling but also for testing / mocking purposes), the injection constructors / property injection methods will not be on the interface, so encapsulation is again in place.
Re : "Doing DI by hand" without Unity etc
What you would need to do is to code your own IoC container, which then is responsible for 'building up' instances of classes - during each 'build up', you would scan the class for dependencies (which are configured in the container, e.g. by config, by attributes, or simply just by convention, e.g. all public settable properties, or any class parameters on a constructor will be assumed to be dependencies). You would then create (if necessary) and inject this 'dependency' instance onto the object (e.g. by using reflection). And then recursively, all dependencies of these dependencies need to be built up etc. You would then also need to provide lifespan management for each of the objects, e.g. Singletons etc.