【问题标题】:Dependency Injection依赖注入
【发布时间】:2011-04-08 05:34:02
【问题描述】:
public interface ITaskProvider
{
    T GetTask<T>();
}

在下面的 ITaskprovider 的实现中,如您所见的 IUserTask 和 IIdentityTask 是从属性而不是构造函数注入的。 原因是Windsor会自动实例化注入的属性 在运行时访问,这样我就不必放置所有必须注入的依赖项 在构造函数中。

public class TaskProvider : ITaskProvider
    {
        public IUserTasks UserTasks { get; set; }

        public IIdentityTasks IdentityTasks { get; set; }

        public T GetTask<T>()
        {
            Type type = typeof(T);
            if (type == typeof(IUserTasks)) return (T)this.UserTasks;
            if (type == typeof(IIdentityTasks)) return (T)this.IdentityTasks;

            return default(T);
        }
    }

在控制器中,我将 ITaskProvider 注入到构造函数中。

public ITaskProvider TaskProvider { get; set; }

public AuctionsController(ITaskProvider taskProvider)
        {
            TaskProvider = taskProvider;
        }

在这里我调用了 taskprovider 及其方法。

public ActionResult Index()
{
 var userTasks = TaskProvider.GetTask<IUserTasks>();
 var user = userTasks.FindbyId(guid);

}

到这里为止,一切正常。

有人告诉我,这更像是服务定位器模式,违反了依赖注入模式,我想知道这里违反了什么。

【问题讨论】:

    标签: c# dependency-injection


    【解决方案1】:

    您应该将 IUserTask 和 IIdentityTask 注入到控制器的构造函数中,因为使用 TaskProvider 没有任何好处。除此之外,以您的方式,您会错过一些编译时检查。例如,您可以调用 TaskProvider.GetTask() 并等待在运行时爆炸。至少,您应该对该泛型参数施加一些限制(如果两个接口都可以从共同父级继承)。

    关于“违规”,您应该注意您没有将依赖项注入控制器。您正在提供一种检索它们的方法。

    【讨论】:

      【解决方案2】:

      对我来说,关于wikipedia,您的代码中没有违反DI:

      将行为与依赖解析分开的核心原则

      但不好的一面是你的控制器知识太多,在某些情况下(如果你不仔细编程)你可能会违反Law Of Demeter

      看看你的代码:

      public ActionResult Index()
      {
       var userTasks = TaskProvider.GetTask<IUserTasks>();
       var user = userTasks.FindbyId(guid);
      }
      

      【讨论】:

      • 感谢这些有用的东西。
      【解决方案3】:

      您正在使用依赖注入将有效的“服务定位器”注入控制器,而不是注入 IUserTasks 和 IIdentityTasks 的实现。

      您的实际控制器确实对 IUserTasks 和 IIdentityTasks 有依赖关系,但您并没有直接将它们注入您的控制器,而是决定使用“服务定位器”或任务提供程序,因此您已经注入了对服务定位器的依赖关系,在示例中通过直接注入真正的依赖项似乎无法提供任何东西。

      【讨论】:

        【解决方案4】:

        如果控制器需要一个IUserTasks 实例,那么如果它直接从容器接收一个实例会更简单。本质上,TaskProvider 只是容器周围的包装器,因为它是从中获取 UserTasksIdentityTasks 实例的地方。

        【讨论】:

        • 是的,这只是一个包装器。是不是还是违反了依赖注入模式?
        • @Murat - 如果将其注入其依赖项中,这并不是真正的违规,它只是没有提供任何价值。
        猜你喜欢
        • 1970-01-01
        • 2014-06-12
        • 2013-04-30
        • 2021-11-19
        • 1970-01-01
        • 2020-12-20
        • 2021-05-31
        相关资源
        最近更新 更多