有关可扩展性和可测试性的(分层)库中有关StructureMap的问题

时间:2010-10-18 17:27:27

标签: c# .net-3.5 structuremap

我们在创建分层库时使用StructureMap作为依赖注入(DI)框架。我们的目标是:

  • 在我们开发和维护库时,让我们轻松完成单元测试类(并使用模拟类而不是真正的依赖项)。
  • 让图书馆用户轻松:
    • 通过实现自己的接口并配置库以使用它们的实现而不是我们自己的实现来自定义库行为。
    • 单元测试他们实现的类(这与我们内部的目标相同,但我们希望它也能够为库用户实现)。

通过分层库,我们意味着我们正在构建两个DLL:

  1. 核心库。它应该可以在任何.NET应用程序中使用,无论是控制台应用程序还是MVC应用程序。
  2. WebForms库。它包括核心库,但也提供WebForms Control,以使WebForms用户的生活更轻松。
  3. 我们的问题:

    1. 我们应该在哪里调用代码来将接口映射到核心库的具体类?它没有单一的入口点,有许多类可以先实例化。

      目前,我们强制用户在进行任何其他库调用之前调用DependencyHandler.Init()。有没有更好的方法,比如加载DLL后执行的一段代码,这样我们就不会强迫用户写一行样板代码?

    2. 让库用户将接口实现更改为自己的类型的推荐方法是什么?目前,用户可以通过StructureMap.Configuration.DSL.Registry theRegistry = DependencyHandler.Instance().GetConfiguration()检索注册表,然后通过例如theRegistry.For<IFoo>().Use<MyOwnFooImplementation>();进行更改。使用XML会更好吗?如果是这样,我们应该把XML放在哪里?我们选择程序化方法,因为Visual Studio将能够为用户提供一些帮助。

    3. 如果使用上面 2 中的当前方法,则需要库用户(至少现在)添加对StructureMap.DLL的引用以及我们的DLL。我们可以从用户那里消除这种负担,也许可以通过使用XML来进行依赖设置吗?

    4. 我们应该使用WebForms中的一个很好的中心位置,它解决了WebForms库DLL的问题 1 吗?

    5. 您如何建议我们为生产和测试构建结构?

      目前的想法是在所有必要的地方使用DI来启用我们和我们的用户想要的单元测试,以及让用户通过提供他们自己的实现来改变库行为。

      为了测试,我们和库用户必须创建模拟类来替换我们想要脱离的依赖项。我们的想法是使用正常配置但是覆盖我们想要模拟的类而不是使用它们的正常实现。这是一个很好的方法吗?

1 个答案:

答案 0 :(得分:2)

重要的是要注意,为了提供其他人可以隔离其代码的API,您需要确保它们可以依赖于抽象而不是具体实现。也就是说,只要你公开的那些“做东西”的类要么实现一个接口(通常是最好的),要从定义接口的抽象类继承,或者将所有公共成员都作为虚拟(通常是最差的)我继承,作为API的使用者,能够将我的代码与具体实现隔离开来。 换句话说,在其中使用IoC容器并不是提供可测试API的关键。但是使你的类非静态并且作为抽象的实现是。 使用容器有许多其他好处。例如,您可能会更容易地自己测试API中的各个类:)

  1. 没有单一的入口点,但要使用你的API我会实例化一个或几个类吗?这些类中的每一个都可以具有构造函数,这些构造函数要求客户端提供类所依赖的抽象的具体实现。为了避免强制客户端指定要使用的实现,您还可以提供使用默认实现的无参数构造函数。

  2. 这取决于你,但从你的方法到简单的DSL,将API连接到配置文件的任何事情都可以。总的来说,正如我之前所说,客户可能不会对更改类依赖的实现感兴趣,只要他们自己可以将自己的代码与“顶级”类隔离开来。

  3. 应用程序启动可能是一个很好的地方。 Web窗体库可以是HttpModule,也可以提供默认启动捆绑,并指示客户端在global.asax中的应用程序启动事件中进行所需的任何更改。

  4. 听起来不错。就像我之前说的那样,我认为最重要的是你的类和它们的方法不是静态的(最好不是单例),它们的接口是以抽象的方式定义的,因此人们可以使用其他具体的实现进行测试

  5. 我可能误解了一些事情,但我希望我的答案可能至少有一点帮助:)