Skip to content

Commit 7807cf5

Browse files
author
maximv
committed
fixed: #199
1 parent 75a9bcc commit 7807cf5

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

build_the_docs.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dotnet msbuild -target:MdGenerate docs\DryIoc.Docs\DryIoc.Docs.csproj

docs/DryIoc.Docs/Home.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ and to support the __extensibility__ and __testability__ of the code.
100100
101101
- Advanced topics:
102102
103+
- [Resolution Pipeline](ResolutionPipeline.md)
103104
- ["Child" Containers](KindsOfChildContainer.md)
104105
- [Required Service Type](RequiredServiceType.md)
105106
- [Examples of context based resolution](ExamplesContextBasedResolution.md)

docs/DryIoc.Docs/Home.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ and to support the __extensibility__ and __testability__ of the code.
9797

9898
- Advanced topics:
9999

100+
- [Resolution Pipeline](ResolutionPipeline.md)
100101
- ["Child" Containers](KindsOfChildContainer.md)
101102
- [Required Service Type](RequiredServiceType.md)
102103
- [Examples of context based resolution](ExamplesContextBasedResolution.md)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Resolution Pipeline
2+
3+
- [Resolution Pipeline](#resolution-pipeline)
4+
- [Overview](#overview)
5+
- [Relative Performance](#relative-performance)
6+
- [Rules.WithUseInterpretation](#ruleswithuseinterpretation)
7+
- [Rules.WithoutUseInterpretationForFirstResolution](#ruleswithoutuseinterpretationforfirstresolution)
8+
- [Rules.WithoutFastExpressionCompiler](#ruleswithoutfastexpressioncompiler)
9+
10+
## Overview
11+
12+
What happens when you call `container.Resolve<X>();` for the same service `X` multiple times in a sequence assuming that the `X` is not a singleton*:
13+
14+
1. The first call will **discover and construct the expression tree** of `X` object graph, **interpret** the expression to get the service, and if succeeded will **cache the expression** in resolution cache.
15+
2. The second call will find cached expression, will **compile** it to delegate, then it will **replace the cached expression with the delegate** and will invoke the delegate to get the service.
16+
3. The third call will find the cached delegate and invoke it.
17+
18+
singleton* - those are always interpreted (cannot be changed via rules) and injected in object graph as `ConstantExpression` unless wrapped in Func or Lazy wrappers (which create singleton when consumer demand).
19+
This is because they need to be created once and one-time interpretation is faster than compilation+invocation.
20+
21+
22+
## Relative Performance
23+
24+
- Expression interpretation is 10x times slower than the delegate invocation
25+
- Delegate compilation is 100x slower than interpretation.
26+
27+
Now, spot the problem for the multi-threaded resolution of the same service (#208)
28+
29+
## Rules.WithUseInterpretation
30+
31+
The compilation (essentially `System.Reflection.Emit`) is not supported by all targets, e.g. Xamarin iOS. In this case, you may specify to always use interpretation via
32+
33+
```cs
34+
var c = new Container(rules => rules.WithUseInterpretation());
35+
```
36+
37+
DryIoc uses its own interpretation mechanism which is faster than `System.Linq.Expressions.Expression.Compile(preferInterpretation: true)` because DryIoc can recognize its own internal methods in the resolved expression tree, and call them directly without reflection. It has other optimizations as well.
38+
39+
## Rules.WithoutUseInterpretationForFirstResolution
40+
41+
On the contrary, if you want to Compile on the first resolution, maybe to "warm-up" the container before the actual usage you can do that via
42+
43+
```cs
44+
var c = new Container(rules => rules.WithoutUseInterpretationForFirstResolution());
45+
```
46+
47+
## Rules.WithoutFastExpressionCompiler
48+
49+
By default, DryIoc relies on [its own Expression Tree compiler](https://github.com/dadhi/FastExpressionCompiler). But it doesn't support certain old platforms, e.g. PCL, <= .NET 4.0, <= .NET Standard 1.2 - so the default `Expression.Compile` is used for them. If you want for some reason to fully switch to `Expression.Compile` you may do so via:
50+
51+
```cs
52+
var c = new Container(rules => rules.WithoutFastExpressionCompiler());
53+
```
54+
55+
But I would not recommend using it, maybe just for the last resort troubleshooting only.
56+
It is very likely that the option will be removed in future DryIoc versions.

0 commit comments

Comments
 (0)