依赖注入和其他构造函数参数——不好的做法

本文关键字:参数 注入 其他 构造函数 依赖 | 更新日期: 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,你可以使用某种形式的表单工厂来构建表单对象。