You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/core/deploying/native-aot/index.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,8 @@
2
2
title: Native AOT deployment overview
3
3
description: Learn what Native AOT deployments are and why you should consider using it as part of the publishing your app with .NET 7 and later.
4
4
author: lakshanf
5
-
ms.date: 06/12/2023
5
+
ms.date: 10/22/2025
6
+
ai-usage: ai-assisted
6
7
---
7
8
8
9
# Native AOT deployment
@@ -134,7 +135,7 @@ Native AOT apps have the following limitations:
134
135
- Implies compilation into a single file, which has known [incompatibilities](../single-file/overview.md#api-incompatibility).
135
136
- Apps include required runtime libraries (just like [self-contained apps](../index.md#self-contained-deployment), increasing their size as compared to framework-dependent apps).
136
137
-<xref:System.Linq.Expressions> always use their interpreted form, which is slower than run-time generated compiled code.
137
-
- Generic parameters substituted with struct type arguments will have specialized code generated for each instantiation. In the dynamic runtime, many instantiations are generated on-demand. In Native AOT, all instantiations are pre-generated. This can have significant impact to the disk size of the application. Generic virtual methods and generic instance methods will also have an instantiation for every implementing or overriding type.
138
+
- Generic parameters substituted with struct type arguments have specialized code generated for each instantiation. In the dynamic runtime, many instantiations are generated on-demand. In Native AOT, all instantiations are pre-generated. This can have significant impact to the disk size of the application. Generic virtual methods and generic instance methods will also have an instantiation for every implementing or overriding type.
138
139
- Not all the runtime libraries are fully annotated to be Native AOT compatible. That is, some warnings in the runtime libraries aren't actionable by end developers.
139
140
-[Diagnostic support for debugging and profiling](./diagnostics.md) with some limitations.
140
141
- Support for some ASP.NET Core features. For more information, see [ASP.NET Core support for Native AOT](/aspnet/core/fundamentals/native-aot/).
Copy file name to clipboardExpand all lines: docs/core/deploying/single-file/overview.md
+6-5Lines changed: 6 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,8 +2,9 @@
2
2
title: Create a single file for application deployment
3
3
description: Learn what single file application is and why you should consider using this application deployment model.
4
4
author: lakshanf
5
-
ms.date: 06/21/2022
5
+
ms.date: 10/22/2025
6
6
ms.custom: kr2b-contr-experiment
7
+
ai-usage: ai-assisted
7
8
---
8
9
9
10
# Single-file deployment
@@ -209,11 +210,11 @@ We have some recommendations for fixing common scenarios:
209
210
210
211
Some workflows require post-processing of binaries before bundling. A common example is signing. The dotnet SDK provides MSBuild extension points to allow processing binaries just before single-file bundling. The available APIs are:
211
212
212
-
- A target `PrepareForBundle` that will be called before `GenerateSingleFileBundle`
213
-
- An `<ItemGroup><FilesToBundle /></ItemGroup>` containing all files that will be bundled
213
+
- A target `PrepareForBundle` that is called before `GenerateSingleFileBundle`
214
+
- An `<ItemGroup><FilesToBundle /></ItemGroup>` containing all files that are to be bundled
214
215
- A Property `AppHostFile` that will specify the apphost template. Post-processing might want to exclude the apphost from processing.
215
216
216
-
To plug into this involves creating a target that will be executed between `PrepareForBundle` and `GenerateSingleFileBundle`.
217
+
To plug into this involves creating a target that is executed between `PrepareForBundle` and `GenerateSingleFileBundle`.
217
218
218
219
Consider the following .NET project `Target` node example:
219
220
@@ -225,7 +226,7 @@ It's possible that tooling will need to copy files in the process of signing. Th
225
226
226
227
### Compress assemblies in single-file apps
227
228
228
-
Single-file apps can be created with compression enabled on the embedded assemblies. Set the `EnableCompressionInSingleFile` property to `true`. The single file that's produced will have all of the embedded assemblies compressed, which can significantly reduce the size of the executable.
229
+
Single-file apps can be created with compression enabled on the embedded assemblies. Set the `EnableCompressionInSingleFile` property to `true`. The single file that's produced has all of the embedded assemblies compressed, which can significantly reduce the size of the executable.
229
230
230
231
Compression comes with a performance cost. On application start, the assemblies must be decompressed into memory, which takes some time. We recommend that you measure both the size change and startup cost of enabling compression before using it. The impact can vary significantly between different applications.
If the `cache` contains the `letter` key, and the `value` is an instance of an `AlphabetLetter` it's written to the console. When the `letter` key is not in the cache, it was evicted and its post eviction callback was invoked.
99
+
If the `cache` contains the `letter` key, and the `value` is an instance of an `AlphabetLetter` it's written to the console. When the `letter` key isn't in the cache, it was evicted and its post eviction callback was invoked.
99
100
100
101
#### Additional extension methods
101
102
@@ -261,7 +262,7 @@ Consider any of the available implementations of the `IDistributedCache` from th
261
262
262
263
### Distributed caching API
263
264
264
-
The distributed caching APIs are a bit more primitive than their in-memory caching API counterparts. The key-value pairs are a bit more basic. In-memory caching keys are based on an `object`, whereas the distributed keys are a `string`. With in-memory caching, the value can be any strongly-typed generic, whereas values in distributed caching are persisted as `byte[]`. That's not to say that various implementations don't expose strongly-typed generic values but that would be an implementation detail.
265
+
The distributed caching APIs are a bit more primitive than their in-memory caching API counterparts. The key-value pairs are a bit more basic. In-memory caching keys are based on an `object`, whereas the distributed keys are a `string`. With in-memory caching, the value can be any stronglytyped generic, whereas values in distributed caching are persisted as `byte[]`. That's not to say that various implementations don't expose stronglytyped generic values, but that's an implementation detail.
Copy file name to clipboardExpand all lines: docs/core/extensions/channels.md
+6-5Lines changed: 6 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,8 @@ title: Channels
3
3
description: Learn the official synchronization data structures in System.Threading.Channels for producers and consumers with .NET.
4
4
author: IEvangelist
5
5
ms.author: dapine
6
-
ms.date: 06/26/2023
6
+
ms.date: 10/22/2025
7
+
ai-usage: ai-assisted
7
8
---
8
9
9
10
# System.Threading.Channels library
@@ -14,7 +15,7 @@ This library is available in the [System.Threading.Channels](https://www.nuget.o
14
15
15
16
## Producer/consumer conceptual programming model
16
17
17
-
Channels are an implementation of the producer/consumer conceptual programming model. In this programming model, producers asynchronously produce data, and consumers asynchronously consume that data. In other words, this model passes data from one party to another through a first-in first-out ("FIFO") queue. Try to think of channels as you would any other common generic collection type, such as a `List<T>`. The primary difference is that this collection manages synchronization and provides various consumption models through factory creation options. These options control the behavior of the channels, such as how many elements they're allowed to store and what happens if that limit is reached, or whether the channel is accessed by multiple producers or multiple consumers concurrently.
18
+
Channels are an implementation of the producer/consumer conceptual programming model. In this programming model, producers asynchronously produce data, and consumers asynchronously consume that data. In other words, this model passes data from one party to another through a first-in first-out ("FIFO") queue. Think of channels as any other common generic collection type, such as a `List<T>`. The primary difference is that this collection manages synchronization and provides various consumption models through factory creation options. These options control the behavior of the channels, such as how many elements they're allowed to store and what happens if that limit is reached, or whether the channel is accessed by multiple producers or multiple consumers concurrently.
18
19
19
20
## Bounding strategies
20
21
@@ -23,7 +24,7 @@ Depending on how a `Channel<T>` is created, its reader and writer behave differe
23
24
To create a channel that specifies a maximum capacity, call <xref:System.Threading.Channels.Channel.CreateBounded%2A?displayProperty=nameWithType>. To create a channel that is used by any number of readers and writers concurrently, call <xref:System.Threading.Channels.Channel.CreateUnbounded%2A?displayProperty=nameWithType>. Each bounding strategy exposes various creator-defined options, either <xref:System.Threading.Channels.BoundedChannelOptions> or <xref:System.Threading.Channels.UnboundedChannelOptions> respectively.
24
25
25
26
> [!NOTE]
26
-
> Regardless of the bounding strategy, a channel will always throw a <xref:System.Threading.Channels.ChannelClosedException> when it's used after it's been closed.
27
+
> Regardless of the bounding strategy, a channel always throws a <xref:System.Threading.Channels.ChannelClosedException> when it's used after it's been closed.
27
28
28
29
### Unbounded channels
29
30
@@ -140,7 +141,7 @@ An alternative producer might use the `WriteAsync` method:
Again, the `Channel<Coordinates>.Writer` is used within a `while` loop. But this time, the <xref:System.Threading.Channels.ChannelWriter%601.WriteAsync%2A> method is called. The method will continue only after the coordinates have been written. When the `while` loop exits, a call to <xref:System.Threading.Channels.ChannelWriter%601.Complete%2A> is made, which signals that no more data is written to the channel.
144
+
Again, the `Channel<Coordinates>.Writer` is used within a `while` loop. But this time, the <xref:System.Threading.Channels.ChannelWriter%601.WriteAsync%2A> method is called. The method continues only after the coordinates have been written. When the `while` loop exits, a call to <xref:System.Threading.Channels.ChannelWriter%601.Complete%2A> is made, which signals that no more data is written to the channel.
144
145
145
146
Another producer pattern is to use the <xref:System.Threading.Channels.ChannelWriter%601.WaitToWriteAsync%2A> method, consider the following code:
146
147
@@ -155,7 +156,7 @@ There are several common channel consumer patterns. When a channel is never endi
description: Discover effective dependency injection guidelines and best practices for developing .NET apps. Deepen your understanding of inversion of control.
4
4
author: IEvangelist
5
5
ms.author: dapine
6
-
ms.date: 07/18/2024
6
+
ms.date: 10/22/2025
7
7
ms.topic: concept-article
8
+
ai-usage: ai-assisted
8
9
---
9
10
10
11
# Dependency injection guidelines
@@ -91,7 +92,7 @@ The app requires an <xref:System.IDisposable> instance with a transient lifetime
91
92
92
93
**Solution**
93
94
94
-
Use the factory pattern to create an instance outside of the parent scope. In this situation, the app would generally have a `Create` method that calls the final type's constructor directly. If the final type has other dependencies, the factory can:
95
+
Use the factory pattern to create an instance outside of the parent scope. In this situation, the app generally has a `Create` method that calls the final type's constructor directly. If the final type has other dependencies, the factory can:
95
96
96
97
- Receive an <xref:System.IServiceProvider> in its constructor.
97
98
- Use <xref:Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance%2A?displayProperty=nameWithType> to instantiate the instance outside of the container, while using the container for its dependencies.
@@ -158,8 +159,8 @@ The factory method of a singleton service, such as the second argument to [AddSi
158
159
-**Coupling**: It can couple otherwise unrelated requests.
159
160
-**Testing challenges**: Shared state and coupling can make unit testing more difficult.
160
161
-**Memory impact**: A singleton may keep a large object graph alive in memory for the lifetime of the application.
161
-
-**Fault tolerance**: If a singleton or any part of its dependency tree fails, it cannot easily recover.
162
-
-**Configuration reloading**: Singletons generally cannot support "hot reload" of configuration values.
162
+
-**Fault tolerance**: If a singleton or any part of its dependency tree fails, it can't easily recover.
163
+
-**Configuration reloading**: Singletons generally can't support "hot reload" of configuration values.
163
164
-**Scope leakage**: A singleton can inadvertently capture scoped or transient dependencies, effectively promoting them to singletons and causing unintended side effects.
164
165
-**Initialization overhead**: When resolving a service, the IoC container needs to look up the singleton instance. If it doesn't already exist, it needs to create it in a thread-safe manner. In contrast, a stateless transient service is very cheap to create and destroy.
165
166
@@ -180,7 +181,7 @@ When you register *Transient* services that implement <xref:System.IDisposable>,
180
181
181
182
:::image type="content" source="media/transient-disposables-without-dispose.png" lightbox="media/transient-disposables-without-dispose.png" alt-text="Anti-pattern: Transient disposables without dispose. Do not copy!":::
182
183
183
-
In the preceding anti-pattern, 1,000 `ExampleDisposable` objects are instantiated and rooted. They will not be disposed of until the `serviceProvider` instance is disposed.
184
+
In the preceding anti-pattern, 1,000 `ExampleDisposable` objects are instantiated and rooted. They won't be disposed of until the `serviceProvider` instance is disposed.
184
185
185
186
For more information on debugging memory leaks, see [Debug a memory leak in .NET](../diagnostics/debug-memory-leak.md).
186
187
@@ -208,7 +209,7 @@ In the preceding code, `Foo` is registered as a singleton and `Bar` is scoped -
The `Foo` object requires a `Bar` object, and since `Foo` is a singleton, and `Bar` is scoped - this is a misconfiguration. As is, `Foo`would only be instantiated once, and it would hold onto `Bar` for its lifetime, which is longer than the intended scoped lifetime of `Bar`. You should consider validating scopes, by passing `validateScopes: true` to the <xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Boolean)>. When you validate the scopes, you'd get an <xref:System.InvalidOperationException> with a message similar to "Cannot consume scoped service 'Bar' from singleton 'Foo'.".
212
+
The `Foo` object requires a `Bar` object, and since `Foo` is a singleton, and `Bar` is scoped - this is a misconfiguration. As is, `Foo`is only instantiated once, and it holds onto `Bar` for its lifetime, which is longer than the intended scoped lifetime of `Bar`. Consider validating scopes by passing `validateScopes: true` to the <xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Boolean)>. When you validate the scopes, you get an <xref:System.InvalidOperationException> with a message similar to "Cannot consume scoped service 'Bar' from singleton 'Foo'.".
212
213
213
214
For more information, see [Scope validation](dependency-injection.md#scope-validation).
Copy file name to clipboardExpand all lines: docs/core/extensions/dependency-injection-usage.md
+7-6Lines changed: 7 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,9 +3,10 @@ title: Use dependency injection
3
3
description: Learn how to use dependency injection in your .NET apps with this comprehensive tutorial. Follow along with this pragmatic guide to understand DI in C#.
4
4
author: IEvangelist
5
5
ms.author: dapine
6
-
ms.date: 07/18/2024
6
+
ms.date: 10/22/2025
7
7
ms.topic: tutorial
8
8
no-loc: [Transient, Scoped, Singleton, Example]
9
+
ai-usage: ai-assisted
9
10
---
10
11
11
12
# Tutorial: Use dependency injection in .NET
@@ -39,7 +40,7 @@ Your new console app project file should resemble the following:
39
40
40
41
## Add interfaces
41
42
42
-
In this sample app, you'll learn how dependency injection handles service lifetime. You'll create several interfaces that represent different service lifetimes. Add the following interfaces to the project root directory:
43
+
In this sample app, you learn how dependency injection handles service lifetime. You create several interfaces that represent different service lifetimes. Add the following interfaces to the project root directory:
43
44
44
45
*IReportServiceLifetime.cs*
45
46
@@ -80,7 +81,7 @@ The example implementations all initialize their `Id` property with the result o
Each implementation is defined as `internal sealed` and implements its corresponding interface. They're not required to be `internal` or `sealed`, however, it's common to treat implementations as `internal` to avoid leaking implementation types to external consumers. Furthermore, since each type will not be extended, it's marked as `sealed`. For example, `ExampleSingletonService` implements `IExampleSingletonService`.
84
+
Each implementation is defined as `internal sealed` and implements its corresponding interface. They're not required to be `internal` or `sealed`, however, it's common to treat implementations as `internal` to avoid leaking implementation types to external consumers. Furthermore, since each type isn't extended, it's marked as `sealed`. For example, `ExampleSingletonService` implements `IExampleSingletonService`.
84
85
85
86
## Add a service that requires DI
86
87
@@ -100,7 +101,7 @@ Update *Program.cs* with the following code:
100
101
101
102
Each `services.Add{LIFETIME}<{SERVICE}>` extension method adds (and potentially configures) services. We recommend that apps follow this convention. Don't place extension methods in the <xref:Microsoft.Extensions.DependencyInjection?displayProperty=fullName> namespace unless you're authoring an official Microsoft package. Extension methods that are defined within the `Microsoft.Extensions.DependencyInjection` namespace:
102
103
103
-
- Are displayed in [IntelliSense](/visualstudio/ide/using-intellisense) without requiring additional`using` directives.
104
+
- Are displayed in [IntelliSense](/visualstudio/ide/using-intellisense) without requiring more`using` directives.
104
105
- Reduce the number of required `using` directives in the `Program` or `Startup` classes where these extension methods are typically called.
105
106
106
107
The app:
@@ -120,9 +121,9 @@ When you run the app, it displays output similar to the following:
120
121
121
122
From the app output, you can see that:
122
123
123
-
- Transient services are always different, a new instance is created with every retrieval of the service.
124
+
- Transient services are always different. A new instance is created with every retrieval of the service.
124
125
- Scoped services change only with a new scope, but are the same instance within a scope.
125
-
- Singleton services are always the same, a new instance is only created once.
126
+
- Singleton services are always the same. A new instance is only created once.
0 commit comments