依赖注入和其他构造函数参数——不好的做法
本文关键字:参数 注入 其他 构造函数 依赖 | 更新日期: 2023-09-27 18:12:20
目前我正在尝试使用依赖注入容器,这次是使用Unity。
给定以下接口:
public interface IPodcastCommService
{
void Download();
void Upload();
}
和以下实现:
public class PodcastService
{
private IPodcastCommService commservice;
private String url;
public PodcastService(String url, IPodcastCommService commservice)
{
this.commservice = commservice;
this.url = url;
}
}
由于构造函数的原因,我正在寻找将参数传递给它的解决方案,并找到了它:
var p = container.Resolve<IPodcastCommService>(new ParameterOverride("url", myUrl));
到目前为止还好,但同时我读到这有多糟糕,以及这个类的设计有多糟糕,是的,它看起来有点丑。但是如何以一种优雅的方式将参数传递给类呢?
我的第一个想法是把它作为一个属性,但后来我必须检查每次我需要它已经给出的Url。
更新:我读到的一个糟糕设计的例子是:
但是在某些情况下,您可能已经为resolve操作传入了自定义构造函数参数。有些人可能会认为这是糟糕的体系结构,但是在一些情况下,比如将di容器带到遗留系统中,可能需要这些操作。
来源:http://mikaelkoskinen.net/unity-passing-constructor-parameters-to-resolve/
我不明白为什么你需要与IPodcastCommService
组成的PodcastService,而不是实现IPodcastCommService
,并通过字符串注入url。我不明白你的设计为什么这么差。注url是很好的。
如果你想到一个更好的方法,我认为它可以通过注入上下文/配置而不是原生数据类型来代替。
public class PodcastService
{
private IPodcastCommService commservice;
private IConnectionContext connection;
public PodcastService(IConnectionContext connection, IPodcastCommService commservice)
{
this.commservice = commservice;
this.connection= connection;
}
}
public interface IConnectionContext{
string PodcastServiceUrl{get;}
}
但是,我没有发现常规方法有任何好处(除了你可以处理会话/常量/静态字段)。
更新:我在这里发现了关于糟糕设计的类似问题。总而言之,并不是本机类型参数(字符串等)或自定义构造函数参数不好。只是需要将参数放到真正负责参数的类中。如果在抽象工厂模式中处理if-else条件,则需要自定义构造函数参数。
在您的场景中,我认为通过构造函数进行DI是完全可以的。之所以认为通过属性来处理是一种更好的方法,是因为它对可读性更好,也就是说,想象一下如果你必须注入20个属性,你的构造函数会是什么样子。
如果你只打算注入几个属性,那么做你所做的绝对没有害处。如果你发现你的依赖项开始慢慢增加,我会考虑使用属性类型的方法。
可能是a
container.RegisterType<PodcastService>(new InjectionConstructor("myUrlParameter"));
会做得更好,不是吗?
但是如果你需要不止一个podcastservice,他们需要另一个url,我想parameteroverride是可以的
这取决于您正在使用的框架。例如,asp.net mvc为IoC容器(如dependdecyresolver)提供了集成点。您应该将用于构造对象和注入依赖的所有逻辑放在那里。如果你使用的是aps.net,你可能会有一些preinit事件注入依赖的基本页面。在asp.net中不能使用构造函数注入,只能使用属性注入。使用winforms,你可以使用某种形式的表单工厂来构建表单对象。