如何在程序集中传递公共引用?

时间:2013-04-22 20:58:28

标签: c# oop design-patterns singleton static-classes

我试图在我的代码库中摆脱静态类,静态帮助器方法和单例类。目前,它们几乎遍布整个代码,特别是对于实用程序类和日志库。这主要是由于需要嘲弄能力以及面向对象的设计和开发问题,例如:可扩展性。我可能还需要在将来引入某种形式的依赖注入,并希望为此敞开大门。

基本上,我遇到的问题是关于传递常用引用的方法。这些是代码库中几乎每个类都使用的对象,例如日志记录接口,实用程序(帮助程序)类接口,也可能是类的实例,它保存大多数类所涉及的程序集的内部公共状态。

据我所知,有两种选择。一种是定义存储公共引用的类(或接口),如果愿意,则定义上下文,并将上下文传递给创建的每个对象。另一种选择是将每个公共引用几乎传递给每个类作为一个单独的参数,这将增加类构造函数的参数数量。

这些方法中哪一个更好,每个方法的优点和缺点是什么,是否有更好的方法来完成这项任务?

3 个答案:

答案 0 :(得分:1)

我通常使用上下文对象方法,并将上下文对象传递给对象的构造函数或方法 - 取决于哪一个最有意义。

上下文对象模式可以采用几种形式。

您可以定义具有所需成员的接口,也可以生成一种容器类。例如,在编写松散耦合的组件时,我倾向于让我实现的每个组件都具有匹​​配的接口,以便在需要时可以重新实现它。然后我在“管理器”对象上注册对象,如下所示:

public interface IServiceManager
{
    public T GetService<T>();
    public T RequireService<T>();
    public void RegisterService<T>(T service);
    public void UnregisterService<T>(T service);
}

在幕后有一个从一个类到另一个对象的地图,这使我可以非常快速地将大量不同的组件组合成一个工作的整体。每个组件都通过接口请求其他组件,而管理器对象将它们粘合在一起。 (如果您正确地编写了组件,您甚至可以在进程运行时将一个服务替换为另一个服务!)

人们可以按照以下方式注册服务:

class FooService : IFooService { }

// During process start-up:
serviceManager.RegisterService<IFooService>(new FooService());

由于字典查找,这种方法比平面接口方法有更多的开销,但它允许我构建非常复杂的系统,可以使用不同的服务实现轻松地重新部署。 (而且,像往常一样,我遇到的任何瓶颈都不是从字典中查找服务对象,而是在其他地方查找,例如数据库。)

答案 1 :(得分:1)

您将获得不同的意见,但通常将每个依赖项的单独参数传递给构造函数是首选,原因如下:

  • 它清楚地定义了一个类的实际依赖关系 - 使用“上下文”,你不知道在没有深入研究代码的情况下使用了上下文的哪些部分。
  • 一般来说,构造函数有很多参数是一种设计气味,所以使用构造函数注入可以帮助你嗅出设计缺陷。
  • 在测试时,您可以模拟个别依赖项,而不必模拟整个上下文

答案 2 :(得分:0)

我建议将参数传递给构造函数。这对于依赖注入和单元可测试性(模拟)都有很大的优势。