Skip to content

Commit 525045a

Browse files
authored
Merge pull request #34473 from dotnet/main
2 parents 17b693c + cfd160d commit 525045a

File tree

5 files changed

+76
-70
lines changed

5 files changed

+76
-70
lines changed

aspnetcore/blazor/javascript-interoperability/static-server-rendering.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,14 @@ export function onDispose() {
9797
}
9898
```
9999

100-
In a [Razor Class Library (RCL)](xref:blazor/components/class-libraries) (the example RCL is named `BlazorPageScript`), add the following module.
100+
In a [Razor Class Library (RCL)](xref:blazor/components/class-libraries) (the example RCL is named `BlazorPageScript`), add the following module, which is a [JS initializer](xref:blazor/fundamentals/startup#javascript-initializers).
101101

102102
`wwwroot/BlazorPageScript.lib.module.js`:
103103

104104
[!INCLUDE[](~/blazor/includes/js-interop/blazor-page-script.md)]
105105

106+
Do ***not*** add a `<script>` tag to the app's root component, typically the `App` componennt, for `BlazorPageScript.lib.module.js` because the module in this case is a [JS initializer (`afterWebStarted`)](xref:blazor/fundamentals/startup#javascript-initializers). JS initializers are detected and loaded automatically by the Blazor framework.
107+
106108
In the RCL, add the following `PageScript` component.
107109

108110
`PageScript.razor`:
@@ -129,6 +131,8 @@ To reuse the same module among pages, but have the `onLoad` and `onDispose` call
129131

130132
To monitor changes in specific DOM elements, use the [`MutationObserver`](https://developer.mozilla.org/docs/Web/API/MutationObserver) pattern in JS on the client. For more information, see <xref:blazor/js-interop/index#dom-cleanup-tasks-during-component-disposal>.
131133

132-
## Example implementation without using an RCL
134+
## Implementation without using an RCL
135+
136+
The approach described in this article can be implemented directly in a Blazor Web App without using a Razor class library (RCL) by moving the assets of the RCL into the app. However, the use of an RCL is convenient because the RCL can be packaged into a NuGet package for consumption by Blazor apps across an organization.
133137

134-
The approach described in this article can be implemented directly in a Blazor Web App without using a Razor class library (RCL). For an example, see <xref:blazor/security/qrcodes-for-authenticator-apps>.
138+
If you move the assets into a Blazor Web App, be sure to rename the module (`BlazorPageScript.lib.module.js`) to match the app per the file naming rules for [JS initializers](xref:blazor/fundamentals/startup#javascript-initializers). If the file isn't named correctly, Blazor can't detect and load the module, and the `afterWebStarted` event doesn't execute automatically when the app starts.

aspnetcore/fundamentals/dependency-injection.md

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ By [Kirk Larkin](https://twitter.com/serpent5), [Steve Smith](https://ardalis.co
1717

1818
ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving [Inversion of Control (IoC)](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#dependency-inversion) between classes and their dependencies.
1919

20-
For more information specific to dependency injection within MVC controllers, see <xref:mvc/controllers/dependency-injection>.
20+
For Blazor DI guidance, which adds to or supersedes the guidance in this article, see <xref:blazor/fundamentals/dependency-injection>.
2121

22-
For information on using dependency injection in applications other than web apps, see [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection).
22+
For information specific to dependency injection within MVC controllers, see <xref:mvc/controllers/dependency-injection>.
2323

24-
For more information on dependency injection of options, see <xref:fundamentals/configuration/options>.
24+
For information on using dependency injection in applications other than web apps, see [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection).
2525

26-
This topic provides information on dependency injection in ASP.NET Core. The primary documentation on using dependency injection is contained in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection).
26+
For information on dependency injection of options, see <xref:fundamentals/configuration/options>.
2727

28-
For Blazor DI guidance, which adds to or supersedes the guidance in this article, see <xref:blazor/fundamentals/dependency-injection>.
28+
This article provides information on dependency injection in ASP.NET Core. The primary documentation on using dependency injection is contained in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection).
2929

3030
[View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/dependency-injection/samples) ([how to download](xref:index#how-to-download-a-sample))
3131

@@ -59,7 +59,7 @@ This interface is implemented by a concrete type, `MyDependency`:
5959

6060
[!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Services/MyDependency.cs?name=snippet1)]
6161

62-
The sample app registers the `IMyDependency` service with the concrete type `MyDependency`. The <xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddScoped%2A> method registers the service with a scoped lifetime, the lifetime of a single request. [Service lifetimes](#service-lifetimes) are described later in this topic.
62+
The sample app registers the `IMyDependency` service with the concrete type `MyDependency`. The <xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddScoped%2A> method registers the service with a scoped lifetime, the lifetime of a single request. [Service lifetimes](#service-lifetimes) are described later in this article.
6363

6464
[!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Program.cs?name=snippet1)]
6565

@@ -89,13 +89,13 @@ The container resolves `ILogger<TCategoryName>` by taking advantage of [(generic
8989
In dependency injection terminology, a service:
9090

9191
* Is typically an object that provides a service to other objects, such as the `IMyDependency` service.
92-
* Is not related to a web service, although the service may use a web service.
92+
* Is not related to a web service, although the service might use a web service.
9393

9494
The framework provides a robust [logging](xref:fundamentals/logging/index) system. The `IMyDependency` implementations shown in the preceding examples were written to demonstrate basic DI, not to implement logging. Most apps shouldn't need to write loggers. The following code demonstrates using the default logging, which doesn't require any services to be registered:
9595

9696
[!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Pages/About.cshtml.cs?name=snippet)]
9797

98-
Using the preceding code, there is no need to update `Program.cs`, because [logging](xref:fundamentals/logging/index) is provided by the framework.
98+
The preceding code works correctly without changing anything in `Program.cs`, because [logging](xref:fundamentals/logging/index) is provided by the framework.
9999

100100
## Register groups of services with extension methods
101101

@@ -124,9 +124,9 @@ See [Service registration methods](/dotnet/core/extensions/dependency-injection#
124124

125125
It's common to use multiple implementations when [mocking types for testing](xref:test/integration-tests#inject-mock-services).
126126

127-
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.
127+
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 can't be registered using the methods that don't take an explicit service type. These methods can register multiple *instances* of a service, but they all have the same *implementation* type.
128128

129-
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}>`.
129+
Any of these 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}>`.
130130

131131
```csharp
132132
services.AddSingleton<IMyDependency, MyDependency>();
@@ -148,7 +148,7 @@ public class MyService
148148

149149
### Keyed services
150150

151-
*Keyed services* refers to a mechanism for registering and retrieving Dependency Injection (DI) services using keys. A service is associated with a key by calling <xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddKeyedSingleton%2A> (or `AddKeyedScoped` or `AddKeyedTransient`) to register it. Access a registered service by specifying the key with the [`[FromKeyedServices]`](xref:Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttribute) attribute. The following code shows how to use keyed services:
151+
The term *keyed services* refers to a mechanism for registering and retrieving Dependency Injection (DI) services using keys. A service is associated with a key by calling <xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddKeyedSingleton%2A> (or `AddKeyedScoped` or `AddKeyedTransient`) to register it. Access a registered service by specifying the key with the [`[FromKeyedServices]`](xref:Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttribute) attribute. The following code shows how to use keyed services:
152152

153153
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/samples/KeyedServices9/Program.cs" highlight="6,7,12-14,39,47" id="snippet_1":::
154154

@@ -204,7 +204,7 @@ To reduce the logging output, set "Logging:LogLevel:Microsoft:Error" in the `app
204204

205205
[!code-json[](~/fundamentals/dependency-injection/samples/3.x/DependencyInjectionSample/appsettings.Development.json?highlight=7)]
206206

207-
## Resolve a service at app start up
207+
## Resolve a service at app startup
208208

209209
The following code shows how to resolve a scoped service for a limited duration when the app starts:
210210

@@ -233,7 +233,7 @@ When designing services for dependency injection:
233233
* Avoid direct instantiation of dependent classes within services. Direct instantiation couples the code to a particular implementation.
234234
* Make services small, well-factored, and easily tested.
235235

236-
If a class has a lot of injected dependencies, it might be a sign that the class has too many responsibilities and violates the [Single Responsibility Principle (SRP)](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#single-responsibility). Attempt to refactor the class by moving some of its responsibilities into new classes. Keep in mind that Razor Pages page model classes and MVC controller classes should focus on UI concerns.
236+
If a class has many injected dependencies, it might be a sign that the class has too many responsibilities and violates the [Single Responsibility Principle (SRP)](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#single-responsibility). Attempt to refactor the class by moving some of its responsibilities into new classes. Keep in mind that Razor Pages page model classes and MVC controller classes should focus on UI concerns.
237237

238238
### Disposal of services
239239

@@ -309,32 +309,11 @@ See [Recommendations](/dotnet/core/extensions/dependency-injection-guidelines#re
309309
* Another service locator variation to avoid is injecting a factory that resolves dependencies at runtime. Both of these practices mix [Inversion of Control](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#dependency-inversion) strategies.
310310
* Avoid static access to `HttpContext` (for example, [IHttpContextAccessor.HttpContext](xref:Microsoft.AspNetCore.Http.IHttpContextAccessor.HttpContext)).
311311

312-
<!--
313-
<a name="ASP0000"></a>
314-
* Avoid calls to <xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider%2A> in `ConfigureServices`. For example, consider the case where the `LoginPath` is loaded from configuration. Avoid the following approach:
315-
316-
![bad code calling BuildServiceProvider](~/fundamentals/dependency-injection/_static/badcodeX.png)
317-
318-
In the preceding image, selecting the green wavy line under `services.BuildServiceProvider` shows the following ASP0000 warning:
319-
320-
> ASP0000 Calling 'BuildServiceProvider' from application code results in an additional copy of singleton services being created. Consider alternatives such as dependency injecting services as parameters to 'Configure'.
321-
322-
Calling `BuildServiceProvider` creates a second container, which can create torn singletons and cause references to object graphs across multiple containers.
323-
324-
A correct way to get `LoginPath` is to use the options pattern's built-in support for DI:
325-
326-
[!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/AntiPattern3/Program.cs?name=snippet)]
327-
328-
* Disposable transient services are captured by the container for disposal. This can turn into a memory leak if resolved from the top level container.
329-
* Enable scope validation to make sure the app doesn't have singletons that capture scoped services. For more information, see [Scope validation](#scope-validation).
330-
331-
Like all sets of recommendations, you may encounter situations where ignoring a recommendation is required. Exceptions are rare, mostly special cases within the framework itself.
332-
-->
333-
DI is an *alternative* to static/global object access patterns. You may not be able to realize the benefits of DI if you mix it with static object access.
312+
DI is an *alternative* to static/global object access patterns. You might not be able to realize the benefits of DI if you mix it with static object access.
334313

335314
## Recommended patterns for multi-tenancy in DI
336315

337-
[Orchard Core](https://github.com/OrchardCMS/OrchardCore) is an application framework for building modular, multi-tenant applications on ASP.NET Core. For more information, see the [Orchard Core Documentation](https://docs.orchardcore.net).
316+
[Orchard Core](https://github.com/OrchardCMS/OrchardCore) is an application framework for building modular, multitenant applications on ASP.NET Core. For more information, see the [Orchard Core Documentation](https://docs.orchardcore.net).
338317

339318
See the [Orchard Core samples](https://github.com/OrchardCMS/OrchardCore.Samples) for examples of how to build modular and multi-tenant apps using just the Orchard Core Framework without any of its CMS-specific features.
340319

@@ -363,10 +342,10 @@ The following table lists a small sample of these framework-registered services:
363342

364343
## Additional resources
365344

345+
* <xref:blazor/fundamentals/dependency-injection>
366346
* <xref:mvc/views/dependency-injection>
367347
* <xref:mvc/controllers/dependency-injection>
368348
* <xref:security/authorization/dependencyinjection>
369-
* <xref:blazor/fundamentals/dependency-injection>
370349
* [NDC Conference Patterns for DI app development](https://www.youtube.com/watch?v=x-C-CNBVTaY)
371350
* <xref:fundamentals/startup>
372351
* <xref:fundamentals/middleware/extensibility>

aspnetcore/test/http-files.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ This article contains documentation for:
2121
* [The `.http` file syntax](#http-file-syntax).
2222
* [How to create an `.http` file](#create-an-http-file).
2323
* [How to send a request from an `.http` file](#send-an-http-request).
24-
* [Where to find `.http` file options that can be configured.](#http-file-options).
24+
* [Where to find `.http` file options that can be configured](#http-file-options).
2525
* [How to create requests in `.http` files by using the Visual Studio 2022 **Endpoints Explorer**](#use-endpoints-explorer).
2626

2727
The `.http` file format and editor was inspired by the Visual Studio Code [REST Client extension](https://marketplace.visualstudio.com/items?itemName=humao.rest-client). The Visual Studio 2022 `.http` editor recognizes `.rest` as an alternative file extension for the same file format.
@@ -166,9 +166,33 @@ Visual Studio displays warnings in the following situations:
166166

167167
A variable defined in an environment file can be the same as one defined in the `.http` file, or it can be different. If a variable is defined in both the `.http` file and the environment file, the value in the `.http` file overrides the value in the environment file.
168168

169+
## Shared variables
170+
171+
`$shared` is a special environment name for values that are the same for multiple environments. For example, consider the following environment file (`http-client.env.json`):
172+
173+
```json
174+
{
175+
"$shared": {
176+
"HostAddress": "https://localhost:7293"
177+
},
178+
"dev1": {
179+
"username": "dev1user"
180+
},
181+
"dev2": {
182+
"username": "dev2user"
183+
},
184+
"staging": {
185+
"username": "staginguser",
186+
"HostAddress": "https://staging.contoso.com"
187+
}
188+
}
189+
```
190+
191+
In the preceding example, the `$shared` environment defines the `HostAddress` variable with the value `localhost:7293`. The `HostAddress` variable with the value `localhost:7293` functions as a default for environments that don't define a `HostAddress`. When the `dev1` or `dev2` environment is defined, the value for `HostAddress` comes from the `$shared` environment because `dev1` and `dev2` don't define a `HostAddress` variable. When the `staging` environment is defined, the value for `HostAddress` is set to `https://staging.contoso.com`, overriding the `$shared` default.
192+
169193
## User-specific environment files
170194

171-
A user-specific value is any value that an individual developer wants to test with but doesnt want to share with the team. Since the `http-client.env.json` file is checked in to source control by default, it wouldn’t be appropriate to add user-specific values to this file. Instead, put them in a file named `http-client.env.json.user` located in the same folder as the `http-client.env.json` file. Files that end with `.user` should be excluded from source control by default when using Visual Studio source control features.
195+
A user-specific value is any value that a developer wants to test with but doesn't want to share with the team. The `http-client.env.json` file is checked in to source control by default, therefore, ***DO NOT*** add user-specific values to this file. Rather, add user-specific values in a file named `http-client.env.json.user`. The `http-client.env.json.user` file is located in the same folder as the `http-client.env.json` file. Files that end with `.user` are excluded from source control by default when using Visual Studio source control features.
172196

173197
When the `http-client.env.json` file is loaded, Visual Studio looks for a sibling `http-client.env.json.user` file. If a variable is defined in an environment in both the `http-client.env.json` file and the `http-client.env.json.user` file, the value in the `http-client.env.json.user` file wins.
174198

@@ -330,7 +354,7 @@ GET {{HostAddress}}{{Path}}
330354
X-UserName: {{$processEnv USERNAME}}
331355
```
332356

333-
If you try to use `$processEnv` to access an environment variable that doesnt exist, the `.http` file editor displays an error message.
357+
If you try to use `$processEnv` to access an environment variable that doesn't exist, the `.http` file editor displays an error message.
334358

335359
## `.env` files
336360

0 commit comments

Comments
 (0)