diff --git a/.github/dependabot.yml b/.github/dependabot.yml index baad00551..6d45c1303 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -223,6 +223,15 @@ updates: kiota-dependencies: patterns: - "*kiota*" +- package-ecosystem: nuget + directory: "/get-started/dotnet-dependency-injection" + schedule: + interval: daily + open-pull-requests-limit: 10 + groups: + kiota-dependencies: + patterns: + - "*kiota*" - package-ecosystem: nuget directory: "/get-started/quickstart/cli/src" schedule: diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a69ad8ede..c772b2994 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -18,6 +18,7 @@ jobs: working-directory: sample-api/api runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/get-started-dotnet.yml b/.github/workflows/get-started-dotnet.yml index f365b5037..eb3c7e20c 100644 --- a/.github/workflows/get-started-dotnet.yml +++ b/.github/workflows/get-started-dotnet.yml @@ -8,6 +8,7 @@ on: paths: - 'get-started/azure-auth/dotnet/**' - 'get-started/azure-auth/cli/**' + - 'get-started/dotnet-dependency-injection/**' - 'get-started/quickstart/dotnet/**' - 'get-started/quickstart/cli/**' pull_request: @@ -15,6 +16,7 @@ on: paths: - 'get-started/azure-auth/dotnet/**' - 'get-started/azure-auth/cli/**' + - 'get-started/dotnet-dependency-injection/**' - 'get-started/quickstart/dotnet/**' - 'get-started/quickstart/cli/**' @@ -22,6 +24,7 @@ jobs: build-azure-dotnet: runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 @@ -40,6 +43,7 @@ jobs: build-azure-cli: runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 @@ -55,9 +59,30 @@ jobs: run: dotnet build --no-restore working-directory: get-started/azure-auth/cli/src/ + build-dotnet-dependency-injection: + defaults: + run: + working-directory: get-started/dotnet-dependency-injection/ + + runs-on: ubuntu-latest + needs: [] + + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + + - name: Restore dependencies dotnet-dependency-injection + run: dotnet restore ./dotnet-dependency-injection.sln + - name: Build dotnet-dependency-injection + run: dotnet build ./dotnet-dependency-injection.sln --no-restore + build-quickstart-dotnet: runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 @@ -79,6 +104,7 @@ jobs: build-quickstart-cli: runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/get-started-java.yml b/.github/workflows/get-started-java.yml index 4241a074f..c7e9da3ac 100644 --- a/.github/workflows/get-started-java.yml +++ b/.github/workflows/get-started-java.yml @@ -24,6 +24,7 @@ jobs: working-directory: get-started/azure-auth/java/ runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 @@ -45,6 +46,7 @@ jobs: working-directory: get-started/quickstart/java/ runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/get-started-php.yml b/.github/workflows/get-started-php.yml index ba029eb9b..bb93ec9f5 100644 --- a/.github/workflows/get-started-php.yml +++ b/.github/workflows/get-started-php.yml @@ -22,6 +22,7 @@ jobs: working-directory: get-started/azure-auth/php/ runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 @@ -51,6 +52,7 @@ jobs: working-directory: get-started/quickstart/php/ runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/get-started-python.yml b/.github/workflows/get-started-python.yml index 635274386..499e008fe 100644 --- a/.github/workflows/get-started-python.yml +++ b/.github/workflows/get-started-python.yml @@ -22,6 +22,7 @@ jobs: working-directory: get-started/azure-auth/python/ runs-on: ubuntu-latest + needs: [] strategy: matrix: @@ -52,6 +53,7 @@ jobs: working-directory: get-started/quickstart/python/ runs-on: ubuntu-latest + needs: [] strategy: matrix: diff --git a/.github/workflows/get-started-ruby.yml b/.github/workflows/get-started-ruby.yml index 6ba95887d..f47836216 100644 --- a/.github/workflows/get-started-ruby.yml +++ b/.github/workflows/get-started-ruby.yml @@ -20,6 +20,7 @@ jobs: working-directory: get-started/azure-auth/ruby/ runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/get-started-typescript.yml b/.github/workflows/get-started-typescript.yml index c8620fb36..4b438fc06 100644 --- a/.github/workflows/get-started-typescript.yml +++ b/.github/workflows/get-started-typescript.yml @@ -22,6 +22,7 @@ jobs: working-directory: get-started/azure-auth/typescript/ runs-on: ubuntu-latest + needs: [] strategy: matrix: @@ -45,6 +46,7 @@ jobs: working-directory: get-started/quickstart/typescript/ runs-on: ubuntu-latest + needs: [] strategy: matrix: diff --git a/.github/workflows/get-started.go.yml b/.github/workflows/get-started.go.yml index 4ddf69446..29942d902 100644 --- a/.github/workflows/get-started.go.yml +++ b/.github/workflows/get-started.go.yml @@ -22,6 +22,7 @@ jobs: working-directory: get-started/azure-auth/go/ runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 @@ -41,6 +42,7 @@ jobs: working-directory: get-started/quickstart/go/ runs-on: ubuntu-latest + needs: [] steps: - uses: actions/checkout@v4 diff --git a/get-started/dotnet-dependency-injection/GitHub/GitHubClient.cs b/get-started/dotnet-dependency-injection/GitHub/GitHubClient.cs new file mode 100644 index 000000000..72535217c --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/GitHubClient.cs @@ -0,0 +1,46 @@ +// +using GitHub.ApiClient.Repos; +using Microsoft.Kiota.Abstractions.Extensions; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Serialization.Form; +using Microsoft.Kiota.Serialization.Json; +using Microsoft.Kiota.Serialization.Multipart; +using Microsoft.Kiota.Serialization.Text; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System; +namespace GitHub.ApiClient +{ + /// + /// The main entry point of the SDK, exposes the configuration and the fluent API. + /// + public class GitHubClient : BaseRequestBuilder + { + /// The repos property + public GitHub.ApiClient.Repos.ReposRequestBuilder Repos + { + get => new GitHub.ApiClient.Repos.ReposRequestBuilder(PathParameters, RequestAdapter); + } + /// + /// Instantiates a new and sets the default values. + /// + /// The request adapter to use to execute the requests. + public GitHubClient(IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}", new Dictionary()) + { + ApiClientBuilder.RegisterDefaultSerializer(); + ApiClientBuilder.RegisterDefaultSerializer(); + ApiClientBuilder.RegisterDefaultSerializer(); + ApiClientBuilder.RegisterDefaultSerializer(); + ApiClientBuilder.RegisterDefaultDeserializer(); + ApiClientBuilder.RegisterDefaultDeserializer(); + ApiClientBuilder.RegisterDefaultDeserializer(); + if (string.IsNullOrEmpty(RequestAdapter.BaseUrl)) + { + RequestAdapter.BaseUrl = "https://api.github.com"; + } + PathParameters.TryAdd("baseurl", RequestAdapter.BaseUrl); + } + } +} diff --git a/get-started/dotnet-dependency-injection/GitHub/GitHubClientFactory.cs b/get-started/dotnet-dependency-injection/GitHub/GitHubClientFactory.cs new file mode 100644 index 000000000..7c4853596 --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/GitHubClientFactory.cs @@ -0,0 +1,21 @@ +using GitHub.ApiClient; +using Microsoft.Kiota.Abstractions.Authentication; +using Microsoft.Kiota.Http.HttpClientLibrary; + +namespace GitHub; + +public class GitHubClientFactory +{ + private readonly IAuthenticationProvider _authenticationProvider; + private readonly HttpClient _httpClient; + + public GitHubClientFactory(HttpClient httpClient) + { + _authenticationProvider = new AnonymousAuthenticationProvider(); + _httpClient = httpClient; + } + + public GitHubClient GetClient() { + return new GitHubClient(new HttpClientRequestAdapter(_authenticationProvider, httpClient: _httpClient)); + } +} \ No newline at end of file diff --git a/get-started/dotnet-dependency-injection/GitHub/Models/Error.cs b/get-started/dotnet-dependency-injection/GitHub/Models/Error.cs new file mode 100644 index 000000000..b9a53f688 --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/Models/Error.cs @@ -0,0 +1,73 @@ +// +using Microsoft.Kiota.Abstractions.Serialization; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System; +namespace GitHub.ApiClient.Models +{ + #pragma warning disable CS1591 + public class Error : ApiException, IAdditionalDataHolder, IParsable + #pragma warning restore CS1591 + { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The error documentation URL +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? DocumentationUrl { get; set; } +#nullable restore +#else + public string DocumentationUrl { get; set; } +#endif + /// The error message +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? MessageEscaped { get; set; } +#nullable restore +#else + public string MessageEscaped { get; set; } +#endif + /// + /// Instantiates a new and sets the default values. + /// + public Error() + { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// A + /// The parse node to use to read the discriminator value and create the object + public static GitHub.ApiClient.Models.Error CreateFromDiscriminatorValue(IParseNode parseNode) + { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new GitHub.ApiClient.Models.Error(); + } + /// + /// The deserialization information for the current model + /// + /// A IDictionary<string, Action<IParseNode>> + public virtual IDictionary> GetFieldDeserializers() + { + return new Dictionary> + { + { "documentation_url", n => { DocumentationUrl = n.GetStringValue(); } }, + { "message", n => { MessageEscaped = n.GetStringValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public virtual void Serialize(ISerializationWriter writer) + { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("documentation_url", DocumentationUrl); + writer.WriteStringValue("message", MessageEscaped); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/get-started/dotnet-dependency-injection/GitHub/Models/Release.cs b/get-started/dotnet-dependency-injection/GitHub/Models/Release.cs new file mode 100644 index 000000000..0148ce12c --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/Models/Release.cs @@ -0,0 +1,94 @@ +// +using Microsoft.Kiota.Abstractions.Serialization; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System; +namespace GitHub.ApiClient.Models +{ + #pragma warning disable CS1591 + public class Release : IAdditionalDataHolder, IParsable + #pragma warning restore CS1591 + { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The release body +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Body { get; set; } +#nullable restore +#else + public string Body { get; set; } +#endif + /// The release creation date + public DateTimeOffset? CreatedAt { get; set; } + /// The release ID + public int? Id { get; set; } + /// The release name +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Name { get; set; } +#nullable restore +#else + public string Name { get; set; } +#endif + /// The release publication date + public DateTimeOffset? PublishedAt { get; set; } + /// The release tag name +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? TagName { get; set; } +#nullable restore +#else + public string TagName { get; set; } +#endif + /// + /// Instantiates a new and sets the default values. + /// + public Release() + { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// A + /// The parse node to use to read the discriminator value and create the object + public static GitHub.ApiClient.Models.Release CreateFromDiscriminatorValue(IParseNode parseNode) + { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new GitHub.ApiClient.Models.Release(); + } + /// + /// The deserialization information for the current model + /// + /// A IDictionary<string, Action<IParseNode>> + public virtual IDictionary> GetFieldDeserializers() + { + return new Dictionary> + { + { "body", n => { Body = n.GetStringValue(); } }, + { "created_at", n => { CreatedAt = n.GetDateTimeOffsetValue(); } }, + { "id", n => { Id = n.GetIntValue(); } }, + { "name", n => { Name = n.GetStringValue(); } }, + { "published_at", n => { PublishedAt = n.GetDateTimeOffsetValue(); } }, + { "tag_name", n => { TagName = n.GetStringValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public virtual void Serialize(ISerializationWriter writer) + { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("body", Body); + writer.WriteDateTimeOffsetValue("created_at", CreatedAt); + writer.WriteIntValue("id", Id); + writer.WriteStringValue("name", Name); + writer.WriteDateTimeOffsetValue("published_at", PublishedAt); + writer.WriteStringValue("tag_name", TagName); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/Releases/Item/WithReleaseNameItemRequestBuilder.cs b/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/Releases/Item/WithReleaseNameItemRequestBuilder.cs new file mode 100644 index 000000000..103963625 --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/Releases/Item/WithReleaseNameItemRequestBuilder.cs @@ -0,0 +1,93 @@ +// +using GitHub.ApiClient.Models; +using Microsoft.Kiota.Abstractions.Serialization; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Threading; +using System; +namespace GitHub.ApiClient.Repos.Item.Item.Releases.Item +{ + /// + /// Builds and executes requests for operations under \repos\{owner}\{repo}\releases\{releaseName} + /// + public class WithReleaseNameItemRequestBuilder : BaseRequestBuilder + { + /// + /// Instantiates a new and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public WithReleaseNameItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos/{owner}/{repo}/releases/{releaseName}", pathParameters) + { + } + /// + /// Instantiates a new and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public WithReleaseNameItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos/{owner}/{repo}/releases/{releaseName}", rawUrl) + { + } + /// + /// Get the latest release + /// + /// A + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. + /// When receiving a 404 status code +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) + { +#nullable restore +#else + public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) + { +#endif + var requestInfo = ToGetRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> + { + { "404", GitHub.ApiClient.Models.Error.CreateFromDiscriminatorValue }, + }; + return await RequestAdapter.SendAsync(requestInfo, GitHub.ApiClient.Models.Release.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false); + } + /// + /// Get the latest release + /// + /// A + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) + { +#nullable restore +#else + public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) + { +#endif + var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters); + requestInfo.Configure(requestConfiguration); + requestInfo.Headers.TryAdd("Accept", "application/json"); + return requestInfo; + } + /// + /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored. + /// + /// A + /// The raw URL to use for the request builder. + public GitHub.ApiClient.Repos.Item.Item.Releases.Item.WithReleaseNameItemRequestBuilder WithUrl(string rawUrl) + { + return new GitHub.ApiClient.Repos.Item.Item.Releases.Item.WithReleaseNameItemRequestBuilder(rawUrl, RequestAdapter); + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + [Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")] + public class WithReleaseNameItemRequestBuilderGetRequestConfiguration : RequestConfiguration + { + } + } +} diff --git a/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/Releases/ReleasesRequestBuilder.cs b/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/Releases/ReleasesRequestBuilder.cs new file mode 100644 index 000000000..fbdbc6962 --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/Releases/ReleasesRequestBuilder.cs @@ -0,0 +1,45 @@ +// +using GitHub.ApiClient.Repos.Item.Item.Releases.Item; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System; +namespace GitHub.ApiClient.Repos.Item.Item.Releases +{ + /// + /// Builds and executes requests for operations under \repos\{owner}\{repo}\releases + /// + public class ReleasesRequestBuilder : BaseRequestBuilder + { + /// Gets an item from the GitHub.ApiClient.repos.item.item.releases.item collection + /// The name of the release + /// A + public GitHub.ApiClient.Repos.Item.Item.Releases.Item.WithReleaseNameItemRequestBuilder this[string position] + { + get + { + var urlTplParams = new Dictionary(PathParameters); + urlTplParams.Add("releaseName", position); + return new GitHub.ApiClient.Repos.Item.Item.Releases.Item.WithReleaseNameItemRequestBuilder(urlTplParams, RequestAdapter); + } + } + /// + /// Instantiates a new and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public ReleasesRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos/{owner}/{repo}/releases", pathParameters) + { + } + /// + /// Instantiates a new and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public ReleasesRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos/{owner}/{repo}/releases", rawUrl) + { + } + } +} diff --git a/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/WithRepoItemRequestBuilder.cs b/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/WithRepoItemRequestBuilder.cs new file mode 100644 index 000000000..c115da3d1 --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/Repos/Item/Item/WithRepoItemRequestBuilder.cs @@ -0,0 +1,38 @@ +// +using GitHub.ApiClient.Repos.Item.Item.Releases; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System; +namespace GitHub.ApiClient.Repos.Item.Item +{ + /// + /// Builds and executes requests for operations under \repos\{owner}\{repo} + /// + public class WithRepoItemRequestBuilder : BaseRequestBuilder + { + /// The releases property + public GitHub.ApiClient.Repos.Item.Item.Releases.ReleasesRequestBuilder Releases + { + get => new GitHub.ApiClient.Repos.Item.Item.Releases.ReleasesRequestBuilder(PathParameters, RequestAdapter); + } + /// + /// Instantiates a new and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public WithRepoItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos/{owner}/{repo}", pathParameters) + { + } + /// + /// Instantiates a new and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public WithRepoItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos/{owner}/{repo}", rawUrl) + { + } + } +} diff --git a/get-started/dotnet-dependency-injection/GitHub/Repos/Item/WithOwnerItemRequestBuilder.cs b/get-started/dotnet-dependency-injection/GitHub/Repos/Item/WithOwnerItemRequestBuilder.cs new file mode 100644 index 000000000..a20614979 --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/Repos/Item/WithOwnerItemRequestBuilder.cs @@ -0,0 +1,45 @@ +// +using GitHub.ApiClient.Repos.Item.Item; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System; +namespace GitHub.ApiClient.Repos.Item +{ + /// + /// Builds and executes requests for operations under \repos\{owner} + /// + public class WithOwnerItemRequestBuilder : BaseRequestBuilder + { + /// Gets an item from the GitHub.ApiClient.repos.item.item collection + /// The repository name + /// A + public GitHub.ApiClient.Repos.Item.Item.WithRepoItemRequestBuilder this[string position] + { + get + { + var urlTplParams = new Dictionary(PathParameters); + urlTplParams.Add("repo", position); + return new GitHub.ApiClient.Repos.Item.Item.WithRepoItemRequestBuilder(urlTplParams, RequestAdapter); + } + } + /// + /// Instantiates a new and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public WithOwnerItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos/{owner}", pathParameters) + { + } + /// + /// Instantiates a new and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public WithOwnerItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos/{owner}", rawUrl) + { + } + } +} diff --git a/get-started/dotnet-dependency-injection/GitHub/Repos/ReposRequestBuilder.cs b/get-started/dotnet-dependency-injection/GitHub/Repos/ReposRequestBuilder.cs new file mode 100644 index 000000000..f8c79d456 --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/Repos/ReposRequestBuilder.cs @@ -0,0 +1,45 @@ +// +using GitHub.ApiClient.Repos.Item; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System; +namespace GitHub.ApiClient.Repos +{ + /// + /// Builds and executes requests for operations under \repos + /// + public class ReposRequestBuilder : BaseRequestBuilder + { + /// Gets an item from the GitHub.ApiClient.repos.item collection + /// The owner of the repository + /// A + public GitHub.ApiClient.Repos.Item.WithOwnerItemRequestBuilder this[string position] + { + get + { + var urlTplParams = new Dictionary(PathParameters); + urlTplParams.Add("owner", position); + return new GitHub.ApiClient.Repos.Item.WithOwnerItemRequestBuilder(urlTplParams, RequestAdapter); + } + } + /// + /// Instantiates a new and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public ReposRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos", pathParameters) + { + } + /// + /// Instantiates a new and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public ReposRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/repos", rawUrl) + { + } + } +} diff --git a/get-started/dotnet-dependency-injection/GitHub/kiota-lock.json b/get-started/dotnet-dependency-injection/GitHub/kiota-lock.json new file mode 100644 index 000000000..affcca9ef --- /dev/null +++ b/get-started/dotnet-dependency-injection/GitHub/kiota-lock.json @@ -0,0 +1,33 @@ +{ + "descriptionHash": "8BCE40C69B7A73D0A0E68DDEEB6ED8C6A75C8B95E78DFB088FE14B60B5FE54531017A6D2CFB266F72C190BCC695157F6588CCB0805F746E26391A14396E9B191", + "descriptionLocation": "../github-releases.yml", + "lockFileVersion": "1.0.0", + "kiotaVersion": "1.15.0", + "clientClassName": "GitHubClient", + "clientNamespaceName": "GitHub.ApiClient", + "language": "CSharp", + "usesBackingStore": false, + "excludeBackwardCompatible": false, + "includeAdditionalData": true, + "disableSSLValidation": false, + "serializers": [ + "Microsoft.Kiota.Serialization.Json.JsonSerializationWriterFactory", + "Microsoft.Kiota.Serialization.Text.TextSerializationWriterFactory", + "Microsoft.Kiota.Serialization.Form.FormSerializationWriterFactory", + "Microsoft.Kiota.Serialization.Multipart.MultipartSerializationWriterFactory" + ], + "deserializers": [ + "Microsoft.Kiota.Serialization.Json.JsonParseNodeFactory", + "Microsoft.Kiota.Serialization.Text.TextParseNodeFactory", + "Microsoft.Kiota.Serialization.Form.FormParseNodeFactory" + ], + "structuredMimeTypes": [ + "application/json", + "text/plain;q=0.9", + "application/x-www-form-urlencoded;q=0.2", + "multipart/form-data;q=0.1" + ], + "includePatterns": [], + "excludePatterns": [], + "disabledValidationRules": [] +} \ No newline at end of file diff --git a/get-started/dotnet-dependency-injection/KiotaServiceCollectionExtensions.cs b/get-started/dotnet-dependency-injection/KiotaServiceCollectionExtensions.cs new file mode 100644 index 000000000..8b40dcc6e --- /dev/null +++ b/get-started/dotnet-dependency-injection/KiotaServiceCollectionExtensions.cs @@ -0,0 +1,48 @@ +using Microsoft.Kiota.Http.HttpClientLibrary; + +/// +/// Service collection extensions for Kiota handlers. +/// +public static class KiotaServiceCollectionExtensions +{ + /// + /// Adds the Kiota handlers to the service collection. + /// + /// to add the services to + /// as per convention + /// The handlers are added to the http client by the call, which requires them to be pre-registered in DI + public static IServiceCollection AddKiotaHandlers(this IServiceCollection services) + { + // Dynamically load the Kiota handlers from the Client Factory + var kiotaHandlers = KiotaClientFactory.GetDefaultHandlerTypes(); + // And register them in the DI container + foreach(var handler in kiotaHandlers) + { + services.AddTransient(handler); + } + + return services; + } + + /// + /// Adds the Kiota handlers to the http client builder. + /// + /// + /// + /// + /// Requires the handlers to be registered in DI by . + /// The order in which the handlers are added is important, as it defines the order in which they will be executed. + /// + public static IHttpClientBuilder AttachKiotaHandlers(this IHttpClientBuilder builder) + { + // Dynamically load the Kiota handlers from the Client Factory + var kiotaHandlers = KiotaClientFactory.GetDefaultHandlerTypes(); + // And attach them to the http client builder + foreach(var handler in kiotaHandlers) + { + builder.AddHttpMessageHandler((sp) => (DelegatingHandler)sp.GetRequiredService(handler)); + } + + return builder; + } +} \ No newline at end of file diff --git a/get-started/dotnet-dependency-injection/KiotaWithDependencyInjection.csproj b/get-started/dotnet-dependency-injection/KiotaWithDependencyInjection.csproj new file mode 100644 index 000000000..8bcf0d66e --- /dev/null +++ b/get-started/dotnet-dependency-injection/KiotaWithDependencyInjection.csproj @@ -0,0 +1,21 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + diff --git a/get-started/dotnet-dependency-injection/KiotaWithDependencyInjection.http b/get-started/dotnet-dependency-injection/KiotaWithDependencyInjection.http new file mode 100644 index 000000000..f6ac4322a --- /dev/null +++ b/get-started/dotnet-dependency-injection/KiotaWithDependencyInjection.http @@ -0,0 +1,6 @@ +@KiotaWithDependencyInjection_HostAddress = http://localhost:5205 + +GET {{KiotaWithDependencyInjection_HostAddress}}/dotnet/releases +Accept: application/json + +### diff --git a/get-started/dotnet-dependency-injection/Program.cs b/get-started/dotnet-dependency-injection/Program.cs new file mode 100644 index 000000000..579748c4a --- /dev/null +++ b/get-started/dotnet-dependency-injection/Program.cs @@ -0,0 +1,73 @@ +using GitHub; +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +// ----------- Add this part to register the generated client ----------- +// Add Kiota handlers to the dependency injection container +builder.Services.AddKiotaHandlers(); + +// Register the factory for the GitHub client +builder.Services.AddHttpClient((sp, client) => { + // Set the base address and accept header + // or other settings on the http client + client.BaseAddress = new Uri("https://api.github.com"); + client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json"); +}).AttachKiotaHandlers(); // Attach the Kiota handlers to the http client, this is to enable all the Kiota features. + +// Register the GitHub client +builder.Services.AddTransient(sp => sp.GetRequiredService().GetClient()); +// ----------- Add this part to register the generated client end ------- + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +var summaries = new[] +{ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" +}; + +app.MapGet("/weatherforecast", () => +{ + var forecast = Enumerable.Range(1, 5).Select(index => + new WeatherForecast + ( + DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + Random.Shared.Next(-20, 55), + summaries[Random.Shared.Next(summaries.Length)] + )) + .ToArray(); + return forecast; +}) +.WithName("GetWeatherForecast") +.WithOpenApi(); + +// ----------- Add this part to create a new endpoint that uses the generated client ----------- + +app.MapGet("/dotnet/releases", async (GitHub.ApiClient.GitHubClient client, CancellationToken cancellationToken) => +{ + var releases = await client.Repos["dotnet"]["runtime"].Releases["latest"].GetAsync(cancellationToken: cancellationToken); + return releases; +}) +.WithName("GetDotnetReleases") +.WithOpenApi(); + +// ----------- Add this part to create a new endpoint that uses the generated client end ----------- + +app.Run(); + +record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) +{ + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); +} diff --git a/get-started/dotnet-dependency-injection/Properties/launchSettings.json b/get-started/dotnet-dependency-injection/Properties/launchSettings.json new file mode 100644 index 000000000..574ff23a8 --- /dev/null +++ b/get-started/dotnet-dependency-injection/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:7358", + "sslPort": 44328 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5205", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7141;http://localhost:5205", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/get-started/dotnet-dependency-injection/README.md b/get-started/dotnet-dependency-injection/README.md new file mode 100644 index 000000000..ca5642145 --- /dev/null +++ b/get-started/dotnet-dependency-injection/README.md @@ -0,0 +1,27 @@ +# Kiota with .NET Dependency Injection + +This project is the finished product of tutorial [Kiota with .NET Dependency Injection](https://learn.microsoft.com/openapi/kiota/tutorials/dotnet-dependency-injection?tabs=portal). + +## Parts of the sample + +- `KiotaServiceCollectionExtensions.cs` - Extension methods to add Kiota services to the service collection. +- `GitHub/GitHubClientFactory.cs` - Factory class to create GitHub clients. +- `Program.cs` - Registring the kiota client with all its handlers. + +## Generate the client + +To generate the client, run the following command: + +```bash +kiota generate -l csharp -d github-releases.yml -c GitHubClient -n GitHub.ApiClient -o ./GitHub +``` + +## Run the sample + +To run the sample, run the following command: + +```bash +dotnet run +``` + +And navigate to `https://localhost:{port}/swagger` in your browser. diff --git a/get-started/dotnet-dependency-injection/appsettings.Development.json b/get-started/dotnet-dependency-injection/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/get-started/dotnet-dependency-injection/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/get-started/dotnet-dependency-injection/appsettings.json b/get-started/dotnet-dependency-injection/appsettings.json new file mode 100644 index 000000000..10f68b8c8 --- /dev/null +++ b/get-started/dotnet-dependency-injection/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/get-started/dotnet-dependency-injection/dotnet-dependency-injection.sln b/get-started/dotnet-dependency-injection/dotnet-dependency-injection.sln new file mode 100644 index 000000000..51ffcc644 --- /dev/null +++ b/get-started/dotnet-dependency-injection/dotnet-dependency-injection.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KiotaWithDependencyInjection", "KiotaWithDependencyInjection.csproj", "{6DB8CD75-0EFC-48AA-89C5-FDA9F2FC14EC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6DB8CD75-0EFC-48AA-89C5-FDA9F2FC14EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6DB8CD75-0EFC-48AA-89C5-FDA9F2FC14EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6DB8CD75-0EFC-48AA-89C5-FDA9F2FC14EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6DB8CD75-0EFC-48AA-89C5-FDA9F2FC14EC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/get-started/dotnet-dependency-injection/github-releases.yml b/get-started/dotnet-dependency-injection/github-releases.yml new file mode 100644 index 000000000..17509128a --- /dev/null +++ b/get-started/dotnet-dependency-injection/github-releases.yml @@ -0,0 +1,82 @@ +openapi: 3.0.3 +info: + title: GitHub Release API + version: 1.0.0 +servers: + - url: https://api.github.com + description: GitHub API + variables: + version: + default: '2022-11-28' + description: GitHub API version +paths: + /repos/{owner}/{repo}/releases/{releaseName}: + get: + summary: Get the latest release + parameters: + - name: owner + in: path + required: true + description: The owner of the repository + schema: + type: string + - name: repo + in: path + required: true + description: The repository name + schema: + type: string + - name: releaseName + in: path + required: true + description: The name of the release + schema: + type: string + responses: + 200: + description: Success! + content: + application/json: + schema: + $ref: "#/components/schemas/github.release" + 404: + description: Not found + content: + application/json: + schema: + $ref: "#/components/schemas/github.error" + +components: + schemas: + github.release: + type: object + properties: + id: + type: integer + description: The release ID + tag_name: + type: string + description: The release tag name + name: + type: string + description: The release name + body: + type: string + description: The release body + created_at: + type: string + format: date-time + description: The release creation date + published_at: + type: string + format: date-time + description: The release publication date + github.error: + type: object + properties: + message: + type: string + description: The error message + documentation_url: + type: string + description: The error documentation URL \ No newline at end of file