在没有第三方框架的情况下实现DI

时间:2012-02-13 21:12:21

标签: c# .net .net-4.0 dependency-injection inversion-of-control

我正在编写插件作为插件架构的一部分。插件的创建方式是通过反射和CreateInstance。因此,将调用默认构造函数。这段代码我无法触及,我试图找到一种合理的方式来使用DI而无法使用框架。

我相信我有3个选择:

i)穷人的DI(PMDI)

ii)工厂模式

iii)TinyIOC或类似的(处理DI的一个cs文件)

我开始关注PMDI,但后来依赖需要另一个依赖,所以我最终得到了类似于丑陋的东西,可能会变得更糟:

public MyMainPluginClass() : this(new Repo(new Logger()))
{

}

public MyMainPluginClass(IRepo repo)
{

}

然后我转向了工厂模式的想法,但找不到任何体面的演示代码。我想我会有这样的事情:

public static FactoryUtility
{
  public static IRepo GetRepo()
  {
    return new Repo(GetLogger());
  }

  public static ILogger GetLogger()
  {
    return new Logger();
  }
}

    public MyMainPluginClass() : this(FactoryUtility.GetRepo())
    {

    }

    public MyMainPluginClass(IRepo repo)
    {

    }

它看起来怎么样?

然后我遇到TinyIOC这是一个完成所有依赖注册的类,但我相信它需要在Program.cs中设置,而我在类库中没有。如果有人有使用它的经验,可以这样使用:

    public MyMainPluginClass()
    {
       var container = TinyIoCContainer.Current;
       container.AutoRegister();
       var implementation = container.Resolve<IRepo>();

       MyMainPluginClass(implementation);
    }

    public MyMainPluginClass(IRepo repo)
    {

    }

是否有任何替代方法可以在不使用第三方库的情况下实现DI,如果不是从上面选择哪种方法?

注意:上面的代码尚未编译,只是我认为可行的方法。如果它们是有效的方法,请发布更正。

3 个答案:

答案 0 :(得分:2)

由于您使用的是.NET 4,因此您可能需要考虑使用MEF,因为它内置于框架本身。这看起来像是一个相当简单的DI,MEF处理得很好,因为它主要用于扩展性。

有关详细信息,请参阅Learn More page on the MEF CodePlex site

答案 1 :(得分:1)

我最终和TinyIOC一起去了。不幸的是,插件的构造函数在实际启动和运行之前会被多次调用。我只是设置一个布尔值来防止多次调用注册,因此它允许我简单地自动注册依赖项,然后关闭。

public MyMainPluginClass() : this(FactoryUtility.SetupIOC())
{

}

public MyMainPluginClass(IRepo repo)
{

}

public static class FactoryUtility
{
    private static bool Initialized  = false;

    public static IRepo SetupIOC()
    {
        var container = TinyIoCContainer.Current;

        if (!Initialized)
        {
            container.AutoRegister(new[] { Assembly.GetExecutingAssembly() });

            Initialized = true;
        }

        var result = container.Resolve<IRepo>();

        return result;
    }
}

答案 2 :(得分:0)

如果我绝对不想为DI容器添加依赖项,我喜欢使用我自己的TinyIOC(抱歉这个名字,不知道它被采用了),这对于小项目给了我相同的语义使用容器,但时钟低于200 LOC。

如果您有兴趣,请输入以下代码:https://gist.github.com/ad7608e2ae10b0f04229