2012-02-13 130 views
4

我正在编写插件作为插件体系结构的一部分。插件的创建方式是通过反射和CreateInstance。因此调用默认的构造函数。我无法触及的这段代码,我试图找到一种明智的方式来使用DI,而无需使用框架。在没有第三方框架的情况下实现DI

我相信我有3个选项:

我)穷人的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任何替代方法,而无需使用第三方库,如果没有哪种办法从上面选择?

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

+0

只是FYI;你的第三个代码示例也基本上是穷人依赖注入。 – 2012-02-13 22:33:26

回答

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

由于您使用的是.NET 4,因此您可能需要考虑使用MEF,因为它已内置到框架本身中。这看起来像是非常直接的DI,MEF处理得很好,因为它主要用于扩展性。

详情请参阅Learn More page on the MEF CodePlex site

+0

我不能使用MEF,因为这是一个具有自己架构的遗留产品 – Jon 2012-02-13 22:04:45

+1

@Jon如果你正在实现DI部分,你可以使用任何你想要的东西......主应用程序不会使用它的事实不应该物。 – 2012-02-13 23:33:50

+0

您是否有过使用传统架构寻找继承MEF特定基类的插件的例子? – Jon 2012-02-14 08:37:47

0

如果我绝对不想为DI容器添加依赖项,我喜欢使用我自己的TinyIOC(对于名称感到抱歉,不知道它是否被采用),这对于小型项目给我一样的语义与使用容器一样,但在200 LOC以下时钟。

如果你有兴趣,这里是代码:https://gist.github.com/ad7608e2ae10b0f04229

+0

这是否会在我的默认构造函数中设置,然后我可以调用具有已解析类型的另一个构造函数? – Jon 2012-02-13 22:06:23

+0

应用程序的Ioc部分通常驻留在应用程序的基础结构中。上面的代码也有一个容器的概念 – flq 2012-02-14 08:33:55

+0

我同意,但正如我所提到的,我无法触及原始应用程序,也没有一个program.cs来设置国际奥委会容器 – Jon 2012-02-14 08:42:59

相关问题