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);
}到目前为止,一切都很好。
有人告诉我,这更像是一种服务定位器模式,违反了依赖注入模式,我想知道这里违反了什么。
发布于 2010-09-04 22:27:12
对我来说,关于wikipedia,您的代码中并没有违反DI
将行为与依赖项解析分离的
核心原则
但是不好的一面是你的控制器有太多的知识,在某些情况下(如果你不仔细编程)你可能会违反Law Of Demeter
看看你的代码:
public ActionResult Index()
{
var userTasks = TaskProvider.GetTask<IUserTasks>();
var user = userTasks.FindbyId(guid);
}发布于 2010-09-04 21:45:16
如果控制器需要一个IUserTasks实例,那么如果它直接从容器接收一个实例会更简单。从本质上讲,TaskProvider只是容器的包装器,因为它是从容器中获取UserTasks和IdentityTasks实例的。
发布于 2010-09-04 22:00:07
您正在使用依赖注入将有效的“服务定位器”注入控制器,而不是注入IUserTasks和IIdentityTasks的实现。
您的实际控制器实际上依赖于IUserTasks和IIdentityTasks,但是您并没有直接将它们注入到控制器中,而是决定使用“服务定位器”或任务提供者,因此您注入了对服务定位器的依赖,在本例中,它似乎没有提供任何无法通过直接注入真正的依赖来完成的功能。
https://stackoverflow.com/questions/3642438
复制相似问题