繁体   English   中英

当我使用依赖注入时,如何设计通常是静态的类?

[英]How do I design a class that would normally be static when I'm using dependency injection?

我有一个类,其中封装了一堆字符串,这些字符串充当用户未明确指定的应用程序设置的默认值。

我目前正在使用带有相关命名实例方法的普通旧类-这种事情:

class SiteConfigurationConventions : ISiteConfigurationConventions
{
    public String GetConfigurationFileName()
    {
        return "SiteConfiguration.xml"; 
    }
}

似乎static类在概念上更合适(例如System.Math ),因为这些字符串在运行时不会更改,并且不需要任何字段,但是我不确定静态类与DI的兼容性如何。 例如,似乎无法在容器中注册静态类,因此它将静态类返回给构造函数,以在容器解析的其他对象中请求它。

现在,我注册

container.RegisterType<ISiteConfiguration, SiteConfiguration>();

这样,发出请求的构造函数即可获得所需的内容:

public SiteGenerator(ISiteConfiguration siteConfiguration)

我的设计选项似乎是:

  • 重构为静态类并在我的使用类中直接引用具体类型,而不是使用构造函数注入
  • 保持原样(将类和实例解析为接口),也许为了正确起见,可以选择使用单例生存期进行注册
  • 创建某种外观或工厂以隐藏静电。 但是,由于某种原因,这种选择使我感到愚蠢。

像这样的类的“实例”的概念似乎很奇怪-静态在概念上似乎更正确。 我将其设为可实例化类的唯一原因是使其对DI更友好。 听起来不错还是正确? 我完全想念什么吗?

任何律师将不胜感激。 :)

大多数DI库为您提供了一个选项,可以指定一个实例可以用于所有注入(创建一个实例,并每次给出答案)。 这是Singleton的一种形式,可能很适合您的问题。

例如,使用MS Unity库,您可以将:

container.RegisterInstance(new SiteConfiguration());

我认为static关键字是内置单例实现的一种形式,而DI路由执行的功能大致相同,但没有使用编译器来处理细节。

好吧,经过一些研究,谷歌搜索和思考,我相信我已经得出了自己的结论。

从某种意义上说,静态类的使用与IoC原理和我打算引入到体系结构中的松散耦合不符。 static修饰符是一种说法,只有一个实现可以满足特定目的,这通常与DI不一致(松散耦合,接口编程,可测试性以及随之而来的所有事情)。

同样,static修饰符实际上只是一种告诉编译器的方法,即我们希望将一个类的实例数限制为一个,同时绝不允许将其分配给变量(即,不使用new运算符)。 如果我们要使用IoC,我们应该将这种生活方式管理放到合成基础上,而且无论如何我们绝不​​直接引用具体类(除了FCL类)。 因此,静态类对我们无济于事。

因此,我说将其保留为普通的旧(非静态)类,并在构图的根本上应用单例生活方式。 当然,除非您认为自己将成为静态类的可能性很小,并且永远不需要在测试中伪造它,否则可以将其视为稳定的依赖项(例如FCL类),并且将其从常规DI方案中排除,直接在消耗类中引用具体类。

如果您必须依赖于使用静态方法的第三方类,或者您想作为依赖项注入的对象本身是完全静态的(从而可以代替测试等用途),则可能仍应创建一个接口并依赖于调用静态方法的可实例化适配器来获取这些值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM