Injection dependency as method parameter instead of constructor parameter

Is it possible to inject a dependency as a method parameter instead of a constructor parameter, or using MEF or Autofac?

thank

+3


source to share


1 answer


I don't know about MEF as I have never used it. You can do it with Unity and with Autofac

Unity

From MSFT documentation.

Unity instantiates dependent objects defined in method parameters that carry the InjectionMethod attribute in target scope. It then calls the attribute method of the target object before returning the object to the caller. You must apply the InjectionMethod attribute on the target class to initiate the method call injection.

public class MyObject
{
   public SomeOtherObject dependentObject;

  [InjectionMethod]
  public void Initialize(SomeOtherObject dep) 
  {
    // assign the dependent object to a class-level variable
    dependentObject = dep;
  }
}

      

This will mean that the class has a dependency method that must be called when the class is initialized and has a method parameter injected by it.

IUnityContainer uContainer = new UnityContainer();
MyObject myInstance = uContainer.Resolve<MyObject>();

// access the dependent object
myInstance.dependentObject.SomeProperty = "Some value";

      

Autofac



Autofac does this via lambdas or callbacks during service activation. From Autofac documentation

While constructor parameter nesting is the preferred method of passing values ​​to the component being constructed, you can also use property nesting or method nesting to provide values.

Property injection uses write properties rather than constructor parameters to perform injection. The injection method installs dependencies by calling the method.

// Register the type that you want to resolve with a resolution callback. Within the callback, invoke the method with a resolved dependency.
builder.Register(c => {
  var result = new MyObjectType();
  var dep = c.Resolve<TheDependency>();
  result.SetTheDependency(dep);
  return result;
});

      

An alternative is the registration callback.

builder
  .Register<MyObjectType>()
  .OnActivating(e => {
      var dep = e.Context.Resolve<TheDependency>();
      e.Instance.SetTheDependency(dep);
  });

      

Both frameworks can only perform method injection at resolution time. However, you cannot inject a dependency into a method after the object has been set. In these scenarios, you should use a factory to retrieve the dependencies you have and the factory resolve it through the DI container.

Factory

// Create the factory. The factory will have a static method that the DI system can register a lambda with, so that the factory can resolve through the DI container without being tightly coupled to it.
public class BarFactory
{
    private static Func<IBarDependency> internalFactory;

    public static void SetFactory(Func<IBarDependency> factory)
    {
        this.internalFactory = factory;
    }

    public IBarDependency CreateBar()
    {
        // Use the DI container lambda assigned in SetFactory to resolve the dependency.
        return internalFactory();
    }
}

public class DependencyInjectionBootstrap
{
    IContainer container;

    public void SetupDI()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<BarDependency>().As<IBarDependency>();
        container = builder.Build();

        // Tell the factory to resolve all IBarDependencies through our IContainer.
        BarFactory.SetFactory(() => container.Resolve<IBarDependency>());
    }
}

public class FooViewModel
{
    public void ExecuteSave()
    {
        var barFactory = new BarFactory();
        IBarDependency bar = barFactory.CreateBar();
    }
}

      

+3


source







All Articles