C# 如何使用内部类的统一性?

C# 如何使用内部类的统一性?,c#,asp.net,dependency-injection,inversion-of-control,unity-container,C#,Asp.net,Dependency Injection,Inversion Of Control,Unity Container,我有一个Web API应用程序,正在使用Unity进行依赖注入。应用程序使用一个库,其中包含一个接口IDoStuff和一个实现该接口的类: 内部接口 { 无效剂量(); } 内部类DoStuff:IDoStuff { 公共无效剂量测定法() { //做点什么 } } 图书馆还有一个公共类,需要做一些事情: 公共类需要dostuff { 私人私人住宅; 公共需要 { this.doStuff=新的doStuff(); } 内部需求减少(IDotuff) { this.doStuff=doStuf

我有一个Web API应用程序,正在使用Unity进行依赖注入。应用程序使用一个库,其中包含一个接口IDoStuff和一个实现该接口的类:

内部接口
{
无效剂量();
}
内部类DoStuff:IDoStuff
{
公共无效剂量测定法()
{
//做点什么
}
}
图书馆还有一个公共类,需要做一些事情:

公共类需要dostuff
{
私人私人住宅;
公共需要
{
this.doStuff=新的doStuff();
}
内部需求减少(IDotuff)
{
this.doStuff=doStuff;
}
虚无快乐的东西
{
doStuff.DoSomething();
}
}

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

暂时忘记您正在使用一个容器,假设您在应用程序的最前端。在C#中,您实际上是如何做到这一点的

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


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

我已经发布了我自己的答案,因为我相信它最接近于回答我的原始问题。它可能不像Steven的建议那样是一个干净的设计选择,但不管你喜不喜欢,它确实允许库的内部类与Unity一起使用

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

  • 将接口公开
  • 公开施工人员
  • 介绍一个静态类/方法,该类/方法在库中执行统一注册,该库是从应用程序启动时执行的主要统一注册逻辑调用的

  • 虽然我个人反对内部接口,但您可以通过添加

    [assembly: InternalsVisibleTo("Unity_ILEmit_InterfaceProxies")] 
    
    指向包含接口的项目的AssemblyInfo.cs文件。我在尝试添加[assembly:InternalsVisibleTo(“Microsoft.Practices.Unity”)后发现了这一点 我在其他岗位上没有看到这种情况,也没有任何效果,但我觉得这是一个正确的方向。我从代码中提取的stacktrace引用了上面的程序集,并允许代码工作


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

    注意,我可以编辑库,但它还没有在其他任何地方使用过。有。谢谢链接标记,非常有趣。不过,我仍然想知道,在内部是否可以实现上述功能?如上所述,我已将此标记为可接受的答案,因为它最接近于回答实际问题。对于我的生产代码,我没有这样做,而是将我的接口移动到一个单独的库中,并按照Stephen和Mark提供的链接建议公开我的实现类。将其隐藏在接口后面,有一个工厂来创建它。内部在Unity中基本上是无用的,因为所有的用户脚本最终都在同一个.NET程序集中,对吗?(Assembly UnityScript.dll)“而我个人反对内部接口”