Skip to content

Commit f6bfcb3

Browse files
halter73guardrex
andauthored
Add more IEnumerable<TService> documentation (#20280)
Co-authored-by: Luke Latham <[email protected]>
1 parent 4f28e4f commit f6bfcb3

File tree

1 file changed

+67
-3
lines changed

1 file changed

+67
-3
lines changed

aspnetcore/fundamentals/dependency-injection.md

+67-3
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,46 @@ The framework provides service registration extension methods that are useful in
212212

213213
For more information on type disposal, see the [Disposal of services](#disposal-of-services) section. It's common to use multiple implementations when [mocking types for testing](xref:test/integration-tests#inject-mock-services).
214214

215+
Registering a service with only an implementation type is equivalent to registering that service with the same implementation and service type. This is why multiple implementations of a service cannot be registered using the methods that don't take an explicit service type. These methods can register multiple *instances* of a service, but they will all have the same *implementation* type.
216+
217+
Any of the above service registration methods can be used to register multiple service instances of the same service type. In the following example, `AddSingleton` is called twice with `IMyDependency` as the service type. The second call to `AddSingleton` overrides the previous one when resolved as `IMyDependency` and adds to the previous one when multiple services are resolved via `IEnumerable<IMyDependency>`. Services appear in the order they were registered when resolved via `IEnumerable<{SERVICE}>`.
218+
219+
```csharp
220+
services.AddSingleton<IMyDependency, MyDependency>();
221+
services.AddSingleton<IMyDependency, DifferentDependency>();
222+
223+
public class MyService
224+
{
225+
public MyService(IMyDependency myDependency,
226+
IEnumberable<IMyDependency> myDependencies)
227+
{
228+
Trace.Assert(myDependency is DifferentDependency);
229+
230+
var dependencyArray = myDependencies.ToArray();
231+
Trace.Assert(dependencyArray[0] is MyDependency);
232+
Trace.Assert(dependencyArray[1] is DifferentDependency);
233+
}
234+
}
235+
```
236+
215237
The framework also provides `TryAdd{LIFETIME}` extension methods, which register the service only if there isn't already an implementation registered.
216238

217-
In the following example, the call to `AddSingleton` registers `MyDependency` as an implementation for `IMyDependency`. The call to `TryAddSingleton` has no effect because `IMyDependency` already has a registered implementation:
239+
In the following example, the call to `AddSingleton` registers `MyDependency` as an implementation for `IMyDependency`. The call to `TryAddSingleton` has no effect because `IMyDependency` already has a registered implementation.
218240

219241
```csharp
220242
services.AddSingleton<IMyDependency, MyDependency>();
221243
// The following line has no effect:
222244
services.TryAddSingleton<IMyDependency, DifferentDependency>();
245+
246+
public class MyService
247+
{
248+
public MyService(IMyDependency myDependency,
249+
IEnumberable<IMyDependency> myDependencies)
250+
{
251+
Trace.Assert(myDependency is MyDependency);
252+
Trace.Assert(myDependencies.Single() is MyDependency);
253+
}
254+
}
223255
```
224256

225257
For more information, see:
@@ -766,14 +798,46 @@ Service registration extension methods offer overloads that are useful in specif
766798

767799
For more information on type disposal, see the [Disposal of services](#disposal-of-services) section. A common scenario for multiple implementations is [mocking types for testing](xref:test/integration-tests#inject-mock-services).
768800

769-
`TryAdd{LIFETIME}` methods only register the service if there isn't already an implementation registered.
801+
Registering a service with only an implementation type is equivalent to registering that service with the same implementation and service type. This is why multiple implementations of a service cannot be registered using the methods that don't take an explicit service type. These methods can register multiple *instances* of a service, but they will all have the same *implementation* type.
770802

771-
In the following example, the first line registers `MyDependency` for `IMyDependency`. The second line has no effect because `IMyDependency` already has a registered implementation:
803+
Any of the above service registration methods can be used to register multiple service instances of the same service type. In the following example, `AddSingleton` is called twice with `IMyDependency` as the service type. The second call to `AddSingleton` overrides the previous one when resolved as `IMyDependency` and adds to the previous one when multiple services are resolved via `IEnumerable<IMyDependency>`. Services appear in the order they were registered when resolved via `IEnumerable<{SERVICE}>`.
804+
805+
```csharp
806+
services.AddSingleton<IMyDependency, MyDependency>();
807+
services.AddSingleton<IMyDependency, DifferentDependency>();
808+
809+
public class MyService
810+
{
811+
public MyService(IMyDependency myDependency,
812+
IEnumberable<IMyDependency> myDependencies)
813+
{
814+
Trace.Assert(myDependency is DifferentDependency);
815+
816+
var dependencyArray = myDependencies.ToArray();
817+
Trace.Assert(dependencyArray[0] is MyDependency);
818+
Trace.Assert(dependencyArray[1] is DifferentDependency);
819+
}
820+
}
821+
```
822+
823+
The framework also provides `TryAdd{LIFETIME}` extension methods, which register the service only if there isn't already an implementation registered.
824+
825+
In the following example, the call to `AddSingleton` registers `MyDependency` as an implementation for `IMyDependency`. The call to `TryAddSingleton` has no effect because `IMyDependency` already has a registered implementation.
772826

773827
```csharp
774828
services.AddSingleton<IMyDependency, MyDependency>();
775829
// The following line has no effect:
776830
services.TryAddSingleton<IMyDependency, DifferentDependency>();
831+
832+
public class MyService
833+
{
834+
public MyService(IMyDependency myDependency,
835+
IEnumberable<IMyDependency> myDependencies)
836+
{
837+
Trace.Assert(myDependency is MyDependency);
838+
Trace.Assert(myDependencies.Single() is MyDependency);
839+
}
840+
}
777841
```
778842

779843
For more information, see:

0 commit comments

Comments
 (0)