目前我正在尝试使用依赖注入容器,这次使用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/
答案 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,您可以使用某种表单工厂来构建表单对象。