15

目前我正在尝试使用依赖注入容器,这次是使用 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

4 回答 4

3

我不明白为什么你需要 PodcastService 的组合IPodcastCommService,而不是实现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;}
}

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

更新:

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

于 2013-05-06T08:58:27.110 回答
1

在您的情况下,我认为通过构造函数进行 DI 非常好。它被认为是通过属性的更好方法的原因是因为它更好的可读性,即想象如果您必须注入 20 个属性,您的构造函数会是什么样子。

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

于 2013-05-06T08:59:17.557 回答
1

也许一个

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

会做得更好,不是吗?

但是如果您需要多个播客服务并且他们需要另一个 url,我猜 parameteroverride 是可以的。

于 2013-05-06T18:18:01.370 回答
-3

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

于 2013-05-06T08:51:14.527 回答