简体   繁体   中英

Auto-wiring property injection

I am trying to use property injection for StructureMap in a plug-in style system.

ObjectFactory.Initialize(o => o.Scan(s =>
{
    s.AssembliesFromPath("path_to_assemblies");
    s.WithDefaultConventions();
});

Here is a sample implementation (purposely did not go deeper in defining T and TU as they are just simple classes)

public interface IBarService
{
    void Baz();
}

public class BarService : IBarService
{
    public void Baz() { /* implementation */ }
}


public abstract class PluginBase<T, TU> : IPlugin
    where T : AClass, new()
    where TU : BClass
{
     protected PluginBase()
     {
         //some init code in the constructor
     }
}

//Foo is created at run-time via Activator.CreateInstance()
public class FooPlugin : PluginBase<AClass, BClass>
{
   [SetterProperty]
   public IBarService BarService { get; set; }

   public void Fooey()
   {
       BarService.Baz();
   }
}

I want to auto-wire the property dependencies on all of these plug-ins that are created at run-time. I thought I'd start out with property injection and then move things to the constructor if the need arose.

If I do:

var obj = ObjectFactory.GetInstance<IBarService>();

anywhere in an instance of FooPlugin , I get the correct implementation and all is well.

If I do:

this.BarService.Baz();

I get a null reference exception because no instance of IBarService was set.

After I create my plug-in, if I do this:

ObjectFactory.BuildUp(pluginObject) .

All is well and FooPlugin has the correct implementation of IBarService .

Is there any way to simply allow me to decorate my plugin properties with [SetterProperty] and have StructureMap automatically inject those when the Plugin is created without having to call ObjectFactory.BuildUp(pluginObject) ?

How are you creating your plugin instance in the cases where it doesn't work? Are you just doing new FooPlugin() ?

If you do var plugin = ObjectFactory.GetInstance<PluginBase<AClass, BClass>>(); , do you get the plugin with all the correct dependencies resolved?

If you are instantiating the object with "new", the container has no way to know that the instance needs dependencies resolved--it has no knowledge of that instance. Instances that need injected dependencies must be "managed by the container" so to speak.

You'll save yourself a lot of trouble if you just go the opposite route and inject all dependencies in the contstructor(s). This way there is a single place where you need to check if your objects are initialized properly...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM