无需第三方框架即可实现 DI
我正在编写一个插件作为插件架构的一部分。创建插件的方式是通过反射和CreateInstance。因此调用默认构造函数。这段代码我无法触及,我正在尝试找到一种在无法使用框架的情况下使用 DI 的合理方法。
我相信我有 3 个选择:
i) Poor Man's DI (PMDI)
ii) Factory Pattern
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)
{
}
是否有任何替代方法可以在不使用第 3 方库的情况下实现 DI,如果没有,会从上面选择哪种方法?
注意:上面的代码尚未编译,只是我认为可行的一个想法。如果它们是有效的方法,请发布更正。
I am writing a plugin as part of a plugin architecture. The way plugins are created is via reflection and CreateInstance
. Therefore the default constructor is called. This code I cannot touch and I am trying to find a sensible way to use DI without the ability to use a framework.
I believe I have 3 options:
i) Poor Man's DI (PMDI)
ii) Factory Pattern
iii) TinyIOC or similar (one cs file that handles DI)
I started looking at PMDI but then a dependency needed another dependency so I ended up with something similar to this which is ugly and could get worse:
public MyMainPluginClass() : this(new Repo(new Logger()))
{
}
public MyMainPluginClass(IRepo repo)
{
}
I then moved onto the idea of a Factory Pattern but could not find any decent demo code. I assume I would have something like this:
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)
{
}
Is that how it would look?
I then came across TinyIOC which is one class that does all the dependency registering but I believe it requires to be setup in a Program.cs which I don't have in a class library. If someone has any experience using this could it be used like so:
public MyMainPluginClass()
{
var container = TinyIoCContainer.Current;
container.AutoRegister();
var implementation = container.Resolve<IRepo>();
MyMainPluginClass(implementation);
}
public MyMainPluginClass(IRepo repo)
{
}
Are there any alternative approaches to achieve DI without using a 3rd party library and if not which approach would choose from above?
NOTE: The code above has not been compiled and is just an idea of what I think would work. Please post corrections if they are valid approaches.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于您使用的是 .NET 4,因此您可能需要考虑使用 MEF,因为它内置于框架本身中。这看起来相当简单的 DI,MEF 处理得很好,因为它主要用于可扩展性。
有关详细信息,请参阅MEF CodePlex 网站上的“了解更多”页面。
Since you're using .NET 4, you might want to consider using MEF, as it's built into the framework itself. This looks like fairly straightforward DI, which MEF handles well, as it's intended mainly for extensibility.
For details, see the Learn More page on the MEF CodePlex site.
我最终选择了TinyIOC。不幸的是,该插件的构造函数在实际启动和运行之前被调用了几次。我只是设置了一个布尔值来防止注册被多次调用,因此它允许我简单地自动注册依赖项,然后我们就可以开始了。
I went with TinyIOC in the end. Unfortunately the plugin's constructor gets called several times before its actually up and running. I simply set a boolean to prevent registration being called several times and therefore it allows me to simply auto-register dependencies and off we go.
如果我绝对不想向 DI 容器添加依赖项,我喜欢使用自己的 TinyIOC(对这个名称感到抱歉,不知道它已被采用),对于小型项目,它为我提供了与使用容器,但时钟频率低于 200 LOC。
如果您有兴趣,这里是代码:https://gist.github.com/ad7608e2ae10b0f04229
If I absolutely don't want to add a dependency to a DI container, I like to use my own TinyIOC (sorry about the name, didn't know it was taken), which for small projects gives me the same semantics as using a container, but clocks in at below 200 LOC.
If you are interested, here is the code: https://gist.github.com/ad7608e2ae10b0f04229