我有一个Web API应用程序,并使用Unity进行依赖注入。该应用程序使用包含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类都公开,这对我来说似乎是错误的。这似乎是错误的,因为这些是实现细节,只与库本身相关。我通过控制反转来实现这一点,你允许顶层应用程序通过某种配置来选择其底层实现,但是这是否意味着不再需要内部等?
答案 0 :(得分:2)
暂时忘记您正在使用容器,并在申请的create those classes yourself中说出startup path。你怎么在C#中实际做到这一点?
答案是,你做不到。这不会在C#中编译,因为C#要求这些类型是公共的。因此,虽然这些类型可能是其他组件的实现细节,但它们并不是应用程序将它们连接在一起的实现细节。你是否使用DI库来帮助你是无关紧要的;该库需要访问这些库,因为对于库,这些类是不是实现细节。
请注意隐藏这些类的方法有很多种。您可以将接口移动到它们自己的程序集中,让消费库和包含这些实现的库都依赖于新的“契约”程序集。如果不让使用程序集依赖于实现程序集,那么实现类型将从使用程序集中有效隐藏,即使这些类型仍然是公共的。
答案 1 :(得分:2)
虽然我个人反对内部接口,但您可以通过添加
来允许团结使用它们[assembly: InternalsVisibleTo("Unity_ILEmit_InterfaceProxies")]
到包含您的接口的项目的AssemblyInfo.cs文件中。在尝试添加[assembly:InternalsVisibleTo(“Microsoft.Practices.Unity”)]之后我发现了这个 我看到它在其他职位上没有工作但没有效果,但觉得这是正确的方向。我从代码中提取的堆栈跟踪引用了上面的程序集,并允许代码工作。
这将允许您隐藏您的界面。构造函数是另一个故事。
答案 2 :(得分:1)
我发布了自己的答案,因为我认为它最接近回答我原来的问题。它可能不像Steven的建议那样干净,但是喜欢它或者讨厌它,它确实允许将库的内部类与Unity结合使用。
我需要对类/接口进行三次更新: