8

我有一些全局组件,我不确定如何将它们放入设计中。如:

  • Settings 类:它是接口程序的初始设置,它可以是后台的 app.config(1way)、web.config(1way)、硬编码值(1way) 或 sqldb(2way)。

  • 语言类:它包含不同的语言集,我可以在它后面有一些 resx 文件(1way)、硬编码值(1way)或 sqldb(2way)。

第一个问题是,我是否应该在依赖注入中设置这些类的属性(我使用 Windsor):

public ISettings Settings {set;}
public ILanguage Language {set;}

或者我应该让它们成为环境上下文:

string DoSomethingAndReportIt() {
    //do something ...
    var param = Settings.Current.SomeParam;
    //report it ...
    return Language.Current.SomeClass_SomeMethod_Job_Done;
}

我注意到 .net 库中有一些组件实际上使用环境上下文模式,例如 System.Security.Principal、System.Web.ProfileBase、System.Thread.CurrentCulture ...

您认为将我的全局类(例如 Settings 和 Language)设置为环境上下文类没有害处吗?如果不是,为什么首选 DI?与环境相比,它们在单元测试中是否更具优势?

第二个问题是,如果 DI 更好,(我感觉首选 DI 模式),代理现有环境类(如 Security.Principal 或 Profile)遵循 DI 模式的好方法是什么?

4

1 回答 1

3

当您需要实现跨多个层的功能时,环境上下文是可以的。(在您的情况下,您说这两个对象是全局的)此功能称为横切关注点。正如您注意到 .NET 中的许多类都实现为环境上下文,例如IPrincipal. 为了获得环境上下文实现的工作版本,如果它们被开发为环境上下文,您将需要为您的Settings和对象提供一些默认值。Language我的假设是您将提供一些默认实现ILanguageand ISettings,并且考虑到您将在全局范围内使用它们,它们是环境上下文的良好候选者。

另一方面,您打算多久使用那些实现这两个接口的对象?而且,这两个对象的存在是否至关重要,意义Settings != nullLanguage != null?如果你真的打算在一两个类中使用它们,和/或如果对象的存在不是很重要,你可能想要使用setter injection。setter 注入实际上并不需要默认值,因此您的对象可以是null.

就我个人而言,我不是环境上下文的粉丝。但是,如果事实证明它是最可接受的解决方案,我会使用它。如果你的实现我会做这样的事情:因为你只需要在一个位置初始化实现两个接口的对象,你可以从环境上下文开始。如果您意识到您在极少数位置使用它,请考虑将其重构为 setter 注入。如果对象的存在很重要,请考虑构造函数注入实现。

于 2012-07-26T13:32:12.180 回答