Castle Windsor(或任何 IoC 框架)和内部依赖项

Castle Windsor (or any IoC framework) and internal dependencies

我在使用内部类型的依赖注入时遇到了一些问题。虽然我已经使用 Castle Windsor 几年了,但我从来没有真正需要过多地考虑可见性,所以通常一切最终都是 public (部分是为了让 Windsor 开心,部分是为了更容易模拟在单元测试中)。但是我现在有一个要求设计一个API.

我知道以下示例不是很好,但旨在说明公开具有不应该 public 可访问的依赖项的类型的场景。

假设我的 API 层公开了一个 GetCustomer() 方法。此 returns 一个客户 class 公开了一个 SendEmail() 方法,该方法利用 MailService class 来实现电子邮件发送。

我想将 MailService 注入客户,但我不希望 API 的消费者可以访问 MailService。我相信它不能是内部的,因为您不能将内部类型传递给 public 构造函数。因此,将 Customer ctr 设置为内部是有意义的(因为只有 BLL 应该创建它们),但 Windsor 抱怨说,因为注册的类型必须具有 public ctr.

我觉得我错过了所有这一切的基本内容。我将如何着手设计这样的东西?我想一个解决方案是接口,但是当(通常)只有一个实现时,为每个内部类型创建接口不知何故感觉不对。

I believe it can't be internal, as you can't pass an internal type to a public constructor.

如果 public 构造函数依赖于内部类型,那么

C# 将不会编译您的 class,这是显而易见的。但是您实际上可以将内部实现传递给 public 构造函数,只要构造函数所依赖的接口也是 public。

It therefore makes sense to make the Customer ctr internal

这不是将构造函数设为内部的好理由,因为这会很好地工作,但如果您要构建可重用的库,将构造函数设为内部是非常有效的,因为一旦您发布了库,更改 public构造函数是一个破坏性的变化。因此,将其内部化是允许图书馆在未来发生变化和发展的好方法。

but Windsor complains because registered types must have a public ctr.

大多数 DI 库允许覆盖默认的构造函数解析行为,如 does Castle Windsor。

因为您正在创建一个可重用的库,所以我建议您阅读 Mark Seemann's DI Friendly Library 文章。