-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.html
941 lines (583 loc) · 103 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="Hugo 0.53" />
<title>Simple Injector Blog - Opinions and Best Practice from the Simple Injector Contributors</title>
<link rel="stylesheet" href="/css/Roboto.css">
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/strange-case.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="/index.xml" rel="alternate" type="application/rss+xml" title="Simple Injector Blog" />
</head>
<body class="scheme-darkbrown">
<div class="container-fluid">
<div class="row">
<div class="col-sm-4 col-md-3 col-lg-3 sidebar">
<div class="sidebar-content">
<a href=""><h1>Simple Injector Blog</h1></a>
<p>Opinions and Best Practice from the Simple Injector Contributors</p>
<ul class="sidebar-menus">
</ul>
<div class="sidebar-recent hidden-xs">
<p>Recent Posts:</p>
<ul>
<li><a href="/2020/12/the-tale-of-the-async-interfaces/">The Tale of the Async Interfaces</a></li>
<li><a href="/2020/06/simple-injector-v5/">Simple Injector v5 - Virus edition</a></li>
<li><a href="/2017/03/simple-injector-v4-has-been-released/">Simple Injector v4 has been released</a></li>
<li><a href="/2016/07/working-around-the-asp-net-core-di-abstraction/">Working around the ASP.NET Core DI abstraction</a></li>
<li><a href="/2016/06/whats-wrong-with-the-asp-net-core-di-abstraction/">What’s wrong with the ASP.NET Core DI abstraction?</a></li>
<li><a href="/2015/12/when-should-you-use-a-container/">When should you use a container?</a></li>
<li><a href="/2015/08/simple-injector-v3-is-here/">Simple Injector v3 is here!</a></li>
</ul>
</div>
<p class="copyright">© 2023. All rights reserved. </p>
<p class="attr">Powered by <a href="http://gohugo.io">Hugo</a> & <a href="https://github.com/ExchangeRate-API/strange-case">Strange Case</a> (inspired by <a href="https://github.com/poole/hyde">Hyde</a>).</p>
</div>
</div>
<div class="col-sm-7 col-sm-offset-4 col-md-6 col-md-offset-3 col-lg-5 col-lg-offset-3 content">
<div class="post">
<div class="post-heading">
<h1><a href="/2020/12/the-tale-of-the-async-interfaces/">The Tale of the Async Interfaces</a></h1>
<span>Dec 15, 2020 by Steven</span>
</div>
<blockquote>
<p>With the release of Simple Injector v5, I made an error of judgement. To support asynchronous disposal of the <code>Container</code> and <code>Scope</code> objects I added a dependency from the core library to the Microsoft.Bcl.AsyncInterfaces NuGet package. Unfortunately, this proved to be a very painful mistake. In this blog post I’ll explain why I choose to take this dependency, why this was a mistake, and how this finally got fixed in <a href="https://github.com/simpleinjector/SimpleInjector/releases/tag/5.2.0">v5.2</a>.</p>
</blockquote>
<h2 id="double-trouble">Double Trouble</h2>
<p><img align="right" width="40%" style="max-width:275px;" src="/images/diamondduck.png" loading="lazy" decoding="async"></p>
<p>With the introduction of .NET Core 3, Microsoft added a new <code>IAsyncDisposable</code> interface as asynchronous counterpart of <code>IDisposable</code>. In order enable asynchronous disposal in older framework versions (i.e. .NET Core 2.0 and .NET 4.6.1), Microsoft published the <a href="https://www.nuget.org/packages/Microsoft.Bcl.AsyncInterfaces/">Microsoft.Bcl.AsyncInterfaces</a> NuGet package. Where the package’s <code>net461</code> and <code>netstandard2.0</code> targets contain assemblies that specify—among other things—the <code>IAsyncDisposable</code> interface, the <code>netstandard2.1</code> target assembly uses type forwarding to reference the framework’s version.</p>
<p>The publication of the AsyncInterfaces NuGet packages allowed Simple Injector v5.0 to start using the <code>IAsyncDisposable</code> interface. This allowed Simple Injector to asynchronously dispose of classes implementing <code>IAsyncDisposable</code>. It also allowed users to dispose of both <code>Scope</code> and <code>Container</code> in an asynchronous fashion.</p>
<p>Historically, the Simple Injector core library hasn’t taken a dependency on an external NuGet package. And for good reason. Because external dependencies can cause conflicts, such as those pesky binding-redirect issues that we’re all too familiar with. This is an unfortunate restriction and there have been many times I wished I could just pull in some external package to simplify my work. The very useful <a href="https://www.nuget.org/packages/System.Collections.Immutable">System.Collections.Immutable</a> package is one such example.</p>
<p>Unfortunately, there is no easy way of allowing Simple Injector to asynchronously dispose of registered types without taking a dependency on AsyncInterfaces. This left me with two options:</p>
<ol>
<li>Add this dependency to the core and implement asynchronous disposal directly in the core library</li>
<li>Create a new NuGet package (e.g., <code>SimpleInjector.Async</code>) that adds extensions that allow asynchronous disposal of <code>Scope</code> and <code>Container</code>.</li>
</ol>
<p>I decided to go with the first option as the second would result in a less discoverable solution. The former option allows implementing <code>IAsyncDisposable</code> directly on <code>Container</code> and <code>Scope</code>; the latter would likely rely on extension methods, to allow something similar to the following: <code>await scope.AsAsyncDisposable().DisposeAsync();</code>.</p>
<p>This new feature was <a href="https://github.com/simpleinjector/SimpleInjector/issues/791">implemented</a> and introduced in <a href="https://blog.simpleinjector.org/2020/06/simple-injector-v5/">Simple Injector v5</a>. This is when the trouble started.</p>
<h2 id="diamonds-are-forever">Diamonds are forever</h2>
<p>Within a few days of the release of v5, developers <a href="https://github.com/simpleinjector/SimpleInjector/issues/823">began</a> reporting binding-redirect issues. This was caused by the multitude of versions that exist for the AsyncInterfaces package and its dependencies. Developers were using other libraries and framework parts that took a dependency on AsyncInterfaces, or its dependencies <a href="https://www.nuget.org/packages/System.Threading.Tasks.Extensions">System.Threading.Tasks.Extensions</a> and <a href="https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe">System.Runtime.CompilerServices.Unsafe</a>. When one of the used application dependencies references a different version of such package (and in particular when the package’s contained assembly has a different assembly version) binding-redirect issues can appear.</p>
<p>In an ideal world, the NuGet package manager automatically solves binding-redirect issues for us by adding the required plumbing in the application’s configuration file. But for some reason, the package manager fails to do this. Instead, we have to manually add binding redirects to our configuration files. And this seems especially confusing with regards to AsyncInterfaces and its sub dependencies, as their assembly versions do not match the NuGet package version. The dependency chain of AsyncInterfaces seems to be in <a href="https://nickcraver.com/blog/2020/02/11/binding-redirects/">the list of common troublemakers</a>.</p>
<p>With the introduction of .NET Core, there’s the idea that binding-redirect issues are thing of the past. A <a href="https://github.com/simpleinjector/SimpleInjector/issues/823#issuecomment-726143424">more-recent bug report</a>, however, demonstrated that this isn’t always the case, demonstrating that these issues won’t easily go away if we wait long enough.</p>
<p>The pain experienced with these dependencies can be solved by setting the correct binding redirects in the application’s configuration file. To help Simple Injector users, I started posting binding direct examples that developers could copy-paste to fix their problem. But even using these examples, developers struggled, and I recently got stuck with this on an application I was developing. Whatever binding redirects I tried, after analyzing the assembly versions of the used NuGet packages, the application would crash with a dreaded “Could not load file or assembly X or one of its dependencies” exception. This was the moment that I started to realize the gravity of this Diamond Dependency dilemma that AsyncInterfaces and his little helpers caused. Action was required. This instigator had to go.</p>
<blockquote>
<p><strong>Diamond Dependency</strong></p>
<p>My application took a dependency on both Simple Injector and System.Collections.Immutable. Those two libraries, however, both depended (indirectly) on the previously mentioned CompilerServices.Unsafe. Simple Injector did so via AsyncInterfaces and Tasks.Extensions, while Immutable depended on CompilerServices.Unsafe via <a href="https://www.nuget.org/packages/System.Memory">System.Memory</a>. This is an example of a Diamond Dependency.</p>
<p>A Diamond Dependency is a dependency chain of at least four libraries where library A (e.g. my application) depends on libraries B (Simple Injector) and C (Immutable). B and C than depend on the final library D (Unsafe). A problem emerges when those middle libraries require different versions of this final library D. This is called the Diamond Dependency Conflict.</p>
</blockquote>
<h2 id="if-it-quacks-like-a-duck">If it quacks like a duck</h2>
<p>But removing the AsyncInterfaces dependency was easier said than done. Removing the asynchronous disposal feature was not an option; developers already depend on that feature, often—but not always —implicitly by using one of the ASP.NET Core integration packages. And we can certainly expect asynchronous disposal to become more common soon, long before the Diamond Dependency problem will disappear (i.e. before Simple Injector can drop support for .NET 4 and .NET Core 2).</p>
<p>Over the last 6 months I have conducted two experiments that tried duck typing to allow removing the AsyncInterfaces dependency from the core library. With duck typing, instead of depending on interfaces, you take a more dynamic approach where you accept any type that conforms to a certain signature. The C# compiler takes this approach in many places, for instance with the <code>foreach</code>, <code>using</code>, and <code>async using</code> keywords. Both trials were discontinued because of the complexity they would introduce into the library, especially when taking performance into consideration. But after I recently experienced the seriousness of the situation myself, I knew removing the party crasher was the only viable solution to this problem. And so, I had to release the Quacken!</p>
<p>After multiple days of trying, failing, testing, improving, <a href="https://stackoverflow.com/questions/65200662/">asking</a>, things started to quack like duck. The meat and potatoes of the implementation is inside the <code>Scope</code> class (which now is littered with compiler directives). <code>Scope</code> now does the following:</p>
<ul>
<li>It tries to figure out if a tracked instance implements an interface named “System.IAsyncDisposable”. Whether that interface is The Real Thing ™ or just some self-defined surrogate is irrelevant. If the instance implements that interface, it is stored for disposal, as would happen for ‘normal’ <code>IDisposable</code> instances.</li>
<li>During asynchronous disposal of the <code>Scope</code>, the <code>Scope</code> will invoke the instance’s <code>DisposeAsync</code> method. The returned object (typically <code>Task</code> or <code>ValueTask</code>) will be awaited.</li>
</ul>
<p>Of course, performance must be taken into consideration, considering that Reflection calls are slow. Such a performance penalty would perhaps be acceptable during disposing of the <code>Container</code>, but certainly not when disposing of a <code>Scope</code>, as an application might create and dispose of thousands of <code>Scope</code> instances per second. And so <code>Scope</code> implements the following caching:</p>
<ul>
<li>Whether a checked type implements <code>IAsyncDisposable</code> or not. This way only one call to <code>Type.GetInterfaces().Where(i => i.FullName == "System.IAsyncDisposable")</code> is required.</li>
<li>When the <code>IAsyncInterface</code> is detected for the first time, it will be stored internally. This allows any subsequent checks to call <code>asyncDisposableType.IsAssignableFrom(type)</code> instead of the slower <code>GetInterfaces().Where(...)</code> again.</li>
<li>The call to <code>IAsyncDisposable.DisposeAsync().AsTask()</code> is compiled using expression trees, just as the rest of Simple Injector does for object composition under the covers. This makes calling <code>DisposeAsync</code> (almost) as fast as a native interface call. The .NET Standard 2.1 version, btw, completely skips all this duck typing nonsense and just natively calls <code>IAsyncDisposable</code> because, as I mentioned previously, with .NET Core 3 that interface is recognized natively.</li>
</ul>
<p>The greatest disadvantage of this approach, from a user’s perspective, is that I had to remove the <code>DisposeAsync</code> methods from <code>Container</code> and <code>Scope</code> in the pre-.NET Standard 2.1 builds. Because not only did the removal of AsyncInterfaces mean no reference to <code>IAsyncDisposable</code>, it also removed the reference to <code>ValueTask</code>, which the <code>IAsyncDisposable.DisposeAsync</code> method returns. For a while I played with the idea of the other builds to have an <code>DisposeAsync</code> method that would simply return <code>Task</code>. This would allow developers to use C#’s <code>async using</code> syntax on <code>Container</code> and <code>Scope</code>. But I quickly realized that the different signature of the <code>DisposeAsync</code> method (the return type is part of the signature) would cause <code>MissingMethodExceptions</code>.</p>
<p>To prevent incompatible signatures, while still allowing both the <code>Container</code> and <code>Scope</code> to be disposed of asynchronously, methods with completely different names needed to be added. This is why you’ll find <code>DisposeContainerAsync()</code> and <code>DisposeScopeAsync()</code> methods on <code>Container</code> and <code>Scope</code> respectively. I’m the first to agree that this is bats-ugly, but it’s the best I could come up with.</p>
<p>On the flip side, however, because of the use of duck typing, Simple Injector can now support asynchronous disposal <em>on all of its builds</em>. Where previously asynchronous disposal was only supported on the <code>net461</code> and <code>netstandard2.0</code> builds of Simple Injector, with the introduction of Simple Injector v5.2, asynchronous disposal is supported on <code>net45</code> and <code>netstandard1.0</code> as well. Although its not possible to reference AsyncInterfaces’ <code>IAsyncDisposable</code> in your application, you can simply define <code>System.IAsyncDisposable</code> somewhere in your application, and it just works. Here’s an example:</p>
<pre><code class="language-c#">namespace System
{
public interface IAsyncDisposable
{
Task DisposeAsync();
}
}
</code></pre>
<p>Even though the official <code>IAsyncDisposable</code> interface exposes <code>ValueTask</code> rather than <code>Task</code>, Simple Injector accepts this alternative definition anyway. As long as the interface is called “System.IAsyncDisposable” and there’s a method named “DisposeAsync” which either returns <code>Task</code> or <code>ValueTask</code>, everything will just run smoothly. This allows you to start using asynchronous disposal until you can migrate to your code base to .NET Core 3 or .NET 5.</p>
<p>All the sweat and tears I poured over my keyboard in the past weeks to get this fixed are now dried up and materialized in the Simple Injector code <a href="https://github.com/simpleinjector/SimpleInjector/releases/tag/5.2.0">v5.2</a> code base. This will certainly not fix all your binding-redirect issues but will at least ensure that Simple Injector is not amplifying the problem any longer.</p>
<p>Happy injecting.</p>
</div>
<div class="post">
<div class="post-heading">
<h1><a href="/2020/06/simple-injector-v5/">Simple Injector v5 - Virus edition</a></h1>
<span>Jun 11, 2020 by Steven</span>
</div>
<p>It’s been 10 years since the birth of Simple Injector, and three years since we released Simple Injector 4.0. The number of features that mean bumping the major version number have been piling up on the backlog, and so we started work on the next major release a few months ago. And it’s finally here! We’ve removed legacy methods, improved performance, fixed bugs, added features, and continued to push the library towards a <a href="https://simpleinjector.org/principles+best-practices">strategy of best-practice</a>.</p>
<p><strong>There are quite a few breaking changes, which will likely impact you when migrating from v4 to v5. There are two changes in particular that you should be aware of: the handling of unregistered concrete types and auto-verification. Please read on to understand what has changed and why.</strong></p>
<p>In this blog post I describe the most prominent changes and their rational, starting with how v5 stops resolving unregistered concrete types.</p>
<h3 id="unregistered-concrete-types-are-no-longer-resolved">Unregistered concrete types are no longer resolved.</h3>
<p>Simple Injector has always promoted best practices, and this is an evolving process. Over the years, for instance, we figured out it was better to require:</p>
<ul>
<li>an active scope for resolving scoped instances</li>
<li>collections to be registered, even if empty</li>
<li>container-uncontrolled collections to be wrapped with transient decorators solely</li>
</ul>
<p>These insights where gained during the development process and for each we decided to introduce a breaking change because we felt the breaking change was worth it.</p>
<p>Resolving unregistered concrete types is a similar case. While the ability to resolve and inject unregistered types can be an appealing concept, we have noticed that developers often trip over this behavior. In the past, we have introduced new verification features (such as the <a href="https://simpleinjector.org/diasc">Short-Circuited Dependencies diagnostic warning</a>) to help reduce issues but errors still occur.</p>
<p>Changing this behavior has been long on my radar and is something I <a href="https://github.com/simpleinjector/SimpleInjector/issues/377">discussed</a> with the other contributors even before the release of v4—over three years ago. Unfortunately, at that time, we were too close to the release of v4 and needed more time to assess the impact to our users. That’s why we postponed the change to v5. Instead, we introduced a switch in v4 that allowed disabling this behavior and started promoting disabling this behavior in the documentation. This would allow new users and new projects to use the new settings and existing users to migrate at their own pace.</p>
<p>With the introduction of v5, we flipped the switch, meaning that resolution of unregistered concrete types is now disabled by default. We advise you keep the default behavior as-is and ensure you register all concrete types directly. If your current application heavily depends on unregistered concrete types being resolved, you can restore the old behavior by setting <code>Container.Options.ResolveUnregisteredConcreteTypes</code> to <code>true</code>. For more details, check <a href="https://simpleinjector.org/ructd">the documentation</a>.</p>
<p>But this is not the only big change we made. Another important change that will likely impact you is auto verification.</p>
<h3 id="the-container-is-now-automatically-verified-when-first-resolved">The container is now automatically verified when first resolved.</h3>
<p>Just as it’s a good idea to explicitly register all types up front, we have learned that it is a good idea to trigger container verification automatically on first resolve.</p>
<p>Many developers using Simple Injector don’t realize its full potential and forget to call <code>Container.Verify()</code>. We often see developers run into problems that a call to <code>Verify()</code> would have prevented. This is why in v5 we decided to automatically trigger full verification including diagnostics when the very first registration is resolved.</p>
<p>This wasn’t an easy call, though, and is a <strong>severe breaking change</strong>. It’s severe, because the change in behavior can be easily overlooked.</p>
<p><strong>When upgrading to Simple Injector v5, check whether your code base deliberately skips verification because of performance concerns.</strong> And when this is the case, you should suppress auto verification.</p>
<p>There are two likely scenarios where you would want to suppress verification:</p>
<ul>
<li><strong>Running integration tests where each test creates and configures a new <code>Container</code> instance.</strong> In that case verifying the container in each test might cause the integration test suite to slow down considerably because <code>Verify()</code> is a costly operation.</li>
<li><strong>Running a large application where start-up time is important.</strong> For big applications, the verification process could take up a considerate amount of time. In such a case you would prevent the application from verifying on startup, and instead move the <code>Verify</code> call to a unit/integration test. That allows fast application start-up.</li>
</ul>
<p>Disabling auto-verification can be done by setting <code>Container.Options.EnableAutoVerification</code> to <code>false</code>.</p>
<p>Although auto verification and disabled unregistered-type resolution are the two changes that will impact most users, there are other changes, such as the discontinued support for .NET 4.0.</p>
<h3 id="no-more-net-4-0">No more .NET 4.0</h3>
<p>We have dropped support for .NET 4.0: <strong>the minimum supported versions are now .NET 4.5 and .NET Standard 1.0.</strong></p>
<p>.NET 4.0 was released on 12 April 2010, which is more than a decade ago. It has been superseded with .NET 4.5 on 15 August 2012—now almost 8 years ago. It’s time to let go of .NET 4.0, even though there may be some Simple Injector users that are stuck to .NET 4.0.</p>
<p>Developing software is always about finding a balance. Keeping older versions supported comes with costs—even for an open-source project. Perhaps even <em>especially</em> for open-source projects where development is done in free time (and free time is precious).</p>
<p>The introduction of support for .NET Standard introduced complexity in the library, caused by the changing Reflection API. This new Reflection API was later added to .NET 4.5, but that lead to the use of <code>#if</code> preprocessor directives, additional build outputs and risk of introducing errors. This is complexity we wanted to get rid of, but that meant ditching support for .NET 4.0.</p>
<p>This comes with the risk of frustrating developers that maintain old applications and still want to enjoy improvements in Simple Injector. We’re truly sorry if this frustrates your project, and hope that Simple Injector v4 serves you well until you can migrate to .NET 4.5 and beyond.</p>
<p>If you feel frustrated by the removal of .NET 4.0, perhaps the next change will cheer you up.</p>
<h3 id="less-first-chance-exceptions">Less first-chance exceptions</h3>
<p>More recently, Microsoft made some changes to Visual Studio that have impacted Simple Injector users. One of those changes is how Visual Studio handles first-chance exceptions by default.</p>
<p>When debugging an application, not all exceptions have to be dealt with. When a third-party or framework library catches an exception and continues, you can safely ignore that exception. Where older versions of Visual Studio didn’t show these exceptions by default, newer versions of Visual Studio automatically stop the debugger and popup the exception window. This can be really confusing because it’s not always immediately clear whether the first-chance exception is being dealt with by the library component or is one that breaks your application. Admittedly, I have wasted many hours because of this, because even Microsoft libraries throw exceptions that they recover from themselves!</p>
<p>In Simple Injector 4, there are times where the library would throw an exception that it caught elsewhere and handled itself. This design worked well in the older versions of Visual Studio. But since stopping at first-chance exceptions is the new norm, the behavior is problematic for our users. Not only does it cause confusion, getting those constant exception popups during startup can be really annoying.</p>
<p>In v5 we changed the APIs that would throw and catch exceptions. They now follow the ‘try-parse’ pattern and return a <code>boolean</code>. This does mean, however, it’s a breaking change. In case you have a custom <code>IConstructorSelectionBehavior</code> or <code>IDependencyInjectionBehavior</code> implementation, you will need to change your implementation.</p>
<p>It was impossible for us to completely remove all first-chance exceptions from the library and there are still edge cases where exceptions are caught—most notably in the generics sub system. There are some situations where Simple Injector can’t correctly determine generic type constraints, which means that it relies on the framework to communicate the existence of such a constraint. This part of the .NET Reflection API lacks a ‘try-parse’ API and we’re stuck with catching exceptions (there currently is a <a href="https://github.com/dotnet/runtime/issues/28033">proposal</a> to add such method in .NET 5.0, but untill now the Microsoft team is not very supportive). The chances, however, of you hitting this are very slim, because it only happens under very special conditions.</p>
<h3 id="simplified-registration-of-disposable-components">Simplified registration of disposable components</h3>
<p>When it comes to analyzing object graphs, Simple Injector always erred on the side of safety.</p>
<p><a href="https://simpleinjector.org/dialm">Lifestyle Mismatches</a> (a.k.a. Captive Dependencies) are, by far, the most common DI pitfall to deal with. Detecting these mismatches is something Simple Injector had done for a very long time now. Simple Injector prevents you from accidentally injecting a short-lived dependency into a longer-lived consumer.</p>
<p>Simple Injector considers a Transient component’s lifetime to be shorter than that of a Scoped component. This is because a single <code>Scope</code> could theoretically live for a very long time. If you wish, you could leave your scope open for the complete duration of a long-running operation or even for the duration of the application, which would make an injected Transient component live for as long as well. This is the reason the injection of a Transient into a Scoped was blocked by default and reported by the Simple Injector’s Diagnostics sub system.</p>
<p>In practice, however, scopes are usually wrapped around a single (web) request, which makes their lifetime very limited and deterministic. In these cases, injecting a Transient into a Scoped is relatively risk-free.</p>
<p>Additionally, the Transient lifestyle also behaves quite differently compared to the Scoped lifestyle. Transient components are not tracked by Simple Injector and, therefore, can’t be disposed of. You likely encountered the <em>”{your class} is registered as transient but implements IDisposable”</em> error before. Registering it as Scoped fixes the issue but would cause the Lifestyle Mismatch error when that registration contains Transient dependencies.</p>
<p>Because of the low risk of injecting a Transient into a Scoped, this strict behavior causes more confusion and frustration than that it prevents errors and is why we have decided to relax this behavior. By default, Simple Injector v5 allows you to inject transients into Scoped components. If you would prefer to revert to the old behavior you can set <code>Container.Options.UseStrictLifestyleMismatchBehavior</code> to <code>true</code>.</p>
<h3 id="performance-performance-performance">Performance, performance, performance</h3>
<p>Simple Injector has historically always been one of the top performers when it comes to speed of resolving. Very early on we decided that performance is a feature and were able to have great performance while adding new features.</p>
<p>We’re now at a practical limit of what’s achievable from a performance perspective. There are areas where performance can theoretically be improved, but it has no practical use, because you wouldn’t notice the difference when running a real application.</p>
<p>There is one area, however, where performance could still be improved, and this is startup time. As I discussed above, registering and verifying a big application can take a considerable amount of time. While running a performance analysis during the development of v5, we noticed a few hotspots that caused a considerable slowdown in performance during the registration phase. These were due to using some of the slower Reflection calls. After building an optimized POC, we noticed a performance boost of up to 60%, which is very significant, especially for big applications.</p>
<p>Unfortunately, this improvement meant we had to introduce a breaking change. But the performance gain is significant, and we felt it worth the risk. Only few developers will be affected by this change. <strong>You will only be affected by this breaking change if you’ve created your own lifestyles.</strong> If this is the case, please review the release notes closely to see what we’ve changed.</p>
<h3 id="asynchronous-disposal">Asynchronous disposal</h3>
<p>Another great improvement is the ability for Simple Injector to asynchronously dispose registered components. The ASP.NET Core integration package in Simple Injector v4 made sure that components implementing <code>IAsyncDisposable</code> were disposed at the end of a web request. This, however, only worked within the context of a web request, and only components could be disposed that implemented both <code>IAsyncDisposable</code> <em>and</em> <code>IDisposable</code>, which might not always be the case.</p>
<p>In v5 we have now integrated this feature into the core library. Not only did this simplify the ASP.NET integration package and remove the <code>IDisposable</code> limitation, it also means that asynchronous disposal is available everywhere. For example, when running background operations in ASP.NET Core, or when running a Console Application.</p>
<p>The v5 ASP.NET Core integration package automatically calls <code>Scope.DisposeAsync()</code> when a web request ends. In other cases, you will need to call <code>Scope.DisposeAsync()</code> manually (or use the new C# <code>async using</code> keyword).</p>
<p><strong>Please note that this feature is only available in the .NET 4.6.1, .NET Standard 2.0, and .NET Standard 2.1 versions of Simple Injector.</strong></p>
<h3 id="metadata">Metadata</h3>
<p>The last big new feature is the ability to inject a dependency’s metadata into a consumer. In v5 you can now write this:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Foo</span>
{
<span style="color:#66d9ef">public</span> Foo(DependencyMetadata<IDependency> metadata) { }
}
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Bar</span>
{
<span style="color:#66d9ef">public</span> Bar(IList<DependencyMetadata<IDependency>> metadata) { }
}</code></pre></div>
<p>The class <code>Foo</code> will receive a <code>DependencyMetadata<T></code>, which is a new Simple Injector type. This metadata gives access to the dependency’s <strong>InstanceProducer</strong>, its implementation type, and allows the type to be resolved by calling <strong>GetInstance()</strong>.</p>
<p>The example’s <code>Bar</code> class, on the other hand, receives a list of <code>DependencyMetadata<T></code> instances, which is useful for the injection of lists of dependencies.</p>
<p>Admittedly, this is a rather advanced feature that not many users will need. It’s meant to be used <em>inside</em> infrastructure components (i.e. classes that are part of the <a href="https://mng.bz/K1qZ">Composition Root</a>). Infrastructure components sometimes require more information about the dependency and need to be able to lazily resolve it. The feature is <em>not</em> meant to be used <em>outside</em> the Composition Root, because that would cause your application to take a dependency on Simple Injector, which is something we advise against.</p>
<p>For a more elaborate example of this this feature, see <a href="https://simpleinjector.org/advanced+metadata">the documentation</a>.</p>
<p>For a complete list of all the breaking changes, new features and bug fixes, please view the <a href="https://github.com/simpleinjector/SimpleInjector/releases/tag/v5.0.0">release notes</a>.</p>
</div>
<div class="post">
<div class="post-heading">
<h1><a href="/2017/03/simple-injector-v4-has-been-released/">Simple Injector v4 has been released</a></h1>
<span>Mar 31, 2017 by Steven</span>
</div>
<p>For the last months we’ve been working on the next major release of Simple Injector, and it is finally here. We have removed legacy methods, simplified working with the library, and fixed many bugs and quirks.</p>
<p><strong>In contrast to the impact that v3 had for developers, we expect most developers to update without having to make any code changes when upgrading from the latest v3.x to v4.0.</strong> There are quite some breaking changes through, but most of them are in more specialized parts of the library that you use when extending Simple Injector, such as writing custom Lifestyles, which is something most developers don’t do.</p>
<p>Our goal has always been to let the API guide you as much as possible through the breaking changes and how to fix them. In most cases removed parts of the API still exist, but are marked with [Obsolete(error: true)] attribute with expressive messages that explain what to do instead. This will cause your compiler to show a compilation error with (hopefully) a clear message describing the action to take. This should make it easier for you to migrate from v3.x to v4.0.</p>
<p><strong>Before you upgrade to v4.0, please make sure you upgrade to the latest v3.x version of Simple Injector first.</strong></p>
<p>With the release of v4.0 we moved to <a href="https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/">.NET Standard</a> in favour of PCL. This means we removed support for PCL in version 4. Since most new platforms embrace the new .NET Standard, this shouldn’t be a problem. As long as your platform supports .NET Standard, Simple Injector v4 will run happily.</p>
<h3 id="new-features">New Features</h3>
<p>With this release we introduced many small and big simplifications to the API, some of which are:</p>
<ul>
<li>The integration of the common <code>LifetimeScopeLifestyle</code> and <code>ExecutionContextScopeLifestyle</code> as part of the core library. These lifestyles have been renamed to the more obvious <code>ThreadScopedLifestyle</code> and <code>AsyncScopedLifestyle</code>, and the old SimpleInjector.Extensions.* NuGet packages have been deprecated.</li>
<li>The deprecation of framework-specific lifestyles <code>WebApiRequestLifestyle</code> and <code>AspNetRequestLifestyle</code> in favor of the new built-in <code>AsyncScopedLifestyle</code>.</li>
<li>The automatic and transparent reuse of registrations for classes that are registered with multiple interfaces. Simple Injector detected these kinds of problems, calling them <a href="https://simpleinjector.org/diatl">Torn Lifestyles</a>, but in Simple Injector v4 we completely removed this problem altogether, making it something the user hardly ever has to think about.</li>
<li>Several overloads added to simplify common scenarios.</li>
</ul>
<p>On top of that, we removed some small parts of the API that could cause ambiguity and could lead to hidden, hard to detect errors. In some situations, e.g. when making conditional registrations, the user was able to make decisions on the service type of the consuming component, but this was unreliable, because such component could be registered with multiple interfaces. This could make the conditional registration invalid, where it was impossible for Simple Injector to warn the user about this. We removed these ambiguous properties and force the user to use the property containing the implementation type instead. We added some convenient extension methods on System.Type to make it easier to extract an abstraction from such implementation type, namely: <code>IsClosedTypeOf<T></code>, <code>GetClosedTypeOf<T></code> and <code>GetClosedTypesOf<T></code>.</p>
<p>We improved the Diagnostic sub system once more. The biggest improvement is the detection of <a href="https://simpleinjector.org/diasc">Short Circuited Dependencies</a>. This is something that we were doing since v2, but there were situations in the past where Short Circuited Dependencies weren’t detected. We fixed that in this release.</p>
<p>For a complete list of all the breaking changes, new features and bug fixes, please view the <a href="https://github.com/simpleinjector/SimpleInjector/releases/tag/v4.0">release notes</a>.</p>
</div>
<div class="post">
<div class="post-heading">
<h1><a href="/2016/07/working-around-the-asp-net-core-di-abstraction/">Working around the ASP.NET Core DI abstraction</a></h1>
<span>Jul 6, 2016 by Steven and Peter</span>
</div>
<p>For the last couple of years, Microsoft has been building the latest version of the .NET platform, branded .NET Core. One of the core components of this new framework is a DI library. Unfortunately, Microsoft made the mistake of defining a public abstraction for its DI library. In our <a href="/2016/06/whats-wrong-with-the-asp-net-core-di-abstraction/">previous blog post</a> we described why the existence of this abstraction leads to all sorts of problems.</p>
<p>The goal of this blog post is to explain how you can effectively limit exposure to this abstraction and instead apply proven practices that promote structure, design and maintainability within your application. The summary of this blog post is the following:</p>
<p><strong>TLDR;</strong></p>
<blockquote>
<p>Refrain from using a self-developed or third-party provided adapter for the .NET Core DI abstraction. Isolate the registration of application components from the framework and third-party components. Pursue a SOLID way of working and allow your application registrations to be verified and diagnosed by Simple Injector, without concern for incompatibilities with the framework and third-party components.</p>
</blockquote>
<p>Microsoft wants its users to start off using the default container and then replace, if you want, with a third-party DI library. This advice of having one container instance that builds up both framework components, third-party components and application components stems from the idea that it is useful for framework components to be injected into application components. Having a single container makes it easy for the container build up object graphs that are a mixture of application and framework components.</p>
<p>Although developers might find this appealing, it’s important to realize that this a violation of the <a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion Principle</a> (DIP), which states that:</p>
<blockquote>
<p>abstracts are owned by the upper/policy layers.</p>
</blockquote>
<p>In other words, in order to conform to the DIP, your application code should not depend on framework abstractions. Typically, code that depends on framework abstractions should exist wholly in the <a href="https://freecontent.manning.com/dependency-injection-in-net-2nd-edition-understanding-the-composition-root/">Composition Root</a>. The DIP and <a href="https://en.wikipedia.org/wiki/Interface_segregation_principle" title="Interface Segregation Principle">ISP</a> promote the use of abstractions tailored to your application’s needs and the creation of adapter implementations. Instead of having a framework or external library dictate the size and shape of abstractions, the application under development should define what’s best for its particular needs. Not only does this result in clean and testable code, it makes the code more flexible and reusable.</p>
<p>The <a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a> principles are of great guidance here, and since the DIP states that your application (upper) layer should only depend on its own abstractions, building up mixed object graphs is an anti-pattern. Having one container build up mixed object graphs leads developers to violate the SOLID principles and will undoubtedly cause pain in the long run.</p>
<p>Instead of aiming for one DI library that builds everything up (one container to rule them all), you should keep these two worlds separate: framework components should be built up by the framework’s container, application components should be built up using your container of choice. To integrate or bridge the two worlds you define small focused adapters on each side. Use the framework’s provided extension points to intercept the creation of root types and forward the creation of those types to your container. On the other side of the container divide you define implementations for application-tailored abstractions, which call-back into framework and third-party library code. A well-designed framework will have all the necessary abstractions in place for you to intercept. ASP.NET Core MVC already contains all the required hooks. Third-party tool developers should follow the same practice.</p>
<p>Some developers feel uncomfortable with the notion of two containers in single application. But if you view the built-in framework container as a configuration system for the framework, having an independent container for your own application components is a non-issue. Every framework has its own configuration system. ASP.NET Web Forms has its own configuration system (mainly XML based) and MVC & Web API have their own code-first configuration systems. In a sense, nothing much has changed; ASP.NET Core still has a configuration system, be it one that includes an internal container-like structure. Apparently this container gives them a lot of flexibility, which is great. But we never had the need to completely swap out a framework’s configuration system before, so why should we need to for ASP.NET Core?</p>
<p>So how does this work? If you don’t want to swap out the built-in configuration system for .NET Core, what should you do? As said before, good practice is to use the framework’s supplied extension points and override as necessary to redirect/intercept the creation of certain types.</p>
<p>The main interception point for ASP.NET Core MVC is the <code>IControllerActivator</code> abstraction. This abstraction allows intercepting the creation of MVC controller types. An implementation for Simple Injector is trivial:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">sealed</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">SimpleInjectorControllerActivator</span> : IControllerActivator
{
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">readonly</span> Container container;
<span style="color:#66d9ef">public</span> SimpleInjectorControllerActivator(Container c) => container = c;
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">object</span> Create(ControllerContext c) =>
container.GetInstance(c.ActionDescriptor.ControllerTypeInfo.AsType());
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> Release(ControllerContext c, <span style="color:#66d9ef">object</span> controller) { }
}</code></pre></div>
<p>To replace the built-in controller activator, you configure the Core container:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp">services.AddSingleton<IControllerActivator>(
<span style="color:#66d9ef">new</span> SimpleInjectorControllerActivator(container));</code></pre></div>
<p>Although trivial to implement, we do provide an out-of-the-box implementation for you in our <a href="https://www.nuget.org/packages/SimpleInjector.Integration.AspNetCore.Mvc/">ASP.NET Core MVC integration package</a> to make your life easier. As a matter of fact, over time we will supply you with with all the convenient methods that allow you to make bootstrapping as seamless as possible. We might not provide you with integration packages for all existing frameworks, but plugging in Simple Injector will always be trivial <em>when the designers provided you with the correct interception points.</em></p>
<p>What this means is that all framework components and third-party components can keep being composed by the built-in DI container and your application will register and resolve your components through Simple Injector.</p>
<p>Many developers incorrectly assume that having one container for the framework’s internal configuration and another for the application components will mean re-registering hundreds of framework and third-party library components in the application container, but this is simply not necessary. First of all, as we already established, those registrations shouldn’t be in the application container because no application component should directly depend on those abstractions. Secondly, your application will only need to interact with a handful of those services at most, so you’ll handle the abstractions you are actually interested in. Thirdly, trying to get all the framework’s registrations inside your application container brings you back to square one: back to the Conforming Container with <a href="/2016/06/whats-wrong-with-the-asp-net-core-di-abstraction/">all its complications, downsides, and incompatibilities</a>.</p>
<h2 id="examples">Examples</h2>
<p>Let’s say you have a component that needs access to the <code>HttpContext</code> instance, because you want to extract the name of the user from the current request being executed. Since the <code>HttpContext</code> can be acquired using the <code>Microsoft.AspNetCore.Http.IHttpContextAccessor</code> abstraction, your component requires this abstraction as a constructor argument and your code might look something like this:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">sealed</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CustomerRepository</span> : ICustomerRepository
{
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">readonly</span> IUnitOfWork uow;
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">readonly</span> IHttpContextAccessor accessor;
<span style="color:#66d9ef">public</span> CustomerRepository(IUnitOfWork uow, IHttpContextAccessor accessor)
{
<span style="color:#66d9ef">this</span>.uow = uow;
<span style="color:#66d9ef">this</span>.accessor = accessor;
}
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> Save(Customer entity)
{
entity.CreatedBy = <span style="color:#66d9ef">this</span>.accessor.HttpContext.User.Identity.Name;
<span style="color:#66d9ef">this</span>.uow.Save(entity);
}
}</code></pre></div>
<p>There are, however, several problems with this approach:</p>
<ul>
<li>The component now takes a dependency on an ASP.NET Core MVC abstraction, which makes it impossible to reuse this component outside the context of ASP.NET Core MVC.</li>
<li>The component has explicit knowledge about how to get the user name for the application.</li>
<li>The code that gets the user name will likely be duplicated throughout the application.</li>
<li>The component becomes much harder to test, because of the <a href="https://c2.com/cgi/wiki?TrainWreck">train wreck</a> in the <code>Save</code> method.</li>
</ul>
<p>One of the main problems is that the <code>IHttpContextAccessor</code> abstraction isn’t designed for the specific needs of this component. The needs of this component are not to access the current <code>HttpContext</code>, its need is to get the name of the user on whose behalf the code is running. We should create a specific abstraction for that specific need:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> IUserContext
{
<span style="color:#66d9ef">string</span> Name { <span style="color:#66d9ef">get</span>; }
}</code></pre></div>
<p>With this abstraction, you can simplify your component to the following:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">sealed</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CustomerRepository</span> : ICustomerRepository
{
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">readonly</span> IUnitOfWork uow;
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">readonly</span> IUserContext userContext;
<span style="color:#66d9ef">public</span> CustomerRepository(IUnitOfWork uow, IUserContext userContext)
{
<span style="color:#66d9ef">this</span>.uow = uow;
<span style="color:#66d9ef">this</span>.userContext = userContext;
}
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> Save(Customer entity)
{
entity.CreatedBy = userContext.Name;
uow.Save(entity);
}
}</code></pre></div>
<p>What you have achieved here is that you:</p>
<ul>
<li>Decoupled your component from the framework code; it can be reused outside of ASP.NET.</li>
<li>Prevented this component to have explicit knowledge about how to retrieve the current user’s name.</li>
<li>Prevented this code from being duplicated throughout the application.</li>
<li>Reduced test complexity.</li>
<li>Made the code simpler.</li>
</ul>
<p>Since you have decoupled your component from the framework code, you can now reuse the component. For instance, it’s quite common to want to run part of your code base in a background Windows Service where there is obviously no <code>HttpContext</code>. To make this work you will create an adapter implementation for <code>IUserContext</code> that is specific to the type of application you are building. For your ASP.NET application, you will need an adapter implementation that contains the original code that retrieves the user’s name. For a Windows Service, you might return the name of the system user.</p>
<p>Here’s the adapter implementation for ASP.NET:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">sealed</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AspNetUserContext</span> : IUserContext
{
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">readonly</span> IHttpContextAccessor accessor;
<span style="color:#66d9ef">public</span> AspNetUserContext(IHttpContextAccessor a) => accessor = a;
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> Name => accessor.HttpContext.Context.User.Identity.Name;
}</code></pre></div>
<p>As you can see, this adapter implementation is straightforward, all it does is getting the <code>HttpContext</code> for the current request and the user name is determined from the context, as you saw before.</p>
<p>This component can be registered in your application container as follows:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">var</span> accessor =
app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
container.RegisterSingleton<IUserContext>(<span style="color:#66d9ef">new</span> AspNetUserContext(accessor));</code></pre></div>
<p>The app variable here is ASP.NET Core’s <code>IApplicationBuilder</code>abstraction that gets injected into the <code>Startup.Configure</code> method.</p>
<p>What you see here is that the <code>AspNetUserContext</code> adapter depends directly on the <code>IHttpContextAccessor</code> abstraction. You can do this because <code>IHttpContextAccessor</code> is one of the framework’s abstractions that are known to be registered as Singleton. For most framework and third-party services, however, we will have no idea what lifestyle it is registered with, and therefore, resolving them directly using the <code>ApplicationServices</code> property of <a href="https://docs.asp.net/projects/api/en/latest/autoapi/Microsoft/AspNetCore/Builder/IApplicationBuilder/">IApplicationBuilder</a> is a pretty bad idea.</p>
<p>Due to <a href="https://simpleinjector.org/decisions#dont-allow-resolving-outside-an-active-scope">another design flaw</a>, ASP.NET Core allows resolving Scoped instances through the <code>ApplicationServices</code> property, but returns those components as Singletons! In other words, if you were to request any framework and third-party services through <code>ApplicationServices</code>, the chances are that you would get a stale instance that would break your application at runtime—and ASP.NET Core will not inform you of that error. Instead of throwing an exception, ASP.NET Core will fail silently and leave your application in a potentially invalid state, maybe causing an <code>ObjectDisposedException</code> or worse. This is actually yet another incompatibility with Simple Injector; Simple Injector blocks these types of invalid resolves by throwing an exception.</p>
<p>UPDATE: ASP.NET Core 2.0 mitigates the resolution of Scoped instances from the root container, when running in development mode. However, it will still not detect the resolution of any disposable Transients from the root container. This will still lead to memory leaks.</p>
<p>Instead of using the <code>ApplicationServices</code> property, it would be better to resolve services using the <code>HttpContext.RequestServices</code> property. The following adapter shows an example when dealing with framework dependencies with a lifestyle that is either not Singleton or unknown:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">sealed</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AspNetAuthorizerAdapter</span> : IAuthorizer
{
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">readonly</span> Func<IAuthorizationService> provider;
<span style="color:#66d9ef">public</span> AspNetAuthorizerAdapter(Func<IAuthorizationService> provider)
{
<span style="color:#66d9ef">this</span>.provider = provider;
}
<span style="color:#75715e">// Implementation here
</span><span style="color:#75715e"></span>}</code></pre></div>
<p>This is an adapter for a hypothetical <code>IAuthorizer</code> abstraction. Instead of depending on ASP.NET’s <code>IAuthorizationService</code> directly, this adapter depends on <code>Func<IAuthorizationService></code>, which allows the correctly Scoped service to be resolved at runtime. This adapter can be registered as follows:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp">container.RegisterSingleton(
<span style="color:#66d9ef">new</span> AspNetAuthorizerAdapter(
GetAspNetServiceProvider<IAuthorizationService>(app)));</code></pre></div>
<p>The <code>AspNetAuthorizationAdapter</code> is created and registered as Singleton. The registration makes use of the convenient <code>GetAspNetServicesProvider<T></code> helper method that allows creating the provider delegate:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> Func<T> GetAspNetServiceProvider<T>(IApplicationBuilder app)
{
<span style="color:#66d9ef">var</span> accessor =
app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
<span style="color:#66d9ef">return</span> () =>
{
<span style="color:#66d9ef">var</span> context = accessor.HttpContext
?? <span style="color:#66d9ef">new</span> InvalidOperationException(<span style="color:#e6db74">"No HttpContext"</span>);
<span style="color:#66d9ef">return</span> context.RequestServices.GetRequiredService<T>();
};
}</code></pre></div>
<p>When supplied with an <code>IApplicationBuilder</code> instance, the <code>GetAspNetServiceProvider</code> method will create a <code>Func<T></code> that allows resolving the given service type <code>T</code> from the <code>RequestServices</code> collection according to its proper scope.</p>
<p><strong>NOTE:</strong> With the introduction of ASP.NET Core integration package for Simple Injector v4, we added <code>GetRequestService<T>()</code> and <code>GetRequiredRequestService<T>()</code> extension methods on <code>IApplicationBuilder</code> that allow retrieving request services just like the previous <code>GetAspNetServiceProvider<T>()</code> method does. With the introduction of v4.1, we added the notion of <a href="https://simpleinjector.org/aspnetcore#cross-wiring-asp-net-and-third-party-services">auto crosswiring</a>, which simplifies this process even more.</p>
<h2 id="using-logging-in-your-application">Using logging in your application</h2>
<p>Besides a DI library, .NET Core ships with a logging library out-of-the-box. Any application developer can use the built-in logger abstraction directly in their applications. But should they? If you look at the <a href="https://github.com/aspnet/Logging/blob/1.0.0/src/Microsoft.Extensions.Logging.Abstractions/ILogger.cs"><code>ILogger</code> abstraction</a> supplied to us by Microsoft, it’s hard to deny that the abstraction is very generic in nature and might very well not suit your application’s specific needs. The previous arguments still hold: application code should be in control over the abstraction.</p>
<p>The SOLID principles guide you towards defining an application-specific abstraction for logging. The exact shape of this abstraction will obviously differ from application to application (but look at <a href="https://stackoverflow.com/questions/5646820/logger-wrapper-best-practice">this example</a> for inspiration). Again, a simple adapter implementation can do the transition from application code to framework code:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#75715e">// your application's logging abstraction
</span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> ILog { <span style="color:#66d9ef">void</span> Log(LogEntry e); }
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">sealed</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">DotNetCoreLoggerAdapter</span> : ILog
{
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">readonly</span> Microsoft.Extensions.Logging.ILogger logger;
<span style="color:#66d9ef">public</span> DotNetCoreLoggerAdapter(ILogger logger) => <span style="color:#66d9ef">this</span>.logger = logger;
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> Log(LogEntry e) =>
logger.Log(ToLevel(e.Severity), <span style="color:#ae81ff">0</span>, e.Message, e.Exception,
(s, _) => s);
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> LogLevel ToLevel(LoggingEventType s) =>
s == LoggingEventType.Warning ? LogLevel.Warning :
s == LoggingEventType.Error ? LogLevel.Error :
LogLevel.Critical;
}</code></pre></div>
<p>This <code>DotNetCoreLoggerAdapter</code> can be registered as singleton as follows:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp">container.RegisterSingleton<ILog>(
<span style="color:#66d9ef">new</span> DotNetCoreLoggerAdapter(loggerFactory.CreateLogger(<span style="color:#e6db74">"Application"</span>)));</code></pre></div>
<p>But there are <a href="https://stackoverflow.com/a/41244169/264697">other options</a> when it comes to integrating logging with Simple Injector.</p>
<h2 id="conclusion">Conclusion</h2>
<p>By creating application-specific abstractions, you prevent your code from taking unnecessary dependencies on external code, making it more flexible, testable and maintainable. You can define simple adapter implementations for the abstractions you need to use, while hiding the details of connecting to external code. This allows your application to use your container of choice (and supports a <a href="https://blog.ploeh.dk/2014/06/10/pure-di/">container-less</a> approach). This approach is part of a set of principles and practices that is been taught by experts like Robert C. Martin and others for decades already. Don’t ignore these practices, embrace them and be both productive and successful.</p>
</div>
<div class="post">
<div class="post-heading">
<h1><a href="/2016/06/whats-wrong-with-the-asp-net-core-di-abstraction/">What’s wrong with the ASP.NET Core DI abstraction?</a></h1>
<span>Jun 30, 2016 by Steven and Peter</span>
</div>
<p>For the last couple of years Microsoft has been building the latest version of the .NET platform: .NET Core. .NET Core is a complete redesign of .NET, with the goals of being truly cross-platform and cloud friendly. We’ve been following the development of .NET Core closely and have released .NET Core compatible versions of Simple Injector since RC1. With the release of Simple Injector v3.2 we now officially support .NET Core.</p>
<p>As you may be aware Microsoft has added its own DI library as one of its core components. Some would yell “finally!” The omission of such a component has spawned many open source DI libraries for .NET. Simple Injector obviously being one of them.</p>
<p>Don’t get us wrong here, we applaud Microsoft for promoting DI as a core practice in .NET and it will likely lead to many more developers practicing DI, which is a win for our industry. The problem, however, starts with the abstraction Microsoft has defined on top of their built-in DI container. Compared to the previous <em>Resolve</em> abstractions, such as <a href="https://msdn.microsoft.com/en-us/library/system.web.mvc.idependencyresolver(v=vs.118).aspx">IDependencyResolver</a> and <a href="https://msdn.microsoft.com/en-us/library/system.iserviceprovider(v=vs.110).aspx">IServiceProvider</a>, this new abstraction adds a <em>Register</em> API on top <a href="https://docs.asp.net/projects/api/en/latest/autoapi/Microsoft/Extensions/DependencyInjection/IServiceCollection/">IServiceCollection</a>. With the definition of this abstraction, it is Microsoft’s vision that other (more feature rich) DI libraries could plug-in into the platform, while application developers, third-party tool builders, and framework developers use the standardized abstraction to add their registrations. This would allow application developers a standard for integrating their DI library of choice.</p>
<p>At first sight having an abstraction might seem like sound advice—a common saying in our industry is that there are few problems in software that can’t be solved by adding a (extra) layer of abstraction. In this instance though their reasoning is flawed. DI experts have been warning Microsoft about this problem from the beginning, without success. Mark Seemann quite accurately described the problems with this approach in general <a href="https://blog.ploeh.dk/2014/05/19/conforming-container/">here</a>, where IMO the main points of his reasoning are:</p>
<ul>
<li>It pulls in the direction of the lowest common denominator</li>
<li>It stifles innovation</li>
<li>It makes it more difficult to avoid using a DI container</li>
<li>It introduces versioning hell</li>
<li>If adapters are supplied by contributors, the adapters may have varying quality levels, and may not support the latest version of the <em>Conforming Container</em>.</li>
</ul>
<p>These are real issues we are facing today with the new .NET Core DI abstraction. DI containers often have very unique and incompatible features when it comes to their registration API. Simple Injector, for instance, is very carefully designed in a way that enables the identification of numerous configuration errors. One very prominent example—but there are many more—is Simple Injector’s <a href="https://simpleinjector.org/diagnostics">diagnostic abilities</a>. This is one of the features that is <em>fundamentally</em> incompatible with the expectations that consumers of the DI abstraction will have. So what are the expectations consumers will have of the new abstraction?</p>
<p>Consumers of the DI abstraction can be divided into three groups. Framework components, third-party libraries, and application developers; especially framework components and third-party libraries, which are now expected to add their own registrations through the common abstraction. Because it is nigh on impossible for these two groups of developers to test their code with all the available adapters, they will test their code solely with the built-in container. And while using the built-in container, these developers will (and arguably should) implicitly expect the standardized behaviour of the built-in container—no matter which adapter is used. In other words, it is the built-in container that defines both the contract and the behaviour of the abstraction. Every implemented adapter must be <em>an exact superset</em> of the built-in container. Deviating from the norm is not allowed because it would break third-party tools that depend on the behaviour of the default, built-in container.</p>
<p>Simple Injector’s diagnostic and verification abilities is one of the many features that make Simple Injector users extremely productive. It detects problems that would be detected much later in the development cycle when using a different DI library. But running the diagnostics on both application and third-party registrations will cause problems because it is unlikely that all the external parties will automatically “play nice” with Simple Injector’s diagnostics. There is every chance they will define registrations that Simple Injector finds suspicious even though they have (hopefully) tested the registrations are fine for their specific case with the default container. It would be impossible for a hypothetical adapter for Simple Injector to distinguish between third-party registrations and application registrations.</p>
<p>Switching off diagnostics completely would remove one of Simple Injector’s most important safety nets, whilst leaving the diagnostics system in place would likely cause false-positives from the third-party tooling that would each need to be suppressed by application developers. As these third-party registrations are mostly hidden to the application developer, working around these issues could be daunting, frustrating and sometimes even impossible. One might argue that it would be good for Simple Injector to detect problems with third-party tools, but contacting those same tool developers to explain the “problem” would probably lead to fingers being pointed at us, because we “obviously” provided the user with an “incompatible” adapter.</p>
<p>Simple Injector’s diagnostic abilities is just one of the many incompatibilities that we would face when writing an adapter for .NET Core’s DI abstraction. Other incompatibilities include:</p>
<ul>
<li>The way Simple Injector <a href="https://simpleinjector.org/separate-collections">explicitly separates the registration of collections</a> from one-to-one mappings</li>
<li>How Simple Injector handles open-generic registrations; they are not treated as fall-back registrations as they are by the built-in container</li>
<li>How Simple Injector handles scoping—Scopes in Simple Injector are ambient while .NET Core forces an <a href="https://github.com/aspnet/DependencyInjection/issues/334">ambient-less scoping model</a> (i.e. a <a href="https://blogs.cuttingedge.it/steven/posts/2019/closure-composition-model/">Closure Composition Model</a>).</li>
</ul>
<p>Making a fully compatible adapter for Simple Injector requires removing many prominent features, and thereby changing the existing behaviour of the Simple Injector library to something that would violate the guiding principles that underpin our vision. This is not an attractive solution. Not only would it introduce major breaking changes, it would remove features and behaviours that make Simple Injector unique and it is this complete set of features that many developers love about Simple Injector. In this sense having an adapter “stifles innovation” as Mark Seemann describes.</p>
<p>With Simple Injector we made many innovations and not only would the adapter make Simple Injector almost useless to our users, it would restrict us from future improvement and innovation. Some might view Simple Injector’s philosophy as radical, but we think otherwise—we designed Simple Injector in a way that we think serves our users best. And the <a href="https://www.nuget.org/packages/SimpleInjector/">NuGet download count</a> on the Simple Injector package indicates that many developers agree with us. Conforming to the defined <em>Register</em> API would prevent us from serving our users.</p>
<p>Although Simple Injector’s view may diverge from the norm more than most other containers, the simple act of defining this common abstraction blocks future DI libraries with an even more radical or innovative viewpoint from being used at all—it stifles innovation for future libraries. Just imagine one of the other containers introducing the same kind of verification that Simple Injector provides? Such feature can’t be introduced without breaking the contract of the DI abstraction. The mere act of having such an adapter blocks progress in our industry.</p>
<p>With this explanation, we hope we’ve also made it clear that Microsoft’s DI abstraction isn’t even the lowest common denominator, because the lowest common denominator implies compatibility with all DI libraries! As we expressed <a href="https://github.com/simpleinjector/SimpleInjector/issues/41">here</a> the chances are that none of the existing DI libraries are fully compatible with the defined abstraction. The Autofac maintainers for instance, <a href="https://www.paraesthesia.com/archive/2016/06/29/netcore-rtm-where-is-autofac/">realized</a> they have some quite severe incompatibility issues and eventually <a href="https://github.com/aspnet/DependencyInjection/pull/416#issuecomment-231773011">came to the same conclusion</a> as <a href="https://github.com/aspnet/DependencyInjection/pull/416#issuecomment-231736332">we did</a>. The Autofac maintainers <a href="https://github.com/autofac/Autofac.Extensions.DependencyInjection/issues/15#issuecomment-313723053">publically stated</a> that their adapter is not 100% compatible with Microsoft’s DI abstraction:</p>
<blockquote>
<p>there will definitely be behavior differences between the Autofac DI container and the Microsoft DI container. We’re not trying to behave identically – if you choose to use Autofac as your backing container, you’re also choosing the Autofac behaviors. The difference in behavior you found is one of probably many</p>
</blockquote>
<p>But while application developers do explicitly choose to use a particular container, like Autofac, framework and third-party library developers don’t. And when those latter developers depend on abstraction behavior that Autofac implements differently, it can break the application in very subtle ways.</p>
<p>Considering that Microsoft’s DI Container is heavily influenced by Autofac’s design, it is a telling sign that even Autofac can’t comply with the abstraction.</p>
<p>A <a href="https://jeremydmiller.com/2017/09/11/proposal-for-structuremap-5/">similar story</a> comes from the maintainer of StructureMap that stated:</p>
<blockquote>
<p>ASP.Net Core DI compliance has been a huge pain in the ass to the point where I’ve openly wondered if the ASP.Net team has purposely tried to sabotage and wipe out all the existing ecosystem of IoC containers</p>
</blockquote>
<p>UPDATE: Other maintainers of DI containers are also starting to notice how the new DI abstraction is stifling innovation. The developer of the <a href="https://www.lightinject.net/">LightInject</a> DI Container, for instance, had to completely disable one of its library’s compelling features to allow his adapter to be used in a vanilla ASP.NET Core v2.2 application, to prevent it from <a href="https://github.com/aspnet/Extensions/issues/686">completely crashing</a> at startup.</p>
<p>UPDATE (2019-09): Due to <a href="https://github.com/castleproject/Windsor/issues/120">similar incompatibilities</a> with the built-in container, the Castle Windsor maintainers were forced to take a <a href="https://github.com/castleproject/Windsor/blob/master/docs/aspnetcore-facility.md">similar integration approach</a> to ours, which we describe in our next blog post. In other words, Castle Windsor’s integration works around the ASP.NET Core DI abstraction as well.</p>
<p>This wouldn’t be so bad if Microsoft’s DI library was a feature-rich implementation that contained features like Simple Injector’s verification and diagnostic services so that we all use the same fully featured DI library. Sadly, the implementation is far from feature rich, Microsoft itself has <a href="https://blogs.msdn.microsoft.com/webdev/2014/06/17/dependency-injection-in-asp-net-vnext/">described</a> their implementation as a</p>
<blockquote>
<p>minimalistic DI container [that] is useful in the cases when you don’t need any advanced injection capabilities</p>
</blockquote>
<p>To make matters worse, since the built-in container defines the contract of the abstraction, adding new features to the built-in container will break all existing adapters! Third-party developers who use the abstraction will only test with the built-in container and when their libraries depend on a feature added to the built-in container that is not yet supported by an adapter, things will fail and the application developer is screwed. This is one aspect of the versioning hell that Mark Seemann discusses in his blog post. Not only is their current implementation “minimalistic,” it can never evolve to a feature rich, completely usable DI container, because they’ve painted themselves in a corner: every future change is breaking change that will piss everyone off.</p>
<p>UPDATE (2023-07): This is exactly what happened with the introduction of .NET 8, where Microsoft introduces keyed registrations to their DI Container. This —once more— <a href="https://twitter.com/jeremydmiller/status/1684359969708146688">frustrates</a> maintainers of DI Container adapters, that now all have you upgrade their integration packages, again.</p>
<p>A better solution is to avoid using the abstraction and its adapters entirely. As Mark Seemann quite accurately explained <a href="https://blog.ploeh.dk/2014/05/19/di-friendly-library/">here</a> and <a href="https://blog.ploeh.dk/2014/05/19/di-friendly-framework/">here</a>, reusable libraries and frameworks may not need to use a DI container at all.</p>
<p>Unfortunately, the mere act of defining an abstraction will make it much harder to avoid using it. By defining an abstraction and actively promoting its use, Microsoft is leading thousands of third-party library developers and framework developers to stop thinking about defining the right library and the right framework abstractions (Mark’s articles clearly describes this). They no longer think about this because Microsoft leads them to believe that the whole world needs one common abstraction. We have seen new factory interfaces for MVC appear very late in the game (such as the <a href="https://github.com/aspnet/Mvc/commit/354400f12bf1bb82d364eddb5710bc370384bff4"><code>IViewComponentActivator</code> abstraction</a> prior to RC2). And if we see the MVC team make these kinds of mistakes till very late in the development cycle, what can we expect from all those developers who are starting to build on top of the new .NET platform?</p>
<p>UPDATE: More than three years later, a <a href="https://github.com/aspnet/AspNetCore/issues/8886">similar issue</a> popped up with the new ASP.NET Core 3 Razor Components, where Microsoft forgot to introduce an <code>IComponentActivator</code> abstraction. Although the issue was reported six months before ASP.NET Core 3 was released, Microsoft decided <em>not</em> to add this abstraction, making it impossible for users of containers like Simple Injector and Castle Windsor to integrate with Razor Components. One would have hoped that Microsoft would <a href="https://github.com/aspnet/DependencyInjection/pull/416#issuecomment-232420894">keep its promise</a> to add the “appropriate composition roots” (read: the “required abstractions”). This unfortunately proves that even framework developers stopped thinking about defining the right framework abstractions.</p>
<h2 id="conclusion">Conclusion</h2>
<p>The definition of a DI abstraction is a painful mistake by Microsoft that will haunt us for many years to come. It has already stifled innovation, has introduced versioning hell, and frustrates many developers. The abstraction is incompatible with many, if not all, DI libraries and, against expert advice, Microsoft chose to retain the abstraction, dividing the world into incompatible and partially compatible containers, leading to endless issue reports for the adapter libraries that implement the DI abstraction and third-party libraries that use the abstraction.</p>
<p>Our view is that, as an application developer, you should refrain from using an adapter and in <a href="/2016/07/working-around-the-asp-net-core-di-abstraction/">the next article</a> we will explain more thoroughly how to approach this and why, even with a compatible container, it is the smarter way forward.</p>
<p>Stay tuned</p>
</div>
<div class="post">
<div class="post-heading">
<h1><a href="/2015/12/when-should-you-use-a-container/">When should you use a container?</a></h1>
<span>Dec 6, 2015 by Steven</span>
</div>
<p>A DI container is a tool that allows constructing the graphs of classes that contain an application’s behaviour (a.k.a. components or <a href="http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/">injectables</a>). When you apply Dependency Injection in your systems the DI container can simplify the process of object construction and can, when used correctly, improve the maintainability of the start-up path (a.k.a. the <a href="https://freecontent.manning.com/dependency-injection-in-net-2nd-edition-understanding-the-composition-root/">Composition Root</a>) of your application. But a DI container is not mandatory when you apply Dependency Injection.</p>
<p>Applying Dependency Injection without a DI container is called <a href="https://blog.ploeh.dk/2014/06/10/pure-di/">Pure DI</a>. When you use Pure DI you define the structure of your object graphs explicitly in code and this code is still centralized in the Composition Root just as it is when using a DI container. Dependency Injection does not discourage the use of the <code>new</code> keyword to construct components; it promotes the centralization of the use of the <code>new</code> keyword.</p>
<p>In <a href="https://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/">this</a> article, <a href="https://blog.ploeh.dk/">Mark Seemann</a> shows the advantage of Pure DI over using a container: with Pure DI the compiler can verify the object graph. Mark makes some good points that for smaller applications Pure DI can be more beneficial than the use of containers, while larger applications can take advantage of <a href="https://en.wikipedia.org/wiki/Convention_over_configuration">convention over configuration</a> which can help a lot in making your Composition Root maintainable. Mark even <a href="https://blog.ploeh.dk/2014/06/03/compile-time-lifetime-matching/">shows</a> how Pure DI can help in finding configuration mistakes like <a href="https://blog.ploeh.dk/2014/06/02/captive-dependency/">Captive Dependencies</a>.</p>
<p>The primary benefit of Pure DI is that it allows your code to fail fast (in this case the system fails at compile time). Detecting failures early is crucial when it comes to lowering development cost, because tracking down bugs is obviously much easier in a system that fails fast.</p>
<p>Although I do agree with Mark’s reasoning, it’s important to realize that Pure DI isn’t a silver bullet that detects all configuration mistakes. On the contrary, it’s quite easy to overlook problems such as Captive Dependencies as the Composition Root starts to grow. If you were to switch from a DI container to Pure DI and you were expecting your code to fail fast, you might be in for an unpleasant surprise when the first bugs appear. This can happen because the C# compiler can only do a few simple checks on your behalf, such as:</p>
<ul>
<li>Check whether the number of arguments supplied to a constructor match</li>
<li>Check whether the types supplied to a constructor match</li>
</ul>
<p>The compiler is unable to perform the following checks:</p>
<ul>
<li>Are null values supplied to constructors?</li>
<li>Do constructor invocations fail?</li>
<li>Are dependencies injected into a component with a longer lifetime (the so called Captive Dependencies)?</li>
<li>Are dependencies that are expected to have a certain lifestyle created more than once for the duration of that lifetime? (Problems known as <a href="https://simpleinjector.org/diatl">Torn Lifestyle</a> and <a href="https://simpleinjector.org/diaal">Ambiguous Lifestyle</a>)</li>
<li>Are disposable components not disposed when they go out of scope?</li>
</ul>
<p>All these issues are relatively easy to spot when the number of components in the application is really small, but once that number starts to grow it’s very easy to lose track. A really strict coding style within your Composition Root does help but can easily go wrong when a team of developers is maintaining the Composition Root (opposed to having one single DI expert who has a really close watch on these types of issues).</p>
<p>It’s hard to define a threshold in application size for when a DI container outweighs Pure DI. In the business systems I help create, we almost always use a DI container for the central application (which often is a web application), while using Pure DI for small (background) Windows Services and Console applications as they typically use just a fraction of the total business layer. Once the Composition Root starts to grow, tools that can verify and diagnose the correctness of the Composition Root become extremely valuable.</p>
<p>It is unfortunate that most DI containers have a limited set of capabilities when it comes to verifying their configuration (causing your application to fail silently). Simple Injector deals with all the previously stated issues and more. In Simple Injector it’s just a matter of following <a href="https://simpleinjector.org/howto+verify-the-container-s-configuration">good practices</a> and calling <code>Container.Verify()</code> once you have completed the configuration of the container. Verification of your configuration gives you an increased level of confidence that all known object graphs are wired correctly at application start-up. Simple Injector can give more certainty than Pure DI, while keeping the benefits of, among other things, convention over configuration.</p>
</div>
<div class="post">
<div class="post-heading">
<h1><a href="/2015/08/simple-injector-v3-is-here/">Simple Injector v3 is here!</a></h1>
<span>Aug 18, 2015 by Steven</span>
</div>
<p>After months of preparation and development we have finally released <a href="https://www.nuget.org/packages/SimpleInjector/">Simple Injector v3.0</a>. In version 3 we are breaking from the past: we have removed legacy methods, simplified parts of the API and added some compelling new features.</p>
<p><em><strong>We expect that almost every developer will have to make changes to their composition root when upgrading to v3.</strong> We did our best to make the upgrade process easy but please be prepared to make changes to your code.</em></p>
<p>The driver for making these breaking changes is that parts of the API have evolved over time and in doing so have grown confusing (e.g. <code>RegisterOpenGeneric</code> and <code>RegisterManyForOpenGeneric</code>). In the pursuit of keeping Simple Injector simple we felt obligated to improve the consistency of the API. These decisions have not been taken lightly because we hate breaking your code. Our driving force is, however, a simpler and more compelling library for everyone.</p>
<p>Our goal was to let the API guide you as much as possible through the breaking changes and how to fix them. In most cases removed parts of the API still exist, but are marked with <code>[Obsolete(error: true)]</code> attribute with expressive messages that explain what to do instead. This will cause your compiler to show a compilation error with (hopefully) a clear message describing the action to take. This should make it easier for you to migrate from v2.x to v3.0.</p>
<p><strong><em>Before you upgrade to v3.0, please make sure you upgrade to the latest 2.8 version of Simple Injector first.</em></strong> Some beta testers reported that there were some changes between minor versions of the 2.x branch that broke code and/or unit tests. Upgrading in two steps should make the process much easier.</p>
<p>Besides the clean-up of the API, Simple Injector is now much stricter when it comes to diagnosing your configuration. When calling <code>Verify()</code>, Simple Injector 3 will automatically run its diagnostics and it will throw an exception when any diagnostic error occurs. Even without calling <code>Verify()</code>, Simple Injector will always check for pesky <a href="https://simpleinjector.org/dialm">Lifestyle Mismatches</a> when resolving instances from the container and will throw an exception when such a mismatch is detected. These exceptions are intended to provide the quickest feedback on configuration mistakes that we believe you should resolve. From experience we know that this can save you from wasting many hours debugging problems later.</p>
<h2 id="breaking-changes">Breaking Changes</h2>
<p>The most prominent breaking changes are the changes to the public API and these can prevent your code from compiling.</p>
<p>Here is a cheat sheet containing a mapping for the most prominent API changes. On the left side are the old v2 API calls, on the right side the related method to use in v3. <em>Note that in most cases the compiler errors will guide you through the process.</em></p>
<table>
<thead>
<tr>
<th>v2 API</th>
<th>v3 API</th>
</tr>
</thead>
<tbody>
<tr>
<td>RegisterSingle</td>
<td>RegisterSingleton</td>
</tr>
<tr>
<td>RegisterAll</td>
<td>RegisterCollection</td>
</tr>
<tr>
<td>RegisterSingleDecorator</td>
<td>RegisterDecorator(Lifestyle.Singleton)</td>
</tr>
<tr>
<td>RegisterAllOpenGeneric</td>
<td>RegisterCollection</td>
</tr>
<tr>
<td>RegisterManyForOpenGeneric</td>
<td>Register / RegisterCollection</td>
</tr>
<tr>
<td>RegisterOpenGeneric</td>
<td>Register</td>
</tr>
<tr>
<td>RegisterSingleOpenGeneric</td>
<td>Register(Lifestyle.Singleton)</td>
</tr>
</tbody>
</table>
<p>For a complete list of all the breaking changes, please see the <a href="https://github.com/simpleinjector/SimpleInjector/releases/tag/v3.0">release notes</a>.</p>
<h2 id="new-features">New Features</h2>
<p>As well as the breaking changes there are many other big and small improvements to the library. The most prominent of these are:</p>
<ul>
<li>the addition of a <code>Lifestyle.Scoped</code> property;</li>
<li>support for conditional and contextual registrations using the new <code>RegisterConditional</code> methods.</li>
<li><code>Register</code> overloads now accept open generic types.</li>
<li><code>RegisterCollection(Type, IEnumerable<Registration>)</code> now accepts open generic types.</li>
<li><code>Container.Register(Type, IEnumerable<Assembly>)</code> and <code>Container.RegisterCollection(Type, IEnumerable<Assembly>)</code> overloads have been added to simplify batch registration.</li>
<li>the <code>Container</code> class now implements <code>IDisposable</code> to allows disposing singletons.</li>
</ul>
<p>The new <code>Lifestyle.Scoped</code> is a small feature that can make your <a href="https://freecontent.manning.com/dependency-injection-in-net-2nd-edition-understanding-the-composition-root/">Composition Root</a> much cleaner. Most applications use a combination of three lifestyles: <code>Transient</code>, <code>Singleton</code>, and some scoped lifestyle that is particularly suited for that application type. For example an ASP.NET MVC application will typically use the <code>WebRequestLifestyle</code>; a Web API application will use the <code>WebApiRequestLifestyle</code>. Instead of using the appropriate <code>RegisterXXX</code> extension method of the appropriate integration package, you can now do the following:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">var</span> container = <span style="color:#66d9ef">new</span> Container();
<span style="color:#75715e">// Just define the scoped lifestyle once.
</span><span style="color:#75715e"></span>container.Options.DefaultScopedLifesyle = <span style="color:#66d9ef">new</span> WebRequestLifestyle();
container.Register<IUserContext, AspNetUserContext>(Lifestyle.Scoped);
container.Register<IUnitOfWork, DbContextUnitOfWork>(Lifestyle.Scoped);</code></pre></div>
<p>Not only does this make your code much cleaner, it also makes it easier to pass the container on to some methods that add some layer-specific configuration to the container. For instance.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> BootstrapBusinessLayer(Container container) {
<span style="color:#75715e">// Registrations specific to the business layer here:
</span><span style="color:#75715e"></span> container.Register<IUnitOfWork, DbContextUnitOfWork>(Lifestyle.Scoped);
}</code></pre></div>
<p>The <code>Lifestyle.Scoped</code> property makes it easy for the business layer bootstrapper to add registrations using the application’s scoped lifestyle without having to know which lifestyle it actually is. This simplifies reuse of this bootstrapper across the applications in your solution.</p>
<p>Another great improvement is the addition of the <code>RegisterConditional</code> methods. These method overloads allow conditional registration of types and registration of contextual types. Take the following conditional registrations:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp">container.RegisterConditional<ILogger, NullLogger>(
c => c.Consumer.ImplementationType == <span style="color:#66d9ef">typeof</span>(HomeController));
container.RegisterConditional<ILogger, SqlLogger>(c => !c.Handled);</code></pre></div>
<p>This particular combination of registrations ensures that a <code>NullLogger</code> is injected into <code>HomeController</code> and all other components get a <code>SqlLogger</code>.</p>
<p>For advanced scenarios one of the <code>RegisterConditional</code> overloads accepts an implementation type factory delegate. Take a look at the following example:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-csharp" data-lang="csharp">container.RegisterConditional(<span style="color:#66d9ef">typeof</span>(ILogger),
c => <span style="color:#66d9ef">typeof</span>(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => <span style="color:#66d9ef">true</span>);</code></pre></div>
<p>This example registers a non-generic <code>ILogger</code> abstraction that will be injected as a closed generic version of <code>Logger<T></code>, where <code>T</code> is determined based on its context (in this case the consuming component). In other words when your <code>HomeController</code> depends on an <code>ILogger</code> it will actually get a <code>Logger<HomeController></code>.</p>
<p>For a complete list of all the breaking changes, new features and bug fixes, please view the release notes.</p>
<p>Happy injecting.</p>
</div>
<div class="post">
<div class="post-heading">
<h1><a href="/2015/06/beta-testers-wanted/">Wanted: Beta Testers</a></h1>
<span>Jun 29, 2015 by Steven</span>
</div>
<p>With Simple Injector 3 we are breaking with the past and working hard to simplify the API to better represent our ideals and, of course, the name of our library. This means that we are introducing breaking changes in v3 that will undoubtedly impact any developer migrating from v2.</p>
<p>The driver for making these breaking changes is that areas of the API have evolved over time and in so doing have grown confusing (e.g. <code>RegisterOpenGeneric</code> and <code>RegisterManyForOpenGeneric</code>). In the pursuit of keeping Simple Injector simple we felt obligated to improve the consistency of the API. These decisions have not been taken lightly because we hate breaking your code. Our driving force is, however, a simpler Simple Injector for everyone.</p>
<p>We are doing our best to make the transition as seamless as possible and we need feedback on this effort. We are looking for Simple Injector users to test the beta of Simple Injector 3 and tell us what they think.</p>
<p>If you can help then please upgrade your NuGet packages to <a href="https://www.nuget.org/packages/SimpleInjector/3.0.0-beta4">3.0.0-beta4</a> and try to compile your code (it will probably fail!). Our main strategy is to guide users with <a href="https://msdn.microsoft.com/en-us/library/aa664623%28v=vs.71%29.aspx">obsolete messages</a> that should be presented as descriptive compiler errors. Once you have fixed any errors please call Verify() on your container, (as you are hopefully already doing) and test your application to ensure everything resolves as expected. To discuss any element of beta testing please join us on <a href="https://simpleinjector.org/chat">gitter</a>. We would usually expect the upgrade process to take no more than a half hour.</p>
<p><em>Please note that we don’t expect you to do our testing for us. Simple Injector has an extensive suite of unit tests and we don’t expect to have introduced many new bugs.</em></p>
<p>Here’s a list of the most prominent breaking changes we are introducing:</p>
<ul>
<li>Calling <code>Verify()</code> will now automatically diagnose the container’s configuration for common configuration mistakes and exceptions will be thrown. We felt that not enough developers were explicitly calling <code>Analyzer.Analyze()</code> to check for diagnostic warnings, leading to a common source of bugs. So we decided to integrate this into Verification in the hope that this will guide our users to the pit of success. The old Verification behaviour can be triggered by calling <code>Verify(VerificationOption.VerifyOnly)</code>.</li>
<li>Even if you don’t call <code>Verify()</code>, the v3 the container will always check for <a href="https://simpleinjector.org/dialm">lifestyle mismatches</a> when resolving an instance and will throw an exception if there is a mismatch in the object graph. This more strict behaviour can be suppressed globally but (for obvious reasons) we advise against doing so.</li>
<li>The <code>RegisterSingle</code> methods have been renamed to <code>RegisterSingleton</code> as we felt there was some ambiguity in the name <code>RegisterSingle</code>, especially in combination with methods like <code>RegisterAll</code>, <code>RegisterCollection</code> and <code>RegisterManyForOpenGeneric</code>. We considered removing these method completely, but the benefits of doing so did not compare favourably to the pain of fixing this as a breaking change.</li>
<li>The <code>RegisterAll</code> methods have been renamed to <code>RegisterCollection</code>. Just as with the <code>RegisterSingle</code> methods, new developers experienced confusion in their naming. The new name expresses more clearly what the methods do.</li>
<li>The <code>RegisterManyForOpenGeneric</code> extension methods from the <code>SimpleInjector.Extensions</code> namespace have been replaced with new <code>Register</code> and <code>RegisterCollection</code> overloads on the <code>Container</code>. When doing one-to-one mappings, <code>Register(Type, IEnumerable<Assembly>)</code> can be used, and when registering collections <code>RegisterCollection(Type, IEnumerable<Assembly>)</code> can be used.</li>
<li>The <code>RegisterSingleDecorator</code> extension methods have been removed. Decorators can be registered by calling <code>RegisterDecorator</code> while supplying the <code>Lifestyle.Singleton</code>.</li>
<li>The <code>RegisterOpenGeneric</code> extension methods have been removed. The <code>Container.Register</code> methods have been extended to accept open generic types. This removes the superficial difference between the registration of open generic types and other registrations. (This difference originally had a technical background, but we allowed the internal difference to effect the user experience.) Do note that there is a behavioural difference between <code>RegisterOpenGeneric</code> and <code>Container.Register</code>. <code>RegisterOpenGeneric</code> registers each generic type as fall-back, which means it will apply that type if no other registration exists for that type. Conversely, <code>Container.Register</code> will not register a fall-back, it will, instead, test for overlapping registrations. If the fall-back behaviour is required, the new <code>RegisterConditional</code> methods can be used. The new <code>RegisterConditional</code> methods allow supplying a delegate that allows signaling a registration as fall-back registration.</li>
<li><code>IConstructorVerificationBehavior</code> and <code>IConstructorVerificationBehavior</code> have been merged and replaced with <code>IDependencyInjectionBehavior</code>.</li>
</ul>
<p><em>In the majority of cases the compiler error messages should guide you through the migration. If you find a scenario that is unclear or it takes time to figure out please let us know. We want to make the migration as seamless as possible.</em></p>
<p>Besides the above list of breaking changes, we have some compelling new features that may be of interest:</p>
<ul>
<li>A <code>Lifestyle.Scoped</code> property was added to simplify registration of scoped lifestyles, since in most applications you would typically only use one specific scoped lifestyle. You can now use <code>Register<IService, Impl>(Lifestyle.Scoped)</code> instead of having to call <code>RegisterPerWebRequest<IService, Impl>()</code> for example. This also simplifies reuse in your composition root, when the same configuration is reused over multiple application types (such as MVC and WCF).</li>
<li>As noted above <code>RegisterConditional</code> methods are added to the <code>Container</code> to allow registering types based on contextual information such as information about the consumer in which they are injected.</li>
<li>Batch registration made easier by adding overloads of the <code>Register</code> method that accept either a collection of types or a collection of assemblies.</li>
<li>As explained above, the <code>Register</code> methods now accept open generic types.</li>
<li>The container now implements <code>IDisposable</code>. This allows cached singletons to be disposed when the container gets disposed.</li>
<li><code>RegisterCollection(Type, IEnumerable<Registration>)</code> now accepts open generic service types as well.</li>
</ul>
</div>
<div class="post">
<div class="post-heading">
<h1><a href="/2015/06/welcome-to-the-simple-injector-weblog/">Welcome to the Simple Injector weblog</a></h1>
<span>Jun 24, 2015 by Steven</span>
</div>
<p>The Simple Injector weblog is where we—the Simple Injector contributors—will write about Simple Injector, Dependency Injection, best practice and software design in general.</p>
<p>Simple Injector is strongly opinionated, and so are we; we love talking about software design and principles and from now on we’ll be doing it right here.</p>
<p>We’ll keep you updated about new Simple Injector features, releases, background stories and anything else we decide to write about.</p>
<p>Welcome to The Simple Injector Blog!</p>
</div>
<div class="text-center">
</div>
</div>
<div class="col-sm-1 col-md-3 col-md-4">
</div>
</div>
</div>
<script src="/js/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</body>
</html>