Devesh
Devesh

Reputation: 394

constructor injection & Factories: Object required in two types of life times?

I have a situation where I have an object C that is required by two types of classes. One of these class runs in separate thread, the other one creates multiple threads with the help of timer elapsed event.

So there are basically two life times of object C.

Object C is created along with A and B by a factory. For class1 I create the instance through master factory, but for second one I will have to pass the entire factory. The second class will now decide in run time (based on timer tick) how to create object C.

My question is regarding the second case: I am passing the entire factory, which besides the knowledge of creating object C also has a knowledge of creating A and B, is this considered bad design? I am attaching a snapshot of what I am doing Composition Snapshot

Upvotes: 0

Views: 94

Answers (1)

Steven
Steven

Reputation: 172756

When working with multiple threads, each thread should get its own object graph. This means that every time you spin off some operation to a new thread (or a thread from the thread pool), you should ask the container again for the root object to work with. Prevent passing services from on thread to the other, because this scatters the knowledge about the thread-safety of your services throughout the code base, while with dependency injection you try to centralize this knowledge to a single place (the composition root). When this knowledge is scattered throughout the application, it becomes much harder to change the behavior of components what thread-safety is concerned.

When you do this, there is probably no need to even have two different configurations for that class. That class might simply be registeres as transient and because you resolve it at each pulse of the timer, each thread gets its own instance or the lifetime is scoped, in that case the class' lifetime will probably end when the timed operation ends.

The code that the timer calls and calls back into the container should be part of the composition root. Since the service is resolved on a background thread, you will often have to wrap that call in some sort of scope (lifetime scope, child container, etc). This allows that instance (or any other registered service) to live for the duration of that scope.

Upvotes: 1

Related Questions