Some DI Containers (e.g. (IIIRC) StructureMap) actually support Per Thread lifetime styles, but that's probably not going to help you, because it would inject IService
into Controller
on one thread, and then use it on a number of other threads.
What I would suggest is to leave the Controller
implementations as is, because the fact that a particular implementation of IService
isn't thread-safe, is an implementation detail.
Instead, create a thread-safe Adapter/Decorator of IService
and inject that into Controller
. Something like this:
public ThreadSafeService : IService
{
private readonly IServiceFactory factory;
public ThreadSafeService(IServiceFactory factory)
{
this.factory = factory;
}
public void DoSomething()
{
this.factory.Create().DoSomething();
}
}
IServiceFactory
could be declared like this:
public interface IServiceFactory
{
IService Create();
}
If you implement IServiceFactory
so that it creates a new instance of IService
for every call to Create
, you have a thread-safe implementation on hand, because there's no shared state.
This approach is container-agnostic and prevents Leaky Abstractions.