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: aspnetcore/blazor/javascript-interoperability/static-server-rendering.md
+7-3Lines changed: 7 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -97,12 +97,14 @@ export function onDispose() {
97
97
}
98
98
```
99
99
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).
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
+
106
108
In the RCL, add the following `PageScript` component.
107
109
108
110
`PageScript.razor`:
@@ -129,6 +131,8 @@ To reuse the same module among pages, but have the `onLoad` and `onDispose` call
129
131
130
132
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>.
131
133
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.
133
137
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.
Copy file name to clipboardExpand all lines: aspnetcore/fundamentals/dependency-injection.md
+16-37Lines changed: 16 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,15 +17,15 @@ By [Kirk Larkin](https://twitter.com/serpent5), [Steve Smith](https://ardalis.co
17
17
18
18
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.
19
19
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>.
21
21
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>.
23
23
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).
25
25
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>.
27
27
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).
29
29
30
30
[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))
31
31
@@ -59,7 +59,7 @@ This interface is implemented by a concrete type, `MyDependency`:
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.
@@ -89,13 +89,13 @@ The container resolves `ILogger<TCategoryName>` by taking advantage of [(generic
89
89
In dependency injection terminology, a service:
90
90
91
91
* 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.
93
93
94
94
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:
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.
99
99
100
100
## Register groups of services with extension methods
101
101
@@ -124,9 +124,9 @@ See [Service registration methods](/dotnet/core/extensions/dependency-injection#
124
124
125
125
It's common to use multiple implementations when [mocking types for testing](xref:test/integration-tests#inject-mock-services).
126
126
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.
128
128
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}>`.
*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:
The following code shows how to resolve a scoped service for a limited duration when the app starts:
210
210
@@ -233,7 +233,7 @@ When designing services for dependency injection:
233
233
* Avoid direct instantiation of dependent classes within services. Direct instantiation couples the code to a particular implementation.
234
234
* Make services small, well-factored, and easily tested.
235
235
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.
237
237
238
238
### Disposal of services
239
239
@@ -309,32 +309,11 @@ See [Recommendations](/dotnet/core/extensions/dependency-injection-guidelines#re
309
309
* 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.
310
310
* Avoid static access to `HttpContext` (for example, [IHttpContextAccessor.HttpContext](xref:Microsoft.AspNetCore.Http.IHttpContextAccessor.HttpContext)).
311
311
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:
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:
* 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.
334
313
335
314
## Recommended patterns for multi-tenancy in DI
336
315
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).
338
317
339
318
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.
340
319
@@ -363,10 +342,10 @@ The following table lists a small sample of these framework-registered services:
Copy file name to clipboardExpand all lines: aspnetcore/test/http-files.md
+27-3Lines changed: 27 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ This article contains documentation for:
21
21
*[The `.http` file syntax](#http-file-syntax).
22
22
*[How to create an `.http` file](#create-an-http-file).
23
23
*[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).
25
25
*[How to create requests in `.http` files by using the Visual Studio 2022 **Endpoints Explorer**](#use-endpoints-explorer).
26
26
27
27
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:
166
166
167
167
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.
168
168
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
+
169
193
## User-specific environment files
170
194
171
-
A user-specific value is any value that an individual developer wants to test with but doesn’t 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.
172
196
173
197
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.
174
198
@@ -330,7 +354,7 @@ GET {{HostAddress}}{{Path}}
330
354
X-UserName: {{$processEnv USERNAME}}
331
355
```
332
356
333
-
If you try to use `$processEnv` to access an environment variable that doesn’t 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.
0 commit comments