8000 Add argument null validation to Aspire.Hosting by JamesNK · Pull Request #6278 · dotnet/aspire · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add argument null validation to Aspire.Hosting #6278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 29, 2024

Conversation

JamesNK
Copy link
Member
@JamesNK JamesNK commented Oct 14, 2024

Description

Fixes #2649

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?
    • Yes
      • Link to aspire-docs issue:
    • No
Microsoft Reviewers: Open in CodeFlow

@JamesNK JamesNK added the area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication label Oct 14, 2024
@JamesNK
Copy link
Member Author
JamesNK commented Oct 14, 2024

There is a test failure from

Which is wrong: WithImageRegistry not allowing null or WithDockerfile calling WithImageRegistry with a null value?

@mitchdenny
Copy link
Member

WithImageRegistry(null!) is valid because sometimes you don't have an image registry.

@JamesNK
Copy link
Member Author
JamesNK commented Oct 14, 2024

Ok. So, that means WithImageRegistry should allow a null argument?

On the surface that seems strange to me. Why would someone call it with null rather than just not call it? If it is changed to accept null, what should the doc comment say if you pass null to it?

I'm not fimilar with this API. I'd like some actionable feedback.

@@ -185,7 +185,7 @@ public async Task EnsureContainerWithVolumesEmitsVolumes()
builder.AddContainer("containerwithvolumes", "image/name")
.WithVolume("myvolume", "/mount/here")
.WithVolume("myreadonlyvolume", "/mount/there", isReadOnly: true)
.WithVolume(null! /* anonymous volume */, "/mount/everywhere");
.WithVolume("/mount/everywhere");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update the API so allow for name to be null? If you follow the call path, it gets passed into source below:

    /// <param name="source">The source path if a bind mount or name if a volume. Can be <c>null</c> if the mount is an anonymous volume.</param>
    /// <param name="target">The target path of the mount.</param>
    /// <param name="type">The type of the mount.</param>
    /// <param name="isReadOnly">A value indicating whether the mount is read-only.</param>
    public ContainerMountAnnotation(string? source, string target, ContainerMountType type, bool isReadOnly)

Also, these WithVolume APIs don't meet .NET Design Guidelines:

public static IResourceBuilder<T> WithVolume<T>(this IResourceBuilder<T> builder, string name, string target, bool isReadOnly = false) where T : ContainerResource

public static IResourceBuilder<T> WithVolume<T>(this IResourceBuilder<T> builder, string target) where T : ContainerResource

https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/member-overloading

❌ AVOID being inconsistent in the ordering of parameters in overloaded members. Parameters with the same name should appear in the same position in all overloads.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WithVolume without name has already shipped.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update the API so allow for name to be null?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why when there is an overload without a name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it makes it easier to write code like this:

string? volumeName = GetVolumeName(); // may return null

builder.AddContainer("containerwithvolumes", "image/name")
    .WithVolume(volumeName, "/mount/everywhere");

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See also: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/member-overloading

✔️ DO allow null to be passed for optional arguments.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

@@ -168,6 +178,10 @@ public static IResourceBuilder<ProjectResource> AddProject(this IDistributedAppl
/// </example>
public static IResourceBuilder<ProjectResource> AddProject(this IDistributedApplicationBuilder builder, [ResourceName] string name, string projectPath, string? launchProfileName)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several of these should probably throw if empty, as in:

Suggested change
ArgumentNullException.ThrowIfNull(name);
ArgumentException.ThrowIfNullOrEmpty(name);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They could. However, there is more validations of names that ensures they're not empty, Technically this null check isn't nesseccary, but I like the consistency of checking all references for null in public API calls.

@JamesNK
Copy link
Member Author
JamesNK commented Oct 21, 2024

Ok. So, that means WithImageRegistry should allow a null argument?

On the surface that seems strange to me. Why would someone call it with null rather than just not call it? If it is changed to accept null, what should the doc comment say if you pass null to it?

I'm not fimilar with this API. I'd like some actionable feedback.

@mitchdenny What is the answer here?

@mitchdenny
Copy link
Member

Given the API has shipped allow null to be passed to WithImageRegistry.

@JamesNK
Copy link
Member Author
JamesNK commented Oct 23, 2024

I don't think it being shipped should stop us. It shipped without a nullable argument.

What is the best behavior?

Copy link
Member
@mitchdenny mitchdenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I think its good to tighten this up.

@mitchdenny
Copy link
Member

/azp run

@mitchdenny
Copy link
Member

Kicking new build to see what the test failures were.

Copy link
Azure Pipelines successfully started running 1 pipeline(s).

@JamesNK JamesNK force-pushed the jamesnk/hosting-argument-validation branch from 95d7184 to 233f1fd Compare October 29, 2024 06:42
@JamesNK JamesNK merged commit f8338c5 into main Oct 29, 2024
9 checks passed
@JamesNK JamesNK deleted the jamesnk/hosting-argument-validation branch October 29, 2024 13:08
@mitchdenny mitchdenny added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Nov 1, 2024
@mitchdenny
Copy link
Member

Flagging this as a breaking change as we did technically change the signature, although most folks won't notice if they just recompile.

@github-actions github-actions bot locked and limited conversation to collaborators Dec 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
< 7BB2 /div>
Labels
area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Review use of ArgumentException/ArgumentNullException in all public APIs
4 participants
0