-
Notifications
You must be signed in to change notification settings - Fork 151
/
StringResources.cs
1111 lines (977 loc) · 60.2 KB
/
StringResources.cs
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
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#region Copyright Simple Injector Contributors
/* The Simple Injector is an easy-to-use Inversion of Control library for .NET
*
* Copyright (c) 2013-2018 Simple Injector Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
* EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#endregion
namespace SimpleInjector
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using SimpleInjector.Advanced;
using SimpleInjector.Diagnostics;
/// <summary>Internal helper for string resources.</summary>
internal static class StringResources
{
private const string CollectionsRegisterMethodName =
nameof(Container) + "." + nameof(Container.Collection) + "." + nameof(ContainerCollectionRegistrator.Register);
// Assembly.Location only exists in .NETStandard1.5 and up, .NET4.0 and PCL, but we only compile
// against .NETStandard1.0 and .NETStandard1.3. We don't want to add an extra build directly, solely
// for the Location property.
private static readonly PropertyInfo AssemblyLocationProperty =
typeof(Assembly).GetProperties().SingleOrDefault(p => p.Name == "Location");
internal static bool UseFullyQualifiedTypeNames { get; set; }
internal static string ContainerCanNotBeChangedAfterUse(string stackTrace)
{
string message = Format(
"The container can't be changed after the first call to {0}, {1}, {2}, and some calls of {3}. " +
"Please see https://simpleinjector.org/locked to understand why the container is locked.",
nameof(Container.GetInstance),
nameof(Container.GetAllInstances),
nameof(Container.Verify),
nameof(Container.GetRegistration));
if (stackTrace == null)
{
return message;
}
return message +
" The following stack trace describes the location where the container was locked:" +
Environment.NewLine + Environment.NewLine + stackTrace;
}
internal static string ContainerCanNotBeUsedAfterDisposal(Type type, string stackTrace)
{
string message = Format(
"Cannot access a disposed object.{0}Object name: '{1}'.",
Environment.NewLine,
type.FullName);
if (stackTrace == null)
{
return message;
}
return message + Environment.NewLine +
"The following stack trace describes the location where the container was disposed:" +
Environment.NewLine + Environment.NewLine + stackTrace;
}
internal static string DelegateForTypeReturnedNull(Type serviceType) =>
Format(
"The registered delegate for type {0} returned null.",
serviceType.TypeName());
internal static string ResolveInterceptorDelegateReturnedNull() =>
Format(
"The delegate that was registered using '{0}' returned null.",
nameof(ContainerOptions.RegisterResolveInterceptor));
internal static string ErrorWhileBuildingDelegateFromExpression(
Type serviceType, Expression expression, Exception exception) =>
Format(
"Error occurred while trying to build a delegate for type {0} using the expression \"{1}\". " +
"{2}",
serviceType.TypeName(),
expression,
exception.Message);
internal static string DelegateForTypeThrewAnException(Type serviceType) =>
Format(
"The registered delegate for type {0} threw an exception.",
serviceType.TypeName());
internal static string NoRegistrationForTypeFound(
Type serviceType,
bool containerHasRegistrations,
bool containerHasRelatedOneToOneMapping,
bool containerHasRelatedCollectionMapping,
Type[] skippedDecorators,
Type[] lookalikes) =>
Format(
"No registration for type {0} could be found.{1}{2}{3}{4}{5}",
serviceType.TypeName(),
ContainerHasNoRegistrationsAddition(containerHasRegistrations),
DidYouMeanToCallGetInstanceInstead(containerHasRelatedOneToOneMapping, serviceType),
DidYouMeanToCallGetAllInstancesInstead(containerHasRelatedCollectionMapping, serviceType),
NoteThatSkippedDecoratorsWereFound(serviceType, skippedDecorators),
NoteThatTypeLookalikesAreFound(serviceType, lookalikes));
internal static string KnownImplementationTypeShouldBeAssignableFromExpressionType(
Type knownImplementationType, Type currentExpressionType) =>
Format(
"You are trying to set the {0}.{1} property with an Expression instance that has a type " +
"of {2}. The expression type however should be a {3} (or a sub type). You can't change " +
"the type of the expression using the {4} event. If you need to change the " +
"implementation, please use the {5} event instead.",
nameof(ExpressionBuildingEventArgs),
nameof(ExpressionBuildingEventArgs.Expression),
currentExpressionType.TypeName(),
knownImplementationType.TypeName(),
nameof(Container.ExpressionBuilding),
nameof(Container.ExpressionBuilt));
internal static string MultipleClosedTypesAreAssignableFromType(
Type type, Type genericTypeDefinition, Type[] types, string otherMethod) =>
Format(
"Your request is ambiguous. " +
"There are multiple closed version of {0} that are assignable from {1}, namely: {2}. " +
"Use {3} instead to get this list of closed types to select the proper type.",
genericTypeDefinition.TypeName(),
type.TypeName(),
types.Select(TypeName).ToCommaSeparatedText(),
otherMethod);
internal static string TypeIsNotAssignableFromOpenGenericType(Type type, Type genericTypeDefinition) =>
Format(
"None of the base classes or implemented interfaces of {0}, nor {0} itself are a closed " +
"type of {1}.",
type.TypeName(),
genericTypeDefinition.TypeName());
internal static string OpenGenericTypesCanNotBeResolved(Type serviceType) =>
Format(
"The request for type {0} is invalid because it is an open-generic type: it is only " +
"possible to instantiate instances of closed-generic types. A generic type is closed if " +
"all of its type parameters have been substituted with types that are recognized by the " +
"compiler.",
serviceType.TypeName());
internal static string LifestyleMismatchesReported(LifestyleMismatchDiagnosticResult error) =>
Format(
"A lifestyle mismatch has been detected. {0} Lifestyle mismatches can cause concurrency " +
"bugs in your application. Please see https://simpleinjector.org/dialm to understand this " +
"problem and how to solve it.",
error.Description);
internal static string DiagnosticWarningsReported(IList<DiagnosticResult> errors)
{
var descriptions =
from error in errors
select Format("-[{0}] {1}", error.Name, error.Description);
return Format(
"The configuration is invalid. The following diagnostic warnings were reported:{1}{0}{1}" +
"See the Error property for detailed information about the warnings. " +
"Please see https://simpleinjector.org/diagnostics how to fix problems and how to suppress " +
"individual warnings.",
string.Join(Environment.NewLine, descriptions.Distinct()),
Environment.NewLine);
}
internal static string ConfigurationInvalidCreatingInstanceFailed(
Type serviceType, Exception exception) =>
Format(
"The configuration is invalid. Creating the instance for type {0} failed. {1}",
serviceType.TypeName(),
exception.Message);
internal static string ConfigurationInvalidIteratingCollectionFailed(
Type serviceType, Exception exception) =>
Format(
"The configuration is invalid. Iterating the collection for type {0} failed. {1}",
serviceType.TypeName(),
exception.Message);
internal static string ConfigurationInvalidCollectionContainsNullElements(
Type firstInvalidServiceType) =>
Format(
"The configuration is invalid. One of the items in the collection for type {0} is " +
"a null reference.",
firstInvalidServiceType.TypeName());
internal static string TypeAlreadyRegistered(Type serviceType) =>
Format(
"Type {0} has already been registered. If your intention is to resolve a collection of " +
"{0} implementations, use the {1} overloads. " +
"For more information, see https://simpleinjector.org/coll1. " +
"If your intention is to replace the existing registration with this new registration, " +
"you can allow overriding the current registration by setting {2}.{3} to true. " +
"For more information, see https://simpleinjector.org/ovrrd.",
serviceType.TypeName(),
CollectionsRegisterMethodName,
nameof(Container) + "." + nameof(Container.Options),
nameof(ContainerOptions.AllowOverridingRegistrations));
internal static string ScopePropertyCanOnlyBeUsedWhenDefaultScopedLifestyleIsConfigured() =>
"To be able to use the Lifestyle.Scoped property, please ensure that the container is " +
"configured with a default scoped lifestyle by setting the Container.Options." +
"DefaultScopedLifestyle property with the required scoped lifestyle for your type of " +
"application. For more information, see https://simpleinjector.org/scoped.";
internal static string MakingConditionalRegistrationsInOverridingModeIsNotSupported() =>
"The making of conditional registrations is not supported when " +
$"{nameof(ContainerOptions.AllowOverridingRegistrations)} is set, because it is impossible " +
"for the container to detect whether the registration should replace a different registration " +
"or not.";
internal static string MakingRegistrationsWithTypeConstraintsInOverridingModeIsNotSupported() =>
MakingConditionalRegistrationsInOverridingModeIsNotSupported() +
" Your registration is considered conditional, because of its generic type constraints. " +
"This makes Simple Injector apply it conditionally, based on its type constraints.";
internal static string NonGenericTypeAlreadyRegisteredAsConditionalRegistration(Type serviceType) =>
NonGenericTypeAlreadyRegistered(serviceType, existingRegistrationIsConditional: true);
internal static string CollectionUsedDuringConstruction(
Type consumer, InstanceProducer producer, KnownRelationship relationship = null) =>
Format(
"{0} is part of the {3} that is injected into {2}. The problem in {2} is that instead " +
"of storing the injected {3} in a private field and iterating over it at the point " +
"its instances are required, {0} is being resolved (from the collection) during " +
"object construction. Resolving services from an injected collection during object " +
"construction (e.g. by calling {4}.ToList() in the constructor) is not advised.",
producer.ImplementationType.ToFriendlyName(),
producer.ServiceType.ToFriendlyName(),
consumer.ToFriendlyName(),
relationship != null
? relationship.Dependency.ServiceType.ToFriendlyName()
: Format(
"collection of {0} services",
producer.ServiceType.ToFriendlyName()),
relationship != null && !relationship.Consumer.IsRoot
? relationship.Consumer.Target.Name
: "collection");
internal static string NonGenericTypeAlreadyRegisteredAsUnconditionalRegistration(Type serviceType) =>
NonGenericTypeAlreadyRegistered(serviceType, existingRegistrationIsConditional: false);
internal static string CollectionTypeAlreadyRegistered(Type serviceType) =>
Format(
"Collection of items for type {0} has already been registered " +
"and the container is currently not configured to allow overriding registrations. " +
"If your intention is to replace the existing collection with this new one, " +
"you can allow overriding the current registration by setting Container.{1}.{2} to true. " +
"In case it is your goal to append items to an already registered collection, please use " +
"the Container.{3}.{4} method overloads. " +
"More info on overriding registration: https://simpleinjector.org/ovrrd.",
serviceType.TypeName(),
nameof(ContainerOptions),
nameof(ContainerOptions.AllowOverridingRegistrations),
nameof(Container.Collection),
nameof(ContainerCollectionRegistrator.Append));
internal static string ParameterTypeMustBeRegistered(
Container container,
InjectionTargetInfo target,
int numberOfConditionals,
bool hasRelatedOneToOneMapping,
bool hasRelatedCollectionMapping,
Type[] skippedDecorators,
Type[] lookalikes)
{
var formatString = target.Parameter != null
? "The constructor of type {0} contains the parameter with name '{1}' and type {2} that " +
"is not registered. Please ensure {2} is registered, or change the constructor of {0}." +
"{3}"
: "Type {0} contains the property with name '{1}' and type {2} that is not registered. " +
"Please ensure {2} is registered, or change {0}.{3}";
string extraInfo = string.Concat(
GetAdditionalInformationAboutExistingConditionalRegistrations(target, numberOfConditionals),
DidYouMeanToDependOnNonCollectionInstead(hasRelatedOneToOneMapping, target.TargetType),
DidYouMeanToDependOnCollectionInstead(hasRelatedCollectionMapping, target.TargetType),
NoteThatSkippedDecoratorsWereFound(target.TargetType, skippedDecorators),
NoteThatConcreteTypeCanNotBeResolvedDueToConfiguration(container, target.TargetType),
NoteThatTypeLookalikesAreFound(target.TargetType, lookalikes, numberOfConditionals));
return Format(
formatString,
target.Member.DeclaringType.TypeName(),
target.Name,
target.TargetType.TypeName(),
extraInfo);
}
internal static string TypeMustHaveASinglePublicConstructorButItHasNone(Type serviceType) =>
Format(
"For the container to be able to create {0} it should have only one public constructor: " +
"it has none.",
serviceType.TypeName());
internal static string TypeMustHaveASinglePublicConstructorButItHas(Type serviceType, int count) =>
Format(
"For the container to be able to create {0} it should have only one public constructor: " +
"it has {1}. See https://simpleinjector.org/one-constructor for more " +
"information.",
serviceType.TypeName(),
count);
internal static string TypeMustNotContainInvalidInjectionTarget(InjectionTargetInfo invalidTarget)
{
string reason = string.Empty;
if (invalidTarget.TargetType.IsValueType())
{
reason = " because it is a value type";
}
if (invalidTarget.Parameter != null)
{
return Format(
"The constructor of type {0} contains parameter '{1}' of type {2}, which can not be " +
"used for constructor injection{3}.",
invalidTarget.Member.DeclaringType.TypeName(),
invalidTarget.Name,
invalidTarget.TargetType.TypeName(),
reason);
}
else
{
return Format(
"The type {0} contains property '{1}' of type {2}, which can not be used for property " +
"injection{3}.",
invalidTarget.Member.DeclaringType.TypeName(),
invalidTarget.Name,
invalidTarget.TargetType.TypeName(),
reason);
}
}
internal static string TypeShouldBeConcreteToBeUsedOnThisMethod(Type serviceType) =>
Format(
"The given type {0} is not a concrete type. Please use one of the other overloads to " +
"register this type.",
serviceType.TypeName());
internal static string MultipleObserversRegisteredTheSameTypeToResolveUnregisteredType(
Type unregisteredServiceType) =>
Format(
"Multiple observers of the {0} event are registering a delegate for the same service " +
"type: {1}. Make sure only one of the registered handlers calls the {2}.{3} method for a " +
"given service type.",
nameof(Container.ResolveUnregisteredType),
unregisteredServiceType.TypeName(),
nameof(UnregisteredTypeEventArgs),
nameof(UnregisteredTypeEventArgs.Register));
internal static string ImplicitRegistrationCouldNotBeMadeForType(
Type serviceType, bool containerHasRegistrations) =>
Format(
"No registration for type {0} could be found and an implicit registration could not be " +
"made.{1}",
serviceType.TypeName(),
ContainerHasNoRegistrationsAddition(containerHasRegistrations));
internal static string ImplicitRegistrationCouldNotBeMadeForType(
Container container, Type serviceType, bool containerHasRegistrations) =>
Format(
"No registration for type {0} could be found and an implicit registration could not be " +
"made.{1}{2}",
serviceType.TypeName(),
NoteThatConcreteTypeCanNotBeResolvedDueToConfiguration(container, serviceType),
ContainerHasNoRegistrationsAddition(containerHasRegistrations));
internal static string DefaultScopedLifestyleCanNotBeSetWithLifetimeScoped() =>
$"{nameof(ContainerOptions.DefaultScopedLifestyle)} can't be set with the value of " +
$"{nameof(Lifestyle)}.{nameof(Lifestyle.Scoped)}.";
internal static string TypeDependsOnItself(Type serviceType) =>
Format(
"The configuration is invalid. The type {0} is directly or indirectly depending on itself.",
serviceType.TypeName());
internal static string CyclicDependencyGraphMessage(IEnumerable<Type> dependencyCycle) =>
Format(
"The cyclic graph contains the following types: {0}.",
string.Join(" -> ", dependencyCycle.Select(TypeName)));
internal static string UnableToResolveTypeDueToSecurityConfiguration(
Type serviceType, Exception innerException) =>
Format(
"Unable to resolve type {0}. The security restrictions of your application's sandbox do " +
"not permit the creation of this type. Explicitly register the type using one of the " +
"generic '{2}' overloads or consider making it public. {1}",
serviceType.TypeName(),
innerException.Message,
nameof(Container.Register));
internal static string UnableToInjectPropertiesDueToSecurityConfiguration(Type serviceType,
Exception innerException) =>
Format(
"Unable to inject properties into type {0}. The security restrictions of your application's " +
"sandbox do not permit the injection of one of its properties. Consider making it public. {1}",
serviceType.TypeName(),
innerException.Message);
internal static string UnableToInjectImplicitPropertiesDueToSecurityConfiguration(Type injectee,
Exception innerException) =>
Format(
"Unable to inject properties into type {0}. The security restrictions of your application's " +
"sandbox do not permit the creation of one of its dependencies. Explicitly register that " +
"dependency using one of the generic '{2}' overloads or consider making it public. {1}",
injectee.TypeName(),
innerException.Message,
nameof(Container.Register));
internal static string PropertyCanNotBeChangedAfterTheFirstRegistration(string propertyName) =>
$"The {propertyName} property cannot be changed after the first registration has " +
"been made to the container.";
internal static string CollectionsRegisterCalledWithTypeAsTService(IEnumerable<Type> types) =>
TypeIsAmbiguous(typeof(Type)) + " " + Format(
"The most likely cause of this happening is because the C# overload resolution picked " +
"a different method for you than you expected to call. The method C# selected for you is: " +
"{3}<Type>(new[] {{ {0} }}). Instead, you probably intended to call: " +
"{3}(typeof({1}), new[] {{ {2} }}).",
ToTypeOCfSharpFriendlyList(types),
CSharpFriendlyName(types.First()),
ToTypeOCfSharpFriendlyList(types.Skip(1)),
CollectionsRegisterMethodName);
internal static string TypeIsAmbiguous(Type serviceType) =>
Format(
"You are trying to register {0} as a service type, but registering this type is not " +
"allowed to be registered because the type is ambiguous. The registration of such a type " +
"almost always indicates a flaw in the design of the application and is therefore not " +
"allowed. Please change any component that depends on a dependency of this type. Ensure " +
"that the container does not have to inject any dependencies of this type by injecting a " +
"different type.",
serviceType.TypeName());
internal static string SuppliedTypeIsNotAReferenceType(Type type) =>
Format(
"The supplied type {0} is not a reference type. Only reference types are supported.",
type.TypeName());
internal static string SuppliedTypeIsAnOpenGenericType(Type type) =>
Format(
"The supplied type {0} is an open-generic type. This type cannot be used for registration " +
"using this method.",
type.TypeName());
internal static string SuppliedTypeIsAnOpenGenericTypeWhileTheServiceTypeIsNot(Type type) =>
Format(
"The supplied type {0} is an open-generic type. This type cannot be used for registration " +
"of collections of non-generic types.",
type.TypeName());
internal static string SuppliedElementDoesNotInheritFromOrImplement(
Type serviceType, Type elementType, string elementDescription) =>
Format(
"The supplied {0} of type {1} does not {2} {3}.",
elementDescription,
elementType.TypeName(),
serviceType.IsInterface() ? "implement" : "inherit from",
serviceType.TypeName());
internal static string SuppliedTypeDoesNotInheritFromOrImplement(Type service, Type implementation) =>
Format(
"The supplied type {0} does not {1} {2}.",
implementation.TypeName(),
service.IsInterface() ? "implement" : "inherit from",
service.TypeName());
internal static string DependencyInjectionBehaviorReturnedNull(IDependencyInjectionBehavior behavior) =>
Format(
"The {0} that was registered through the Container.{1}.{2} property, returned a null " +
"reference from its {3} method. {4}.{3} implementations should not return null when " +
"supplied with throwOnFailure = true, but should throw an {5} with an expressive message " +
"instead.",
behavior.GetType().TypeName(),
nameof(Container.Options),
nameof(ContainerOptions.DependencyInjectionBehavior),
nameof(IDependencyInjectionBehavior.GetInstanceProducer),
nameof(IDependencyInjectionBehavior),
typeof(ActivationException).FullName);
internal static string ConstructorResolutionBehaviorReturnedNull(
IConstructorResolutionBehavior selectionBehavior, Type implementationType) =>
Format(
"The {0} that was registered through Container.{4}.{5} returned a null reference after " +
"its {6} method was supplied with implementationType '{1}'. {2}.{6} implementations " +
"should never return null, but should throw a {3} with an expressive message instead.",
selectionBehavior.GetType().TypeName(),
implementationType.TypeName(),
nameof(IConstructorResolutionBehavior),
typeof(ActivationException).FullName,
nameof(Container.Options),
nameof(ContainerOptions.ConstructorResolutionBehavior),
nameof(IConstructorResolutionBehavior.GetConstructor));
internal static string LifestyleSelectionBehaviorReturnedNull(
ILifestyleSelectionBehavior selectionBehavior, Type implementationType) =>
Format(
"The {0} that was registered through Container.{3}.{4} returned a null reference after " +
"its {5} method was supplied with implementationType '{1}'. {2}.{5} implementations " +
"should never return null.",
selectionBehavior.GetType().TypeName(),
implementationType.TypeName(),
nameof(ILifestyleSelectionBehavior),
nameof(Container.Options),
nameof(ContainerOptions.LifestyleSelectionBehavior),
nameof(ILifestyleSelectionBehavior.SelectLifestyle));
internal static string RegistrationReturnedNullFromBuildExpression(
Registration lifestyleRegistration) =>
Format(
"The {0} for the {1} returned a null reference from its {2} method.",
lifestyleRegistration.GetType().TypeName(),
lifestyleRegistration.Lifestyle.GetType().TypeName(),
nameof(Registration.BuildExpression));
internal static string MultipleTypesThatRepresentClosedGenericType(
Type closedServiceType, Type[] implementations) =>
Format(
"In the supplied list of types or assemblies, there are {0} types that represent the " +
"same closed-generic type {1}. Did you mean to register the types as a collection " +
"using the {2} method instead? Conflicting types: {3}.",
implementations.Length,
closedServiceType.TypeName(),
CollectionsRegisterMethodName,
implementations.Select(TypeName).ToCommaSeparatedText());
internal static string CantGenerateFuncForDecorator(
Type serviceType, Type decorateeFactoryType, Type decoratorType) =>
Format(
"It's impossible for the container to generate a {3} for injection into the {1} " +
"decorator that will be wrapped around instances of the collection of {0} instances, " +
"because the registered collection is not controlled by the container. The collection is " +
"considered to be container-uncontrolled collection, because the registration was made " +
"using either the {2}<{0}>(IEnumerable<{0}>) or {2}(Type, IEnumerable) overloads. " +
"It is impossible for the container to determine its lifestyle of an element in a " +
"container-uncontrolled collections, which makes it impossible to generate a {3} for {1}. " +
"Either switch to one of the other {2} overloads, or use a decorator that depends on {0} " +
"instead of {3}.",
serviceType.TypeName(),
decoratorType.TypeName(),
CollectionsRegisterMethodName,
decorateeFactoryType.TypeName());
internal static string SuppliedTypeIsNotAGenericType(Type type) =>
Format("The supplied type {0} is not a generic type.", type.TypeName());
internal static string SuppliedTypeIsNotAnOpenGenericType(Type type) =>
Format("The supplied type {0} is not an open-generic type.", type.TypeName());
internal static string SuppliedTypeCanNotBeOpenWhenDecoratorIsClosed() =>
"Registering a closed-generic service type with an open-generic decorator is not " +
"supported. Instead, register the service type as open generic, and the decorator type as " +
"closed generic.";
internal static string TheConstructorOfTypeMustContainTheServiceTypeAsArgument(
Type decoratorType, Type serviceType) =>
Format(
"For the container to be able to use {0} as a decorator, its constructor must include a " +
"single parameter of type {1} (or Func<{1}>) - i.e. the type of the instance that is " +
"being decorated. The parameter type {1} does not currently exist in the constructor of " +
"class {0}.",
decoratorType.TypeName(),
serviceType.TypeName());
internal static string TheConstructorOfTypeMustContainASingleInstanceOfTheServiceTypeAsArgument(
Type decoratorType, Type serviceType) =>
Format(
"For the container to be able to use {0} as a decorator, its constructor must include a " +
"single parameter of type {1} (or Func<{1}>) - i.e. the type of the instance that is " +
"being decorated. The parameter type {1} is defined multiple times in the constructor of " +
"class {0}.",
decoratorType.TypeName(),
serviceType.TypeName());
internal static string OpenGenericTypeContainsUnresolvableTypeArguments(
Type openGenericImplementation) =>
Format(
"The supplied type {0} contains unresolvable type arguments. " +
"The type would never be resolved and is therefore not suited to be used.",
openGenericImplementation.TypeName());
internal static string DecoratorCanNotBeAGenericTypeDefinitionWhenServiceTypeIsNot(
Type serviceType, Type decoratorType) =>
Format(
"The supplied decorator {0} is an open-generic type definition, while the supplied " +
"service type {1} is not.",
decoratorType.TypeName(),
serviceType.TypeName());
internal static string TheSuppliedRegistrationBelongsToADifferentContainer() =>
"The supplied Registration belongs to a different Container instance.";
internal static string CanNotDecorateContainerUncontrolledCollectionWithThisLifestyle(
Type decoratorType, Lifestyle lifestyle, Type serviceType) =>
Format(
"You are trying to apply the {0} decorator with the '{1}' lifestyle to a collection of " +
"type {2}, but the registered collection is not controlled by the container. Because the " +
"number of returned items might change on each call, the decorator with this lifestyle " +
"cannot be applied to the collection. Instead, register the decorator with the Transient " +
"lifestyle, or use one of the {3} overloads that takes a collection of System.Type types.",
decoratorType.TypeName(),
lifestyle.Name,
serviceType.TypeName(),
CollectionsRegisterMethodName);
internal static string PropertyHasNoSetter(PropertyInfo property) =>
Format(
"The property named '{0}' with type {1} and declared on type {2} can't be used for " +
"injection, because it has no set method.",
property.Name,
property.PropertyType.TypeName(),
property.DeclaringType.TypeName());
internal static string PropertyIsStatic(PropertyInfo property) =>
Format(
"Property of type {0} with name '{1}' can't be used for injection, because it is static.",
property.PropertyType.TypeName(),
property.Name);
internal static string ThisOverloadDoesNotAllowOpenGenerics(IEnumerable<Type> openGenericTypes) =>
Format(
"The supplied list of types contains one or multiple open-generic types, but this method " +
"is unable to handle open-generic types because it can only map closed-generic service " +
"types to a single implementation. " +
"You must register the open-generic types separately using the Register(Type, Type) " +
"overload. Alternatively, try using {0} instead, if you expect to have multiple " +
"implementations per closed-generic abstraction. Invalid types: {1}.",
CollectionsRegisterMethodName,
openGenericTypes.Select(TypeName).ToCommaSeparatedText());
internal static string AppendingRegistrationsToContainerUncontrolledCollectionsIsNotSupported(
Type serviceType) =>
Format(
"You are trying to append a registration to the registered collection of {0} instances, " +
"which is either registered using {1}<TService>(IEnumerable<TService>) or " +
"{1}(Type, IEnumerable). Because the number of returned items might change on each call, " +
"appending registrations to these collections is not supported. Please register the " +
"collection with one of the other {1} overloads if appending is required.",
serviceType.TypeName(),
CollectionsRegisterMethodName);
internal static string UnregisteredTypeEventArgsRegisterDelegateReturnedUncastableInstance(
Type serviceType, InvalidCastException exception) =>
Format(
"The delegate that was registered for service type {0} using the {2}.{3}(Func<object>) " +
"method returned an object that couldn't be casted to {0}. {1}",
serviceType.TypeName(),
exception.Message,
nameof(UnregisteredTypeEventArgs),
nameof(UnregisteredTypeEventArgs.Register));
internal static string UnregisteredTypeEventArgsRegisterDelegateThrewAnException(
Type serviceType, Exception exception) =>
Format(
"The delegate that was registered for service type {0} using the {2}.{3}(Func<object>) " +
"method threw an exception. {1}",
serviceType.TypeName(),
exception.Message,
nameof(UnregisteredTypeEventArgs),
nameof(UnregisteredTypeEventArgs.Register));
internal static string TheServiceIsRequestedOutsideTheContextOfAScopedLifestyle(Type serviceType,
ScopedLifestyle lifestyle) =>
Format(
"{0} is registered as '{1}' lifestyle, but the instance is requested outside the " +
"context of an active ({1}) scope. Please see https://simpleinjector.org/scoped " +
"for more information about how to manage scopes.",
serviceType.TypeName(),
lifestyle.Name);
internal static string ThisMethodCanOnlyBeCalledWithinTheContextOfAnActiveScope(
ScopedLifestyle lifestyle) =>
Format(
"This method can only be called within the context of an active ({0}) scope.",
lifestyle.Name);
internal static string DecoratorFactoryReturnedNull(Type serviceType) =>
Format(
"The decorator type factory delegate that was registered for service type {0} returned null.",
serviceType.TypeName());
internal static string FactoryReturnedNull(Type serviceType) =>
Format(
"The type factory delegate that was registered for service type {0} returned null.",
serviceType.TypeName());
internal static string ImplementationTypeFactoryReturnedNull(Type serviceType) =>
Format(
"The implementation type factory delegate that was registered for service type {0} " +
"returned null.",
serviceType.TypeName());
internal static string TheDecoratorReturnedFromTheFactoryShouldNotBeOpenGeneric(
Type serviceType, Type decoratorType) =>
Format(
"The registered decorator type factory returned open-generic type {0} while the registered " +
"service type {1} is not generic, making it impossible for a closed-generic decorator type " +
"to be constructed.",
decoratorType.TypeName(),
serviceType.TypeName());
internal static string TheTypeReturnedFromTheFactoryShouldNotBeOpenGeneric(
Type serviceType, Type implementationType) =>
Format(
"The registered type factory returned open-generic type {0} while the registered service " +
"type {1} is not generic, making it impossible for a closed-generic type to be constructed.",
implementationType.TypeName(),
serviceType.TypeName());
internal static string TypeFactoryReturnedIncompatibleType(
Type serviceType, Type implementationType) =>
Format(
"The registered type factory returned type {0} which does not implement {1}.",
implementationType.TypeName(),
serviceType.TypeName());
internal static string RecursiveInstanceRegistrationDetected() =>
"A recursive registration of Action or IDisposable instances was detected during disposal " +
"of the scope. This is possibly caused by a component that is directly or indirectly " +
"depending on itself.";
internal static string GetRootRegistrationsCanNotBeCalledBeforeVerify() =>
"Root registrations can't be determined before Verify is called. Please call Verify first.";
internal static string VisualizeObjectGraphShouldBeCalledAfterTheExpressionIsCreated() =>
Format(
"This method can only be called after {0}() or {1}() have been called.",
nameof(Container.GetInstance),
nameof(Registration.BuildExpression));
internal static string MixingCallsToCollectionsRegisterIsNotSupported(Type serviceType) =>
Format(
"Mixing calls to {1} for the same open-generic service type is not supported. Consider " +
"making one single call to {1}(typeof({0}), types).",
CSharpFriendlyName(serviceType.GetGenericTypeDefinition()),
CollectionsRegisterMethodName);
internal static string MixingRegistrationsWithControlledAndUncontrolledIsNotSupported(
Type serviceType, bool controlled) =>
Format(
"You already made a registration for {0} using one of the {3} overloads that registers " +
"container-{1} collections, while this method registers container-{2} collections. " +
"Mixing calls is not supported. Consider merging those calls or make both calls either as " +
"controlled or uncontrolled registration.",
(serviceType.IsGenericType() ? serviceType.GetGenericTypeDefinition() : serviceType).TypeName(),
controlled ? "uncontrolled" : "controlled",
controlled ? "controlled" : "uncontrolled",
CollectionsRegisterMethodName);
internal static string ValueInvalidForEnumType(
string paramName, object invalidValue, Type enumClass) =>
Format(
"The value of argument '{0}' ({1}) is invalid for Enum type '{2}'.",
paramName,
invalidValue,
enumClass.Name);
internal static string ServiceTypeCannotBeAPartiallyClosedType(Type openGenericServiceType) =>
Format(
"The supplied type '{0}' is a partially closed generic type, which is not supported by " +
"this method. Please supply the open-generic type '{1}' instead.",
openGenericServiceType.TypeName(),
CSharpFriendlyName(openGenericServiceType.GetGenericTypeDefinition()));
internal static string ServiceTypeCannotBeAPartiallyClosedType(
Type openGenericServiceType, string serviceTypeParamName, string implementationTypeParamName) =>
Format(
"The supplied type '{0}' is a partially closed generic type, which is not supported as " +
"value of the {1} parameter. Instead, please supply the open-generic type '{2}' and make " +
"the type supplied to the {3} parameter partially closed instead.",
openGenericServiceType.TypeName(),
serviceTypeParamName,
CSharpFriendlyName(openGenericServiceType.GetGenericTypeDefinition()),
implementationTypeParamName);
internal static string SuppliedTypeIsNotGenericExplainingAlternativesWithAssemblies(Type type) =>
SuppliedTypeIsNotGenericExplainingAlternatives(type, typeof(Assembly).Name);
internal static string SuppliedTypeIsNotGenericExplainingAlternativesWithTypes(Type type) =>
SuppliedTypeIsNotGenericExplainingAlternatives(type, typeof(Type).Name);
internal static string SuppliedTypeIsNotOpenGenericExplainingAlternativesWithAssemblies(Type type) =>
SuppliedTypeIsNotOpenGenericExplainingAlternatives(type, typeof(Assembly).Name);
internal static string SuppliedTypeIsNotOpenGenericExplainingAlternativesWithTypes(Type type) =>
SuppliedTypeIsNotOpenGenericExplainingAlternatives(type, typeof(Type).Name);
internal static string RegistrationForClosedServiceTypeOverlapsWithOpenGenericRegistration(
Type closedServiceType, Type overlappingGenericImplementationType) =>
Format(
"There is already an open-generic registration for {0} (with implementation {1}) that " +
"overlaps with the registration of {2} that you are trying to make. If your intention is " +
"to use {1} as fallback registration, please instead call: " +
"{5}(typeof({3}), typeof({4}), c => !c.Handled).",
closedServiceType.GetGenericTypeDefinition().TypeName(),
overlappingGenericImplementationType.TypeName(),
closedServiceType.TypeName(),
CSharpFriendlyName(closedServiceType.GetGenericTypeDefinition()),
CSharpFriendlyName(overlappingGenericImplementationType),
nameof(Container.RegisterConditional));
internal static string AnOverlappingRegistrationExists(
Type openGenericServiceType,
Type overlappingImplementationType,
bool isExistingRegistrationConditional,
Type implementationTypeOfNewRegistration,
bool isNewRegistrationConditional)
{
string solution = "Either remove one of the registrations or make them both conditional.";
if (isExistingRegistrationConditional && isNewRegistrationConditional
&& overlappingImplementationType == implementationTypeOfNewRegistration)
{
solution =
"You can merge both registrations into a single conditional registration and combine " +
"both predicates into one single predicate.";
}
return Format(
"There is already a {0}registration for {1} (with implementation {2}) that " +
"overlaps with the {3}registration for {4} that you are trying to make. This new " +
"registration causes ambiguity, because both registrations would be used for the " +
"same closed service types. {5}",
isExistingRegistrationConditional ? "conditional " : string.Empty,
openGenericServiceType.TypeName(),
overlappingImplementationType.TypeName(),
isNewRegistrationConditional ? "conditional " : string.Empty,
implementationTypeOfNewRegistration.TypeName(),
solution);
}
internal static string MultipleApplicableRegistrationsFound(
Type serviceType, Tuple<Type, Type, InstanceProducer>[] overlappingRegistrations) =>
Format(
"Multiple applicable registrations found for {0}. The applicable registrations are {1}. " +
"If your goal is to make one registration a fallback in case another registration is not " +
"applicable, make the fallback registration last using RegisterConditional and make sure " +
"the supplied predicate returns false in case the Handled property is true.",
serviceType.TypeName(),
overlappingRegistrations.Select(BuildRegistrationName).ToCommaSeparatedText());
internal static string UnableToLoadTypesFromAssembly(Assembly assembly, Exception innerException) =>
Format(
"Unable to load types from assembly {0}. {1}",
assembly.FullName,
innerException.Message);
private static string BuildRegistrationName(
Tuple<Type, Type, InstanceProducer> registration, int index)
{
Type serviceType = registration.Item1;
Type implementationType = registration.Item2;
InstanceProducer producer = registration.Item3;
return Format(
"({0}) the {1} {2}registration for {3} using {4}",
index + 1,
producer.IsConditional ? "conditional" : "unconditional",
serviceType.IsGenericTypeDefinition()
? "open-generic "
: serviceType.IsGenericType() ? "closed-generic " : string.Empty,
serviceType.TypeName(),
implementationType.TypeName());
}
private static string NonGenericTypeAlreadyRegistered(
Type serviceType, bool existingRegistrationIsConditional)
{
return Format(
"Type {0} has already been registered as {1} registration. For non-generic types, " +
"conditional and unconditional registrations can't be mixed.",
serviceType.TypeName(),
existingRegistrationIsConditional ? "conditional" : "unconditional");
}
private static string GetAdditionalInformationAboutExistingConditionalRegistrations(
InjectionTargetInfo target, int numberOfConditionalRegistrations)
{
string serviceTypeName = target.TargetType.TypeName();
bool isGenericType = target.TargetType.IsGenericType();
string openServiceTypeName = isGenericType
? target.TargetType.GetGenericTypeDefinition().TypeName()
: target.TargetType.TypeName();
if (numberOfConditionalRegistrations > 1)
{
return Format(
" {0} conditional registrations for {1} exist{2}, but none of the supplied predicates " +
"returned true when provided with the contextual information for {3}.",
numberOfConditionalRegistrations,
openServiceTypeName,
isGenericType ? (" that are applicable to " + serviceTypeName) : string.Empty,
target.Member.DeclaringType.TypeName());
}
else if (numberOfConditionalRegistrations == 1)
{
return Format(
" 1 conditional registration for {0} exists{1}, but its supplied predicate didn't " +
"return true when provided with the contextual information for {2}.",
openServiceTypeName,
isGenericType ? (" that is applicable to " + serviceTypeName) : string.Empty,
target.Member.DeclaringType.TypeName());
}
else
{
return string.Empty;
}
}
private static string SuppliedTypeIsNotOpenGenericExplainingAlternatives(
Type type, string registeringElement) =>
Format(
"Supply this method with the open-generic type {0} to register all available " +
"implementations of this type, or call {2}(Type, IEnumerable<{1}>) either with the open " +
"or closed version of that type to register a collection of instances based on that type.",
CSharpFriendlyName(type.GetGenericTypeDefinition()),
registeringElement,
CollectionsRegisterMethodName);
private static string ToTypeOCfSharpFriendlyList(IEnumerable<Type> types) =>
string.Join(", ",
from type in types
select Format("typeof({0})", CSharpFriendlyName(type)));
private static string SuppliedTypeIsNotGenericExplainingAlternatives(
Type type, string registeringElement) =>
Format(
"This method only supports open-generic types. " +
"If you meant to register all available implementations of {0}, call " +
"{2}(typeof({0}), IEnumerable<{1}>) instead.",
type.TypeName(),
registeringElement,
CollectionsRegisterMethodName);
private static object ContainerHasNoRegistrationsAddition(bool containerHasRegistrations) =>
containerHasRegistrations
? string.Empty
: " Please note that the container instance you are resolving from contains no " +
"registrations. Could it be that you accidentally created a new -and empty- container?";
private static object DidYouMeanToCallGetInstanceInstead(
bool hasRelatedOneToOneMapping, Type collectionServiceType) =>
hasRelatedOneToOneMapping
? Format(
" There is, however, a registration for {0}; Did you mean to call GetInstance<{0}>() " +
"or depend on {0}? Or did you mean to register a collection of types using " +
"{1}? Please see https://simpleinjector.org/collections for more information " +
"about registering and resolving collections.",
collectionServiceType.GetGenericArguments()[0].TypeName(),
CollectionsRegisterMethodName)
: string.Empty;
private static string DidYouMeanToDependOnNonCollectionInstead(
bool hasRelatedOneToOneMapping, Type collectionServiceType) =>
hasRelatedOneToOneMapping
? Format(
" There is, however, a registration for {0}; Did you mean to depend on {0}?",
collectionServiceType.GetGenericArguments()[0].TypeName())
: string.Empty;
private static string DidYouMeanToCallGetAllInstancesInstead(bool hasCollection, Type serviceType) =>
hasCollection
? Format(
" There is, however, a registration for {0}; Did you mean to call " +
"GetAllInstances<{1}>() or depend on {0}? " +
"Please see https://simpleinjector.org/collections for more information " +
"about registering and resolving collections.",
typeof(IEnumerable<>).MakeGenericType(serviceType).TypeName(),
serviceType.TypeName())
: string.Empty;
private static string DidYouMeanToDependOnCollectionInstead(bool hasCollection, Type serviceType) =>
hasCollection
? Format(
" There is, however, a registration for {0}; Did you mean to depend on {0}? If you " +
"meant to depend on {1}, you should use one of the {3} overloads instead of using {2}." +