Nobody can answer that question for you. The performance impact depends on lots of variables such as your hardware, your application, and how often that property is being called.
So the real question is, is it fast enough for your situation. You are the only one who can find out by benchmarking this.
The framework is highly optimized in that it will:
- Minimize the number of method calls in the happy path of the framework (which means the minimum number of method calls when calling
GetInstance<T>
and GetInstance(Type)
).
- Minimize the number of locks in the happy path of the application (the happy path is currently lock-free).
- Minimize the number of callbacks into the container when resolving an object graph (which means that the container itself will not call
GetInstance<T>
to resolve an object's dependencies, but will inline the creation of those dependencies in the registration's internally constructed Func<object>
delegate).
But although Simple Injector is highly optimized, there is a constant cost in calling GetInstance<T>
. On each call, the container will always have to:
- Do a dictionary lookup (using a
Dictionary<Type, InstanceProducer>
in the current implementation) for the given typeof(T)
.
- Call the
GetInstance()
method on the found InstanceProducer
instance.
- Call a
Func<object>
delegate for the creation the given instance (inside the InstanceProducer.GetInstance
method).
- Do a cast from
object
to T
before returning from GetInstance<T>
.
From this constant cost, doing the dictionary lookup takes about 80% the time. The percentage of the constant overhead however goes down rather quickly when you start resolving anything else than a singleton, especially when resolving big object graphs.
Still, if you're doing lots of calls to the Cache
property in a performance critical path of the application, you might want to optimize that (but again, you have to determine whether it is too slow: don't do premature optimizations). One easy way to do this is by injecting the ICacheClient
into the constructor of consumers. This prevents the instance from being resolved from the container over and over again, and allows consumers to just use the locally cached ICacheClient
instance without a problem.
As a matter of fact, this is a general pattern called Constructor Injection and is an adviced practive. Prefer letting the container build up a complete object graph for you (by using constructor injection) by making one single call to GetInstance<T>
at the start of a 'request', instead of calling back constantly to the container during that request.