如何将Unity与内部类一起使用?

我有一个Web API应用程序,并使用Unity进行dependency injection。 该应用程序使用包含Interface IDoStuff的库和实现该接口的类:

internal interface IDoStuff { void DoSomething(); } internal class DoStuff : IDoStuff { public void DoSomething() { // Do some stuff } } 

该库还有一个需要做的事情的公共类:

 public class NeedToDoStuff { private IDoStuff doStuff; public NeedToDoStuff() { this.doStuff = new DoStuff(); } internal NeedToDoStuff(IDoStuff doStuff) { this.doStuff = doStuff; } void PleaseDoStuff() { doStuff.DoSomething(); } } 

我想使用Unity在我的控制器中创建一个NeedToDoStuff实例,并且还负责在内部创建DoStuff类,而不是直接调用new的构造函数。 但是,我能看到的唯一方法就是将IDoStuff接口和DoStuff类都公开,这对我来说似乎是错误的。 这似乎是错误的,因为这些是实现细节,只与库本身相关。 我得到了控制反转,你允许顶级应用程序通过某种配置来选择它的底层实现,但这是否意味着不再需要内部等?

忘记你正在使用容器,让我们说你自己在应用程序的启动路径中创建这些类 。 你怎么在C#中实际做到这一点?

答案是,你做不到。 这不会在C#中编译,因为C#要求这些类型是公共的。 因此,尽管这些类型可能是其他组件的实现细节,但它们并不是应用程序中将它们连接在一起的实现细节。 你是否使用DI库来帮助你是无关紧要的; 该库需要访问这些库,因为对于库,这些类不是实现细节。

并注意隐藏这些类有不同的方法。 您可以将接口移动到它们自己的程序集中,让消费库和包含实现的库都依赖于新的“契约”程序集。 如果不让使用程序集依赖于实现程序集,则实际类型会从使用程序集中有效隐藏,即使这些类型仍然是公共的。

虽然我个人反对内部接口,但您可以通过添加允许团结使用它们

 [assembly: InternalsVisibleTo("Unity_ILEmit_InterfaceProxies")] 

到包含您的接口的项目的AssemblyInfo.cs文件。 我在尝试添加[assembly:InternalsVisibleTo(“Microsoft.Practices.Unity”)]之后找到了这个,我看到它在其他post中没有用,并且没有效果,但觉得这是正确的方向。 我从代码中提取的堆栈跟踪引用了上面的程序集并允许代码工作。

这将允许您隐藏您的接口。 构造函数是另一个故事。

我发布了自己的答案,因为我认为它最接近于回答我原来的问题。 它可能不像Steven的建议那样干净,但是喜欢它或者讨厌它,它确实允许将库的内部类与Unity结合使用。

我需要对类/接口进行三次更新:

  1. 使接口公开。
  2. 使构造函数公开。
  3. 引入一个静态类/方法,在库中执行统一注册,从应用程序启动时执行的主统一注册逻辑调用。