lundi 15 juillet 2019

Dependency Injection in Transient Objects

I'd like some advice on how to structure some objects via dependency injection.

Most of my application is singletons, and it's pretty straightforward to inject singletons as dependencies of each other.

However, I have a situation where I dynamically generate some transient objects that depend on several singletons.

Here's some C# pseudocode of the current situation:

// random singletons
public static class SingletonA {...}
public static class SingletonB {...}
public static class SingletonC {...}

// random objects that all need to depend on some subset of the above singletons
public class BaseTask {...}
public class TaskA : BaseTask {...}
public class TaskB : BaseTask {...}
public class TaskC : BaseTask {...}

public class Scheduler {
    public Scheduler() {
    }

    public void Start() {
        // When these tasks are created is actually really dependent on business logic,
        // and each task executes a bunch of internal logic.
        // Each Task can create more children Task at arbitrary times too.
        ...
        var taskA = new TaskA();
        ...
        var taskB = new TaskB();
        ...
        var taskC = new TaskC();
        ...
}

There is code in all of TaskA, TaskB, TaskC, ... that calls methods on the singletons. Also, each task can construct new tasks.

If I use dependency injection, I could do something like:

public class Scheduler {
    private ISingletonA _singletonA;
    private ISingletonB _singletonB;
    ...

    public Scheduler(ISingletonA singletonA, ISingletonB singletonB, ...) {
        _singletonA = singletonA;
        _singletonB = singletonB;
        ...
    }

    public void Start() {
        ...
        var taskA = new TaskA(_singletonA, _singletonB, ...);
        ...
        var taskB = new TaskB(_singletonA, _singletonB, ...);
        ...
        var taskC = new TaskC(_singletonA, _singletonB, ...);
        ...
    }
}

This seems like a mess, so I was thinking of refactoring all of the TaskA, TaskB, TaskC into a common class and making something like a factory:

public class Scheduler {
    public TaskFactory _taskFactory

    public Scheduler(TaskFactory taskFactory) {
        _taskFactory = taskFactory;
    }

    public void Start() {
        ...
        var taskA = _taskFactory.NewTaskA(_taskFactory);
        ...
        var taskB = _taskFactory.NewTaskB(_taskFactory);
        ...
        var taskC = _taskFactory.NewTaskC(_taskFactory);
        ...
    }
}

Any better ideas? And if not, I don't think this is the factory pattern. Is there a more accurate name?

Aucun commentaire:

Enregistrer un commentaire