Skip to content

Commit

Permalink
Acrolinx 4/21 (dotnet#29141)
Browse files Browse the repository at this point in the history
  • Loading branch information
gewarren authored Apr 21, 2022
1 parent 7c6e1a9 commit 7913b88
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 28 deletions.
51 changes: 24 additions & 27 deletions docs/azure/sdk/resource-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ author: nickzhums

The next-generation of .NET SDK's management (or "management plane") libraries will help you create, provision, and manage Azure resources from within .NET applications. All Azure services have corresponding management libraries.

With the management libraries (names beginning with `Azure.ResourceManager`, e.g. `Azure.ResourceManager.Compute`), you can write configuration and deployment programs to perform the same tasks that you can through the Azure portal, Azure CLI, or other resource management tools.
With the management libraries (names beginning with `Azure.ResourceManager`, for example, `Azure.ResourceManager.Compute`), you can write configuration and deployment programs to perform the same tasks that you can through the Azure portal, Azure CLI, or other resource management tools.

Those packages follow the [new Azure SDK guidelines](https://azure.github.io/azure-sdk/general_introduction.html), which provide core capabilities that are shared amongst all Azure SDKs, including:

Expand Down Expand Up @@ -39,7 +39,7 @@ Install-Package Azure.ResourceManager.Compute -Version 1.0.0-beta.3
Install-Package Azure.ResourceManager.Network -Version 1.0.0-beta.3
```

# [dotnet cli](#tab/dotnetcli)
# [.NET CLI](#tab/dotnetcli)

```dotnetcli
dotnet add package Azure.ResourceManager
Expand Down Expand Up @@ -83,15 +83,14 @@ For more information about the `Azure.Identity.DefaultAzureCredential` class, se

### Understanding Azure Resource Hierarchy

To reduce both the number of clients needed to perform common tasks and the amount of redundant parameters that each of those clients take, we have introduced an object hierarchy in the SDK that mimics the object hierarchy in Azure. Each resource client in the SDK has methods to access the resource clients of its children that are already scoped to the proper subscription and resource group.
To reduce the number of clients needed to perform common tasks and the number of redundant parameters that each of those clients take, we've introduced an object hierarchy in the SDK that mimics the object hierarchy in Azure. Each resource client in the SDK has methods to access the resource clients of its children that are already scoped to the proper subscription and resource group.

To accomplish this, we're introducing 3 standard types for all resources in Azure:
To accomplish this, we're introducing three standard types for all resources in Azure:

#### **[Resource].cs**

This represents a full resource client object which contains a **Data** property exposing the details as a **[Resource]Data** type.
It also has access to all of the operations on that resource without needing to pass in scope parameters such as subscription ID or resource name. This makes it very convenient to directly execute operations on the result of list calls
since everything is returned as a full resource client now.
This type represents a full resource client object that contains a **Data** property exposing the details as a **[Resource]Data** type.
It also has access to all of the operations on that resource without needing to pass in scope parameters such as subscription ID or resource name. This makes it convenient to directly execute operations on the result of list calls, since everything is returned as a full resource client now.

```csharp
ArmClient armClient = new ArmClient(new DefaultAzureCredential());
Expand All @@ -108,11 +107,11 @@ await foreach (VirtualMachine vm in rg.GetVirtualMachines().GetAllAsync())

#### **[Resource]Data.cs**

This represents the model that makes up a given resource. Typically, this is the response data from a service call such as HTTP GET and provides details about the underlying resource. Previously, this was represented by a **Model** class.
This type represents the model that makes up a given resource. Typically, this is the response data from a service call such as HTTP GET and provides details about the underlying resource. Previously, this was represented by a **Model** class.

#### **[Resource]Collection.cs**

This represents the operations you can perform on a collection of resources belonging to a specific parent resource.
This type represents the operations you can perform on a collection of resources belonging to a specific parent resource.
This object provides most of the logical collection operations.

| Collection Behavior | Collection Method |
Expand All @@ -123,7 +122,7 @@ This object provides most of the logical collection operations.
| Contains | CheckIfExists(string name) |
| TryGet | GetIfExists(string name) |

For most things, the parent will be a **ResourceGroup**. However, each parent / child relationship is represented this way. For example, a **Subnet** is a child of a **VirtualNetwork** and a **ResourceGroup** is a child of a **Subscription**.
For most things, the parent will be a **ResourceGroup**. However, each parent-child relationship is represented this way. For example, a **Subnet** is a child of a **VirtualNetwork** and a **ResourceGroup** is a child of a **Subscription**.

### Putting it all together

Expand Down Expand Up @@ -157,7 +156,7 @@ await foreach(VirtualMachine vm in vmCollection.GetAllAsync())

#### Structured Resource Identifier

Resource IDs contain useful information about the resource itself, but they are plain strings that have to be parsed. Instead of implementing your own parsing logic, you can use a `ResourceIdentifier` object which will do the parsing for you: `new ResourceIdentifier("myid");`.
Resource IDs contain useful information about the resource itself, but they're plain strings that have to be parsed. Instead of implementing your own parsing logic, you can use a `ResourceIdentifier` object that will do the parsing for you: `new ResourceIdentifier("myid");`.

#### Example: Parsing an ID using a ResourceIdentifier object

Expand All @@ -170,7 +169,7 @@ Console.WriteLine($"Vnet: {id.Parent.Name}");
Console.WriteLine($"Subnet: {id.Name}");
```

However, keep in mind that some of those properties could be null. You can usually tell by the id string itself which type a resource ID is, but if you are unsure, check if the properties are null or use the Try methods to retrieve the values as it's shown below:
However, keep in mind that some of those properties could be null. You can usually tell by the ID string itself which type a resource ID is. But if you're unsure, check if the properties are null, or use the `Try` methods to retrieve the values, as shown in the following example.

#### Example: ResourceIdentifier TryGet methods

Expand All @@ -189,11 +188,11 @@ Console.WriteLine($"Vnet: {id.Parent.Name}");
Console.WriteLine($"Subnet: {id.Name}");
```

### Managing Existing Resources By Id
### Managing Existing Resources By ID

Performing operations on resources that already exist is a common use case when using the management client libraries. In this scenario you usually have the identifier of the resource you want to work on as a string. Although the new object hierarchy is great for provisioning and working within the scope of a given parent, it is not the most efficient when it comes to this specific scenario.
Performing operations on resources that already exist is a common use case when using the management client libraries. In this scenario, you usually have the identifier of the resource you want to work on as a string. Although the new object hierarchy is great for provisioning and working within the scope of a given parent, it is not the most efficient when it comes to this specific scenario.

Here is an example how you to access an `AvailabilitySet` object and manage it directly with its id:
Here's an example how you to access an `AvailabilitySet` object and manage it directly with its ID:

```csharp
using Azure.Identity;
Expand All @@ -218,7 +217,7 @@ ResourceGroup resourceGroup = await subscription.GetResourceGroups().GetAsync(id
AvailabilitySet availabilitySet = await resourceGroup.GetAvailabilitySets().GetAsync(id.Name);
```

This approach required a lot of code and 3 API calls to Azure. The same can be done with less code and without any API calls by using extension methods that we have provided on the client itself. These extension methods allow you to pass in a resource identifier and retrieve a scoped resource client. The object returned is a *[Resource]* mentioned above, since it has not reached out to Azure to retrieve the data yet the Data property will be null.
This approach required a lot of code and three API calls to Azure. The same can be done with less code and without any API calls by using extension methods that we've provided on the client itself. These extension methods allow you to pass in a resource identifier and retrieve a scoped resource client. The object returned is a [Resource](#resourcecs). Since it hasn't reached out to Azure to retrieve the data yet, the `Data` property will be null.

So, the previous example would end up looking like this:

Expand All @@ -238,11 +237,11 @@ Console.WriteLine(availabilitySet.Data.Name);

### Check if a [Resource] exists

If you are not sure if a resource you want to get exists, or you just want to check if it exists, you can use `GetIfExists()` or `CheckIfExists()` methods, which can be invoked from any [Resource]Collection class.
If you aren't sure if a resource you want to get exists, or you just want to check if it exists, you can use `GetIfExists()` or `CheckIfExists()` methods, which can be invoked from any [Resource]Collection class.

`GetIfExists()` and `GetIfExistsAsync()` return a `Response<T>` where T is null if the specified resource does not exist. On the other hand, `CheckIfExists()` and `CheckIfExistsAsync()` return `Response<bool>` where the bool will be false if the specified resource does not exist. Both of these methods still give you access to the underlying raw response.
`GetIfExists()` and `GetIfExistsAsync()` return a `Response<T>`, where `T` is null if the specified resource does not exist. On the other hand, `CheckIfExists()` and `CheckIfExistsAsync()` return `Response<bool>` where the Boolean value is false if the specified resource does not exist. Both of these methods still give you access to the underlying raw response.

In previous versions of packages, you would have to catch the `RequestFailedException` and inspect the status code for 404. With this new API, we hope that this can boost the developer productivity and optimize resource access. .
In previous versions of packages, you would have to catch the `RequestFailedException` and inspect the status code for 404. With this new API, we hope that this can boost the developer productivity and optimize resource access.

```csharp
ArmClient armClient = new ArmClient(new DefaultAzureCredential());
Expand All @@ -260,7 +259,7 @@ catch (RequestFailedException ex) when (ex.Status == 404)
}
```

Now with these convenience methods we can simply do the following.
Now with these convenience methods, we can simply do the following.

```csharp
ArmClient armClient = new ArmClient(new DefaultAzureCredential());
Expand All @@ -283,7 +282,7 @@ else
}
```

Another way to do this is by using `GetIfExists()` which will avoid the race condition mentioned above:
Another way to do this is by using `GetIfExists()`, which avoids the race condition mentioned previously:

```csharp
ArmClient armClient = new ArmClient(new DefaultAzureCredential());
Expand Down Expand Up @@ -361,10 +360,8 @@ For more detailed examples, take a look at [samples](https://github.com/Azure/az
## Troubleshooting

- If you have a bug to report or have a suggestion, file an issue via [GitHub issues](https://github.com/Azure/azure-sdk-for-net/issues) and make sure you add the "Preview" label to the issue.
- If you need help, check [previous
questions](https://stackoverflow.com/questions/tagged/azure+.net)
or ask new ones on StackOverflow using azure and .NET tags.
- If having trouble with authentication, go to [DefaultAzureCredential documentation](/dotnet/api/azure.identity.defaultazurecredential).
- If you need help, check [previous questions](https://stackoverflow.com/questions/tagged/azure+.net), or ask new ones on StackOverflow using Azure and .NET tags.
- If having trouble with authentication, see the [DefaultAzureCredential documentation](/dotnet/api/azure.identity.defaultazurecredential).

## Next steps

Expand All @@ -376,6 +373,6 @@ For more detailed examples, take a look at [samples](https://github.com/Azure/az

### Additional Documentation

If you are migrating from the old SDK to this preview, check out this [Migration guide](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/resourcemanager/Azure.ResourceManager/docs/MigrationGuide.md).
If you're migrating from the old SDK to this preview, check out this [Migration guide](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/resourcemanager/Azure.ResourceManager/docs/MigrationGuide.md).

For more information on Azure SDK, please refer to [this website](https://azure.github.io/azure-sdk/).
For more information on Azure SDK, see [Azure SDK Releases](https://azure.github.io/azure-sdk/).
2 changes: 1 addition & 1 deletion docs/fundamentals/code-analysis/quality-rules/ca1305.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ dev_langs:

## Cause

A method or constructor calls one or more members that have overloads that accept a <xref:System.IFormatProvider?displayProperty=fullName> parameter, and the method or constructor does not call the overload that takes the <xref:System.IFormatProvider> parameter.
A call is made to a method that has an overload that accepts a <xref:System.IFormatProvider?displayProperty=fullName> parameter, and that overload isn't called.

This rule ignores calls to .NET methods that are documented as ignoring the <xref:System.IFormatProvider> parameter. The rule also ignores the following methods:

Expand Down

0 comments on commit 7913b88

Please sign in to comment.