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

时间:2013-05-06 08:37:52

标签: c# dependency-injection

目前我正在尝试使用依赖注入容器,这次使用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时我必须检查。

更新 一个例子,我读到这是一个糟糕的设计,是这样的:

  

但是在某些情况下,您可以为解析操作传递自定义构造函数参数。有些人可能会说这种糟糕的体系结构的尖叫声,但是有一种情况,比如将DI容器带到遗留系统,可能需要这些操作。

来源:http://mikaelkoskinen.net/unity-passing-constructor-parameters-to-resolve/

4 个答案:

答案 0 :(得分:3)

我不明白为什么你需要组成为IPodcastCommService的PodcastService,而不是实现IPodcastCommService并且有字符串注入的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;}
}

但同样,我没有从常规方法中找到任何好处(除了你可以处理会话/常量/静态字段)。

更新:

我发现了关于糟糕设计here的类似问题。总之,本机类型参数(字符串等)或自定义构造函数参数不是坏的。只需要将参数放到真正负责参数的类中即可。如果在抽象工厂模式中处理if-else条件,则需要自定义构造函数参数。

答案 1 :(得分:1)

在你的场景中,我认为通过构造函数的DI非常好。它被认为是一种更好的方法来通过属性是因为它更好的可读性,即想象如果你必须注入20个属性你的构造函数会是什么样的。

如果你只打算注射一些属性,那么你做的事情绝对没有害处。如果你发现你的依赖关系开始蔓延,我会考虑转向属性类型的方法。

答案 2 :(得分:1)

也许是

container.RegisterType<PodcastService>(new InjectionConstructor("myUrlParameter"));

会做得更好,不是吗?

但是如果你需要一个以上的podcastservice并且他们需要另一个url,那么我认为参数覆盖是可以的。

答案 3 :(得分:-3)

这取决于你使用的框架。例如asp.net mvc提供程序集成点,用于IoC容器,如DependecyResolver。您应该放置所有逻辑来构造对象并在那里注入依赖项。如果你使用的是aps.net,你可能会有一些preinit eevnt注入依赖关系的基页。你不能在asp.net中使用构造函数注入,只能使用属性注入。使用winforms,您可以使用某种表单工厂来构建表单对象。