From f7029e39917e0b31a9cbaeb49bfc76ac353bbc8e Mon Sep 17 00:00:00 2001 From: David Pine Date: Wed, 28 Oct 2020 10:34:07 -0500 Subject: [PATCH 1/2] Added details about IEnumerable into DI. --- docs/core/extensions/dependency-injection.md | 35 ++++++++++++++++--- .../app-lifetime/app-lifetime.csproj | 2 +- .../console-custom-logging.csproj | 4 +-- .../console-di-disposable.csproj | 2 +- .../ConsoleMessageWriter.cs | 11 ++++++ .../console-di-ienumerable/ExampleService.cs | 20 +++++++++++ .../console-di-ienumerable/IMessageWriter.cs | 7 ++++ .../LoggingMessageWriter.cs | 15 ++++++++ .../console-di-ienumerable/Program.cs | 26 ++++++++++++++ .../console-di-ienumerable.csproj | 13 +++++++ .../console-di/console-di.csproj | 2 +- .../console-env/console-env.csproj | 2 +- .../console-host/console-host.csproj | 4 +-- .../console-ini/console-ini.csproj | 4 +-- .../console-json/console-json.csproj | 4 +-- .../console-memory/console-memory.csproj | 2 +- .../console-xml/console-xml.csproj | 4 +-- .../configuration/console/console.csproj | 2 +- .../custom-provider/custom-provider.csproj | 6 ++-- .../LoggingMessageWriter.cs | 2 +- .../dependency-injection.csproj | 2 +- .../worker-service-options.csproj | 2 +- .../worker-service/worker-service.csproj | 2 +- 23 files changed, 145 insertions(+), 28 deletions(-) create mode 100644 docs/core/extensions/snippets/configuration/console-di-ienumerable/ConsoleMessageWriter.cs create mode 100644 docs/core/extensions/snippets/configuration/console-di-ienumerable/ExampleService.cs create mode 100644 docs/core/extensions/snippets/configuration/console-di-ienumerable/IMessageWriter.cs create mode 100644 docs/core/extensions/snippets/configuration/console-di-ienumerable/LoggingMessageWriter.cs create mode 100644 docs/core/extensions/snippets/configuration/console-di-ienumerable/Program.cs create mode 100644 docs/core/extensions/snippets/configuration/console-di-ienumerable/console-di-ienumerable.csproj diff --git a/docs/core/extensions/dependency-injection.md b/docs/core/extensions/dependency-injection.md index a59784dd79469..b128ab4bb62ee 100644 --- a/docs/core/extensions/dependency-injection.md +++ b/docs/core/extensions/dependency-injection.md @@ -3,7 +3,7 @@ title: Dependency injection in .NET description: Learn how .NET implements dependency injection and how to use it. author: IEvangelist ms.author: dapine -ms.date: 09/23/2020 +ms.date: 10/28/2020 ms.topic: overview --- @@ -205,16 +205,41 @@ The framework provides service registration extension methods that are useful in For more information on type disposal, see the [Disposal of services](dependency-injection-guidelines.md#disposal-of-services) section. +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. + +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 `IMessageWriter` as the service type. The second call to `AddSingleton` overrides the previous one when resolved as `IMessageWriter` and adds to the previous one when multiple services are resolved via `IEnumerable`. Services appear in the order they were registered when resolved via `IEnumerable<{SERVICE}>`. + +:::code language="csharp" source="snippets/configuration/console-di-ienumerable/Program.cs" highlight="19-24"::: + +The preceding sample source code registers two implementations of the `IMessageWriter`. + +:::code language="csharp" source="snippets/configuration/console-di-ienumerable/ExampleService.cs" highlight="9-18"::: + +The `ExampleService` defines two constructor parameters; a single `IMessageWriter`, and an `IEnumerable`. The single `IMessageWriter` is the last implemenation to have been registered, whereas the `IEnumerable` represents all registered implementations. + The framework also provides `TryAdd{LIFETIME}` extension methods, which register the service only if there isn't already an implementation registered. -In the following example, the call to `AddSingleton` registers `MessageWriter` as an implementation for `IMessageWriter`. The call to `TryAddSingleton` has no effect because `IMessageWriter` already has a registered implementation: +In the following example, the call to `AddSingleton` registers `ConsoleMessageWriter` as an implementation for `IMessageWriter`. The call to `TryAddSingleton` has no effect because `IMessageWriter` already has a registered implementation: ```csharp -services.AddSingleton(); -services.TryAddSingleton(); +services.AddSingleton(); +services.TryAddSingleton(); ``` -The `TryAddSingleton` has no effect, as it was already added and the "try" will fail. +The `TryAddSingleton` has no effect, as it was already added and the "try" will fail. The `ExampleService` would assert the following: + +```csharp +public class ExampleService +{ + public ExampleService( + IMessageWriter messageWriter, + IEnumerable messageWriters) + { + Trace.Assert(messageWriter is ConsoleMessageWriter); + Trace.Assert(messageWriters.Single() is ConsoleMessageWriter); + } +} +``` For more information, see: diff --git a/docs/core/extensions/snippets/configuration/app-lifetime/app-lifetime.csproj b/docs/core/extensions/snippets/configuration/app-lifetime/app-lifetime.csproj index 44bf071e6eb6b..fee919e2d44f8 100644 --- a/docs/core/extensions/snippets/configuration/app-lifetime/app-lifetime.csproj +++ b/docs/core/extensions/snippets/configuration/app-lifetime/app-lifetime.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/core/extensions/snippets/configuration/console-custom-logging/console-custom-logging.csproj b/docs/core/extensions/snippets/configuration/console-custom-logging/console-custom-logging.csproj index bda98b726d9aa..c0c0960153d8c 100644 --- a/docs/core/extensions/snippets/configuration/console-custom-logging/console-custom-logging.csproj +++ b/docs/core/extensions/snippets/configuration/console-custom-logging/console-custom-logging.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/docs/core/extensions/snippets/configuration/console-di-disposable/console-di-disposable.csproj b/docs/core/extensions/snippets/configuration/console-di-disposable/console-di-disposable.csproj index 27be2f6602d77..f7bf79dca0f41 100644 --- a/docs/core/extensions/snippets/configuration/console-di-disposable/console-di-disposable.csproj +++ b/docs/core/extensions/snippets/configuration/console-di-disposable/console-di-disposable.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/core/extensions/snippets/configuration/console-di-ienumerable/ConsoleMessageWriter.cs b/docs/core/extensions/snippets/configuration/console-di-ienumerable/ConsoleMessageWriter.cs new file mode 100644 index 0000000000000..8afb1326bd6d8 --- /dev/null +++ b/docs/core/extensions/snippets/configuration/console-di-ienumerable/ConsoleMessageWriter.cs @@ -0,0 +1,11 @@ +using System; + +namespace ConsoleDI.IEnumerableExample +{ + public class ConsoleMessageWriter : IMessageWriter + { + public void Write(string message) => + Console.WriteLine( + $"ConsoleMessageWriter.Write(message: \"{message}\")"); + } +} diff --git a/docs/core/extensions/snippets/configuration/console-di-ienumerable/ExampleService.cs b/docs/core/extensions/snippets/configuration/console-di-ienumerable/ExampleService.cs new file mode 100644 index 0000000000000..77930c760717f --- /dev/null +++ b/docs/core/extensions/snippets/configuration/console-di-ienumerable/ExampleService.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace ConsoleDI.IEnumerableExample +{ + public class ExampleService + { + public ExampleService( + IMessageWriter messageWriter, + IEnumerable messageWriters) + { + Trace.Assert(messageWriter is LoggingMessageWriter); + + var dependencyArray = messageWriters.ToArray(); + Trace.Assert(dependencyArray[0] is ConsoleMessageWriter); + Trace.Assert(dependencyArray[1] is LoggingMessageWriter); + } + } +} diff --git a/docs/core/extensions/snippets/configuration/console-di-ienumerable/IMessageWriter.cs b/docs/core/extensions/snippets/configuration/console-di-ienumerable/IMessageWriter.cs new file mode 100644 index 0000000000000..4d97d536f87f5 --- /dev/null +++ b/docs/core/extensions/snippets/configuration/console-di-ienumerable/IMessageWriter.cs @@ -0,0 +1,7 @@ +namespace ConsoleDI.IEnumerableExample +{ + public interface IMessageWriter + { + void Write(string message); + } +} diff --git a/docs/core/extensions/snippets/configuration/console-di-ienumerable/LoggingMessageWriter.cs b/docs/core/extensions/snippets/configuration/console-di-ienumerable/LoggingMessageWriter.cs new file mode 100644 index 0000000000000..eaa3960e5ac71 --- /dev/null +++ b/docs/core/extensions/snippets/configuration/console-di-ienumerable/LoggingMessageWriter.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.Logging; + +namespace ConsoleDI.IEnumerableExample +{ + public class LoggingMessageWriter : IMessageWriter + { + private readonly ILogger _logger; + + public LoggingMessageWriter(ILogger logger) => + _logger = logger; + + public void Write(string message) => + _logger.LogInformation(message); + } +} diff --git a/docs/core/extensions/snippets/configuration/console-di-ienumerable/Program.cs b/docs/core/extensions/snippets/configuration/console-di-ienumerable/Program.cs new file mode 100644 index 0000000000000..fcbd111ee72a5 --- /dev/null +++ b/docs/core/extensions/snippets/configuration/console-di-ienumerable/Program.cs @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using ConsoleDI.IEnumerableExample; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace ConsoleDI.Example +{ + class Program + { + static Task Main(string[] args) + { + IHost host = CreateHostBuilder(args).Build(); + + _ = host.Services.GetService(); + + return host.RunAsync(); + } + + static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureServices((_, services) => + services.AddSingleton() + .AddSingleton() + .AddSingleton()); + } +} diff --git a/docs/core/extensions/snippets/configuration/console-di-ienumerable/console-di-ienumerable.csproj b/docs/core/extensions/snippets/configuration/console-di-ienumerable/console-di-ienumerable.csproj new file mode 100644 index 0000000000000..7d30462cc350e --- /dev/null +++ b/docs/core/extensions/snippets/configuration/console-di-ienumerable/console-di-ienumerable.csproj @@ -0,0 +1,13 @@ + + + + Exe + net5.0 + ConsoleDI.IEnumerableExample + + + + + + + diff --git a/docs/core/extensions/snippets/configuration/console-di/console-di.csproj b/docs/core/extensions/snippets/configuration/console-di/console-di.csproj index 50dcec6072ceb..e7213ab087e49 100644 --- a/docs/core/extensions/snippets/configuration/console-di/console-di.csproj +++ b/docs/core/extensions/snippets/configuration/console-di/console-di.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/core/extensions/snippets/configuration/console-env/console-env.csproj b/docs/core/extensions/snippets/configuration/console-env/console-env.csproj index 1729b313d18a1..861f0027e1efd 100644 --- a/docs/core/extensions/snippets/configuration/console-env/console-env.csproj +++ b/docs/core/extensions/snippets/configuration/console-env/console-env.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/core/extensions/snippets/configuration/console-host/console-host.csproj b/docs/core/extensions/snippets/configuration/console-host/console-host.csproj index ff74c8ecd4112..40f303596554d 100644 --- a/docs/core/extensions/snippets/configuration/console-host/console-host.csproj +++ b/docs/core/extensions/snippets/configuration/console-host/console-host.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/docs/core/extensions/snippets/configuration/console-ini/console-ini.csproj b/docs/core/extensions/snippets/configuration/console-ini/console-ini.csproj index 05cc948039b15..ac368e55d5cc9 100644 --- a/docs/core/extensions/snippets/configuration/console-ini/console-ini.csproj +++ b/docs/core/extensions/snippets/configuration/console-ini/console-ini.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/docs/core/extensions/snippets/configuration/console-json/console-json.csproj b/docs/core/extensions/snippets/configuration/console-json/console-json.csproj index 59c19da27f4c2..d1aa83c8cec79 100644 --- a/docs/core/extensions/snippets/configuration/console-json/console-json.csproj +++ b/docs/core/extensions/snippets/configuration/console-json/console-json.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/docs/core/extensions/snippets/configuration/console-memory/console-memory.csproj b/docs/core/extensions/snippets/configuration/console-memory/console-memory.csproj index 8392441bfc032..3ea4dd81fca35 100644 --- a/docs/core/extensions/snippets/configuration/console-memory/console-memory.csproj +++ b/docs/core/extensions/snippets/configuration/console-memory/console-memory.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/core/extensions/snippets/configuration/console-xml/console-xml.csproj b/docs/core/extensions/snippets/configuration/console-xml/console-xml.csproj index b4cfea4b98bdb..f03adb27014e0 100644 --- a/docs/core/extensions/snippets/configuration/console-xml/console-xml.csproj +++ b/docs/core/extensions/snippets/configuration/console-xml/console-xml.csproj @@ -21,8 +21,8 @@ - - + + diff --git a/docs/core/extensions/snippets/configuration/console/console.csproj b/docs/core/extensions/snippets/configuration/console/console.csproj index 50addbfec1e20..fcff3112ca134 100644 --- a/docs/core/extensions/snippets/configuration/console/console.csproj +++ b/docs/core/extensions/snippets/configuration/console/console.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/core/extensions/snippets/configuration/custom-provider/custom-provider.csproj b/docs/core/extensions/snippets/configuration/custom-provider/custom-provider.csproj index 4c4c3542874e0..ca91778dc8dc1 100644 --- a/docs/core/extensions/snippets/configuration/custom-provider/custom-provider.csproj +++ b/docs/core/extensions/snippets/configuration/custom-provider/custom-provider.csproj @@ -7,9 +7,9 @@ - - - + + + diff --git a/docs/core/extensions/snippets/configuration/dependency-injection/LoggingMessageWriter.cs b/docs/core/extensions/snippets/configuration/dependency-injection/LoggingMessageWriter.cs index c3ac8b53475ef..85db642526850 100644 --- a/docs/core/extensions/snippets/configuration/dependency-injection/LoggingMessageWriter.cs +++ b/docs/core/extensions/snippets/configuration/dependency-injection/LoggingMessageWriter.cs @@ -9,7 +9,7 @@ public class LoggingMessageWriter : IMessageWriter public LoggingMessageWriter(ILogger logger) => _logger = logger; - public void Write(string message) => + public void Write(string message) => _logger.LogInformation(message); } } diff --git a/docs/core/extensions/snippets/configuration/dependency-injection/dependency-injection.csproj b/docs/core/extensions/snippets/configuration/dependency-injection/dependency-injection.csproj index 59cd25c5b8087..c4cbdc83c4786 100644 --- a/docs/core/extensions/snippets/configuration/dependency-injection/dependency-injection.csproj +++ b/docs/core/extensions/snippets/configuration/dependency-injection/dependency-injection.csproj @@ -6,6 +6,6 @@ - + diff --git a/docs/core/extensions/snippets/configuration/worker-service-options/worker-service-options.csproj b/docs/core/extensions/snippets/configuration/worker-service-options/worker-service-options.csproj index 4eda3aaca0632..86172782cb105 100644 --- a/docs/core/extensions/snippets/configuration/worker-service-options/worker-service-options.csproj +++ b/docs/core/extensions/snippets/configuration/worker-service-options/worker-service-options.csproj @@ -8,6 +8,6 @@ - + diff --git a/docs/core/extensions/snippets/configuration/worker-service/worker-service.csproj b/docs/core/extensions/snippets/configuration/worker-service/worker-service.csproj index 6305ab9927c95..f07eca52253fb 100644 --- a/docs/core/extensions/snippets/configuration/worker-service/worker-service.csproj +++ b/docs/core/extensions/snippets/configuration/worker-service/worker-service.csproj @@ -7,6 +7,6 @@ - + From d6f7928ac1a2acbbdfaa56c3d446b397dcf9291a Mon Sep 17 00:00:00 2001 From: David Pine Date: Wed, 28 Oct 2020 11:49:09 -0500 Subject: [PATCH 2/2] Added missing access-by-lines.txt file for all fundamentals work. --- docs/core/extensions/access-by-line.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 docs/core/extensions/access-by-line.txt diff --git a/docs/core/extensions/access-by-line.txt b/docs/core/extensions/access-by-line.txt new file mode 100644 index 0000000000000..ad3a08e3a2b3b --- /dev/null +++ b/docs/core/extensions/access-by-line.txt @@ -0,0 +1,22 @@ +snippets/configuration/dependency-injection/Program.cs: ~/docs/core/extensions/dependency-injection.md +snippets/configuration/console-di-ienumerable/Program.cs: ~/docs/core/extensions/dependency-injection.md +snippets/configuration/console-di-ienumerable/ExampleService.cs: ~/docs/core/extensions/dependency-injection.md +snippets/configuration/console-json/Program.cs: ~/docs/core/extensions/configuration-providers.md +snippets/configuration/console-xml/Program.cs: ~/docs/core/extensions/configuration-providers.md +snippets/configuration/console-ini/Program.cs: ~/docs/core/extensions/configuration-providers.md +snippets/configuration/console/Program.cs: ~/docs/core/extensions/configuration.md +snippets/logging/console-formatter-simple/Program.cs: ~/docs/core/extensions/custom-log-formatter.md +snippets/configuration/custom-provider/Program.cs: ~/docs/core/extensions/custom-configuration-provider.md +snippets/configuration/console-custom-logging/ColorConsoleLogger.cs: ~/docs/core/extensions/custom-logging-provider.md +snippets/configuration/console-di-disposable/Program.cs: ~/docs/core/extensions/dependency-injection-guidelines.md +snippets/configuration/console-di/Program.cs: ~/docs/core/extensions/dependency-injection-usage.md +snippets/configuration/console-host/Program.cs: ~/docs/core/extensions/generic-host.md +snippets/configuration/app-lifetime/Program.cs: ~/docs/core/extensions/generic-host.md +snippets/configuration/app-lifetime/ExampleHostedService.cs: ~/docs/core/extensions/generic-host.md +snippets/configuration/worker-service-options/Worker.cs: ~/docs/core/extensions/high-performance-logging.md +snippets/configuration/console/Program.cs: ~/docs/core/extensions/logging-providers.md +snippets/configuration/worker-service/appsettings.IncludeScopes.json: ~/docs/core/extensions/logging.md +snippets/configuration/worker-service/Worker.cs: ~/docs/core/extensions/logging.md +snippets/configuration/console-json/appsettings.json: ~/docs/core/extensions/options.md +snippets/configuration/console-json/TransientFaultHandlingOptions.cs: ~/docs/core/extensions/options.md +snippets/configuration/console-json/Program.cs: ~/docs/core/extensions/options.md