Maybe I'm abusing Unity, but here. I have several applications, both of which load the same assembly of plugins. All assemblies require a library, and I want them to have access to this library through Unity. However, in order to use Unity or any other IoC infrastructure, I would have to write an interface for this library. I will probably do this, but since the interface is really not needed for anything other than support for Unity, I am afraid that this means that I 1) skip the point or 2) use the framework incorrectly. If I avoid something that the DI offers me, then I will have to make the library class single, and then pass it to all the plugin constructors or through a public property, and I don't want to do this.
However, and nothing is implemented with Unity, I donβt get one more detail - although Unity will allow me to request the library via Resolve <>, my plugins should still have a link to Unity which is created in the main applications. So, this is the case when your only option is to pass the Unity link to all the plugins, but then it is convenient from this point, simply because you can use Unity to get all the other dependencies?
UPDATE
I realized that I missed this point, but I hope someone can clarify for me - I should not miss the link to Unity all over the world! I only need to create a container in my application and then register all types later. Then, when I create all my plugins, they should just magically use these registered interfaces, without any extra effort, right? In my case, my constructors should be parameterless, because my plugin loader cannot deal with arguments, in which case I will have to use property nesting to give them access to the interfaces, right?
OTHER UPDATE
I went ahead and tried Unity. I registered an instance of my class that all plugins need. I also know that in the end I will have a problem with my plugin loader, as they are without parameters (and I may need to pass a Unity link to it to make them work). However, at the moment I am directly creating a plugin, and I am doing this using the Resolve method. So, here is basically what the code looks like:
// 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? } }
So, my problem right now is that I would expect (given my limited knowledge) that Unity will automatically set the CandySettings plugin link to any instance registered through RegisterInstance, but it is not.
WORKING OPTION
If I skip the smoke and mirror material and just pass my UnityContainer to the plugin constructor, then I can call Unity.Resolve () to set the value of the CandySettings property, and everything works fine. I would really like to know why the [Dependency] attribute does not do what I thought. If I'm not mistaken, I don't need to pass Unity to every constructor in my plugin loader. I should just use Unity.Resolve (), and it will supposedly work if [Dependency] works. However, now I understand that everyone is talking about how to choose an IoC container, then force it to the entire development team.
MEF!
So far, MEF has won the battle for me. It's pretty simple, and the magic material for smoke and mirrors is great for my needs (for now). But I would still like to get Unity to work. It seems strange to me that for MEF I only need to compose the details, and everything else just falls into place, whereas I can not get Unity to simply enter the material automatically, and I need to solve everything through the Unity link everywhere. It may not be right.
More MEF
I like the idea that I can easily resolve multiple objects using MEF, but what about when I use a strategy template to dictate code behavior? Currently, it is as simple as changing a link from one implementation of behavior to another, and it just works. Does anyone do this with MEF? The correct way to do this is with ImportMany, and then use additional code to determine which behavior in the list should be triggered?