Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection if a class needs to create multiple instances of another class when required in a method

Hi I am learning the best way to do dependency injection and also using IoC containers to resolve dependencies. however most of the examples that i have come across a class only needs a single instance of its dependency class and this dependency is injected into the constructor. But my scenarios is a little different. I have a class with a method which is continuously doing some work in a loop and foreach iteration in the loop i need to create a new instance of a different class. How do I go about doing dependency injection in this scenario? how can an IoC container resolve this ?

Thank you for your patience

like image 690
rakesh Avatar asked Sep 14 '25 20:09

rakesh


1 Answers

Like dkatzel said, use a factory. This is the way I go about it. If you were creating instances of say, BaseViewModel:

public interface IViewModelFactory {
    T Create<T>() where T : BaseViewModel;
}

public class ViewModelFactory : IViewModelFactory {
    private readonly Dictionary<Type, Func<BaseViewModel>> _factories;

    public ViewModelFactory(Dictionary<Type, Func<BaseViewModel>> factories) {
        _factories = factories;
    }

    public T Create<T>() where T : BaseViewModel {
        return _factories[typeof (T)]() as T;
    }
}

So now we have an injectable factory that can be configured to create and return anything that implements BaseViewModel.

In IoC we need to configure the types to return so imagine these view models (and note the dependency in the second view model):

public abstract class BaseViewModel {
    // ...
}

public class FirstViewModel : BaseViewModel {
    // ...
}

public class SecondViewModel : BaseViewModel {
    private readonly ISomeDependency _injectedDependency;

    public SeoncdViewModel(ISomeDependency dependency) {
        _injectedDependency = dependency;
    }
}

And (using Autofac) we configure it like this:

var builder = new ContainerBuilder();

builder.Register(b => {

    var factories = new Dictionary<Type, Func<BaseViewModel>> {
        { typeof (FirstViewModel), () => new FirstViewModel() },
        { typeof (SecondViewModel), () => new SecondViewModel(b.Resolve<ISomeDependency>()) },
    };

    return new ViewModelFactory(factories);

}).As<IViewModelFactory>();

And now we can inject IViewModelFactory and create instances of FirstViewModel or SecondViewModel:

public class SomeClass {
    public readonly IViewModelFactory _factory;

    public SomeClass(IViewModelFactory factory) {
        _factory = factory;

        var secondViewModel = _factory.Create<SecondViewModel>();
    }
}

The nice part is that IoC handles all of the dependencies. SomeClass just knows that it has a thing that can create a SecondViewModel so SomeClass doesn't need to know about SecondViewModels dependencies.

like image 120
Neil Smith Avatar answered Sep 16 '25 11:09

Neil Smith