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

时间:2015-11-26 15:29:37

标签: c# asp.net dependency-injection inversion-of-control unity-container

我有一个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类都公开,这对我来说似乎是错误的。这似乎是错误的,因为这些是实现细节,只与库本身相关。我通过控制反转来实现这一点,你允许顶层应用程序通过某种配置来选择其底层实现,但是这是否意味着不再需要内部等?

3 个答案:

答案 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结合使用。

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

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