话虽如此,但在实际使用Unity之前,还有一个问题 – 虽然Unity会让我通过Resolve<>请求库,但我的插件仍然需要引用在主应用程序中创建的Unity实例。那么这种情况下您唯一的选择是将Unity引用传递给所有插件吗?但从那时起,您可以方便地使用Unity来获取所有其他依赖项,对吗?
更新
我意识到自己错了,但希望有人能为我澄清一下——我不应该到处传递对Unity的引用!我只需在我的应用程序中创建容器,然后注册所有类型。然后当我实例化所有插件时,它们应该可以神奇地使用这些已注册的接口,几乎不需要额外的工作,对吗?在我的情况下,我的构造函数必须是无参数的,因为我的插件加载器无法处理参数,在这种情况下,我将不得不使用属性注入来让它们访问接口,对吗?
另一个更新
我继续尝试Unity。我注册了所有插件都需要的类的实例。我也知道我最终会遇到一个问题,因为它们是无参的(我可能需要传递一个对Unity的引用来使它们运行)。但是,现在我直接创建插件,并通过Resolve方法完成。因此,代码基本上如下所示:
// app code
ICandySettings _candy_settings = new CandySettings();
IUnityContainer unity = new UnityContainer().RegisterInstance<ICandySettings>( _candy_settings);
CandyPlugin _plugin = unity.Resolve<Candy>(); // throws null reference exception, see below.
// plugin code
public class Candy
{
[Dependency]
ICandySettings CandySettings { get; set; }
...
public Candy()
{
CandySettings.GetSetting("box"); // CandySettings is null! why? Didn't Unity do this for me?
}
}
目前我的问题是,我认为(鉴于我的有限知识),Unity应该会自动将插件的CandySettings引用设置为通过RegisterInstance注册的任何实例,但事实并非如此。
一个可行的选项
如果我跳过烟雾和镜子的东西,只需在插件的构造函数中传递我的UnityContainer,然后我就可以调用Unity.Resolve()来设置我的CandySettings属性的值,一切都能正常工作。我很想知道为什么[Dependency]属性没有做我认为它应该做的事情。如果我没弄错的话,我实际上不需要在我的插件加载器的每个构造函数中都传递Unity。如果[Dependency]正在起作用,我只需要使用Unity.Resolve(),那么它可能会起作用。但是,现在我明白了大家所说的选择IoC容器会强制整个开发团队使用它的原因。
MEF!
到目前为止,MEF对我来说获胜了。它非常简单,并且神奇的烟雾和镜子的东西非常适合我的需求(目前)。但我仍然想让Unity工作。我觉得奇怪的是,对于MEF,我只需要组成部分,其他一切都会自然而然地实现,而我似乎无法让Unity自动注入所有东西,我必须通过引用到每个地方传递的Unity来解决所有问题。这不对。
更多MEF
我喜欢使用MEF非常容易解析多个对象,但是在使用策略模式指定代码行为的情况下怎么办?目前,只需将引用从一种行为的实现更改为另一种行为的实现就可以轻松完成,它就可以正常工作。有人使用MEF做吗?正确的方法是使用ImportMany,然后使用额外的代码确定应调用列表中的哪个行为吗?