服务定位器和依赖注入之间的实际区别是什么?

时间:2012-08-28 13:03:28

标签: dependency-injection inversion-of-control service-locator

我正在进行前面的讨论,其中详细讨论了服务定位器和依赖注入器之间的区别,但我仍然无法得到它。 我可以在没有任何代码的情况下得到一般回复吗?

2 个答案:

答案 0 :(得分:2)

此代码示例应用Dependency Injection原则:

public class UserService : IUserService
{
    private IUserRepository repository;

    // Constructor taking dependencies
    public UserService(IUserRepository repository)
    {
        this.repository = repository;
    }
}

此代码示例使用Service Locator模式:

public class UserService : IUserService
{
    private IUserRepository repository;

    public UserService()
    {
        this.repository = ObjectFactory.GetInstance<IUserRepository>();
    }
}

这是服务定位器模式的实现:

public class UserService : IUserService
{
    private IUserRepository repository;

    public UserService(Container container)
    {
        this.repository = container.GetInstance<IUserRepository>();
    }
}

甚至这是服务定位器模式的实现:

public class UserService : IUserService
{
    private IUserRepository repository;

    public UserService(IServiceLocator locator)
    {
        this.repository = locator.GetInstance<IUserRepository>();
    }
}

不同之处在于,使用依赖注入,您可以将消费者需要的所有依赖项注入到使用者中(但没有其他内容)。注入它的理想方法是通过构造函数。

使用Service Locator,您可以从某个共享源请求依赖项。在第一个示例中,这是静态ObjectFactory类,而在第二个示例中,这是注入构造函数的Container实例。最后一个代码片段仍然是Service Locator模式的一个实现,尽管容器本身是使用依赖注入注入的。

您应该使用依赖注入而非服务定位器的重要原因。 This article does a good job explaining it

答案 1 :(得分:0)

如果使用服务定位器,通常意味着您明确要求某个对象为您创建另一个对象,这通常被视为反模式。 反向注入是另一种方式。

假设你有一个名为Warrior的类,它有一个武器。 使用服务定位器,您可以在Warrior的构造函数中向服务定位器询问武器 使用依赖注入,武器会被注入到Warrior的构造函数中,而不会明确地要求它。