Skip to content

Commit

Permalink
chore: kiota support
Browse files Browse the repository at this point in the history
  • Loading branch information
Kunal22shah committed Aug 20, 2024
1 parent f677bd2 commit 44ca5be
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 65 deletions.
1 change: 1 addition & 0 deletions Uno.Extensions-packageonly.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"src\\Uno.Extensions.Core\\Uno.Extensions.Core.csproj",
"src\\Uno.Extensions.Hosting.UI\\Uno.Extensions.Hosting.WinUI.csproj",
"src\\Uno.Extensions.Hosting\\Uno.Extensions.Hosting.csproj",
"src\\Uno.Extensions.Http.Kiota\\Uno.Extensions.Http.Kiota.csproj",
"src\\Uno.Extensions.Http.Refit\\Uno.Extensions.Http.Refit.csproj",
"src\\Uno.Extensions.Http.UI\\Uno.Extensions.Http.WinUI.csproj",
"src\\Uno.Extensions.Http\\Uno.Extensions.Http.csproj",
Expand Down
19 changes: 19 additions & 0 deletions Uno.Extensions.sln
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Extensions.RuntimeTests
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Extensions.RuntimeTests.Core", "src\Uno.Extensions.RuntimeTests\Uno.Extensions.RuntimeTests.Core\Uno.Extensions.RuntimeTests.Core.csproj", "{869C9E5B-0F85-4316-BC4B-CB6CBFCC02A3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Extensions.Http.Kiota", "src\Uno.Extensions.Http.Kiota\Uno.Extensions.Http.Kiota.csproj", "{C9827C80-312B-4E81-B539-2D305D893A6C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -732,6 +734,22 @@ Global
{869C9E5B-0F85-4316-BC4B-CB6CBFCC02A3}.Release|x64.Build.0 = Release|Any CPU
{869C9E5B-0F85-4316-BC4B-CB6CBFCC02A3}.Release|x86.ActiveCfg = Release|Any CPU
{869C9E5B-0F85-4316-BC4B-CB6CBFCC02A3}.Release|x86.Build.0 = Release|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Debug|arm64.ActiveCfg = Debug|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Debug|arm64.Build.0 = Debug|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Debug|x64.ActiveCfg = Debug|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Debug|x64.Build.0 = Debug|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Debug|x86.ActiveCfg = Debug|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Debug|x86.Build.0 = Debug|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Release|Any CPU.Build.0 = Release|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Release|arm64.ActiveCfg = Release|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Release|arm64.Build.0 = Release|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Release|x64.ActiveCfg = Release|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Release|x64.Build.0 = Release|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Release|x86.ActiveCfg = Release|Any CPU
{C9827C80-312B-4E81-B539-2D305D893A6C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -778,6 +796,7 @@ Global
{B72698C5-6706-4275-8A2B-A1D39FE9B13E} = {2197ADCE-59C4-465A-B380-0B06BF68BBBC}
{A42362AF-8A61-4BBA-AA8A-E43323D5A063} = {FB399485-A0B1-4416-A494-E19AC7F5A665}
{869C9E5B-0F85-4316-BC4B-CB6CBFCC02A3} = {FB399485-A0B1-4416-A494-E19AC7F5A665}
{C9827C80-312B-4E81-B539-2D305D893A6C} = {45179294-70DC-47E8-AD22-1296F897B594}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6E7B035D-9A64-4D95-89AA-9D4653F17C42}
Expand Down
131 changes: 66 additions & 65 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,76 +1,77 @@
<Project ToolsVersion="15.0">
<!--
<!--
Due to an issue with duplicate references on output for Windows we need to ensure that when building for MAUI Embedding that we use the same version
of both WinUI and Uno.WinUI across Extensions and the MauiEmbedding Sample Project.
-->
<!-- <PropertyGroup Condition="$(SolutionName) != 'MauiEmbedding'">
<!-- <PropertyGroup Condition="$(SolutionName) != 'MauiEmbedding'">
<UnoVersion Condition="$(UnoVersion) == '' AND !$(MSBuildProjectName.Contains('Maui'))">5.2.175</UnoVersion>
<UnoVersion Condition="$(UnoVersion) == '' AND $(MSBuildProjectName.Contains('Maui'))">5.2.175</UnoVersion>
<WinAppSdkVersion Condition="$(WinAppSdkVersion) == ''">1.5.240311000</WinAppSdkVersion>
</PropertyGroup> -->

<!--<PropertyGroup>
<!--<PropertyGroup>
<UnoToolkitVersion>5.0.15</UnoToolkitVersion>
</PropertyGroup>-->

<ItemGroup>
<PackageVersion Include="CommunityToolkit.Mvvm" Version="7.0.1" />
<PackageVersion Include="DotNet.ReproducibleBuilds" Version="1.1.1" />
<PackageVersion Include="FluentAssertions" Version="6.7.0" />
<PackageVersion Include="IdentityModel.OidcClient" Version="5.0.0" />
<PackageVersion Include="MSTest.TestAdapter" Version="2.2.9" />
<PackageVersion Include="MSTest.TestFramework" Version="2.2.9" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.61.3" />
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.61.3" />
<PackageVersion Include="Microsoft.Maui.Controls" Version="8.0.3" />
<PackageVersion Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.3" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageVersion Include="Microsoft.Net.Compilers.Toolset" Version="4.2.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<PackageVersion Include="Microsoft.UI.Xaml" Version="2.7.1" />
<PackageVersion Include="Microsoft.Graphics.Win2D" Version="1.2.0" />
<PackageVersion Include="Moq" Version="4.17.2" />
<PackageVersion Include="Refit" Version="6.3.2" />
<PackageVersion Include="Refit.HttpClientFactory" Version="6.3.2" />
<PackageVersion Include="Serilog.Extensions.Hosting" Version="4.2.0" />
<PackageVersion Include="Serilog.Settings.Configuration" Version="3.3.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageVersion Include="Serilog.Sinks.Debug" Version="2.0.0" />
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageVersion Include="Serilog.Sinks.Xamarin" Version="1.0.0" />
<PackageVersion Include="System.Collections.Immutable" Version="1.3.1" /> <!--Lower version breaks build of reactive.<UI|WinUI>-->
<PackageVersion Include="System.Linq.Async" Version="4.0.0" />
<PackageVersion Include="System.Net.Http.WinHttpHandler" Version="6.0.1" />
<PackageVersion Include="System.Text.Json" Version="8.0.4" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageVersion Include="Uno.Core" Version="4.1.1" />
<PackageVersion Include="Uno.Core.Extensions" Version="4.1.1" />
<PackageVersion Include="Uno.Core.Extensions.Collections" Version="4.1.1" />
<PackageVersion Include="Uno.Core.Extensions.Logging.Singleton" Version="4.1.1" />
<PackageVersion Include="Uno.Extensions.Logging.OSLog" Version="1.7.0" />
<PackageVersion Include="Uno.Extensions.Logging.WebAssembly.Console" Version="1.7.0" />
<PackageVersion Include="Uno.Extensions.Markup.Generators" Version="5.3.12" />
<PackageVersion Include="Uno.Extensions.Markup.WinUI" Version="5.3.12" />
<PackageVersion Include="Uno.Roslyn" Version="1.3.0-dev.12" />
<PackageVersion Include="Uno.Toolkit" Version="6.1.7" />
<PackageVersion Include="Uno.UI.Adapter.Microsoft.Extensions.Logging" Version="$(UnoVersion)"/>

<PackageVersion Include="Uno.UI.RuntimeTests.Engine" Version="0.37.0-dev.126" />
<PackageVersion Include="Uno.WinUI" Version="$(UnoVersion)" />
<PackageVersion Include="Uno.WinUI.Markup" Version="5.3.12" />
<PackageVersion Include="Uno.WinUI.MSAL" Version="$(UnoVersion)" />
<PackageVersion Include="coverlet.collector" Version="3.1.2" />
<PackageVersion Include="xunit" Version="2.4.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.1" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageVersion Include="FluentValidation" Version="11.4.0" />
</ItemGroup>
<ItemGroup>
<PackageVersion Include="CommunityToolkit.Mvvm" Version="7.0.1" />
<PackageVersion Include="DotNet.ReproducibleBuilds" Version="1.1.1" />
<PackageVersion Include="FluentAssertions" Version="6.7.0" />
<PackageVersion Include="IdentityModel.OidcClient" Version="5.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Kiota.Abstractions" Version="1.11.0" />
<PackageVersion Include="Microsoft.Kiota.Http.HttpClientLibrary" Version="1.11.0" />
<PackageVersion Include="Microsoft.Kiota.Serialization.Json" Version="1.11.0" />
<PackageVersion Include="MSTest.TestAdapter" Version="2.2.9" />
<PackageVersion Include="MSTest.TestFramework" Version="2.2.9" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.61.3" />
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.61.3" />
<PackageVersion Include="Microsoft.Maui.Controls" Version="8.0.3" />
<PackageVersion Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.3" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageVersion Include="Microsoft.Net.Compilers.Toolset" Version="4.2.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<PackageVersion Include="Microsoft.UI.Xaml" Version="2.7.1" />
<PackageVersion Include="Microsoft.Graphics.Win2D" Version="1.2.0" />
<PackageVersion Include="Moq" Version="4.17.2" />
<PackageVersion Include="Refit" Version="6.3.2" />
<PackageVersion Include="Refit.HttpClientFactory" Version="6.3.2" />
<PackageVersion Include="Serilog.Extensions.Hosting" Version="4.2.0" />
<PackageVersion Include="Serilog.Settings.Configuration" Version="3.3.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageVersion Include="Serilog.Sinks.Debug" Version="2.0.0" />
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageVersion Include="Serilog.Sinks.Xamarin" Version="1.0.0" />
<PackageVersion Include="System.Collections.Immutable" Version="1.3.1" /> <!--Lower version breaks build of reactive.<UI|WinUI>-->
<PackageVersion Include="System.Linq.Async" Version="4.0.0" />
<PackageVersion Include="System.Net.Http.WinHttpHandler" Version="6.0.1" />
<PackageVersion Include="System.Text.Json" Version="8.0.4" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageVersion Include="Uno.Core" Version="4.1.1" />
<PackageVersion Include="Uno.Core.Extensions" Version="4.1.1" />
<PackageVersion Include="Uno.Core.Extensions.Collections" Version="4.1.1" />
<PackageVersion Include="Uno.Core.Extensions.Logging.Singleton" Version="4.1.1" />
<PackageVersion Include="Uno.Extensions.Logging.OSLog" Version="1.7.0" />
<PackageVersion Include="Uno.Extensions.Logging.WebAssembly.Console" Version="1.7.0" />
<PackageVersion Include="Uno.Extensions.Markup.Generators" Version="5.3.12" />
<PackageVersion Include="Uno.Extensions.Markup.WinUI" Version="5.3.12" />
<PackageVersion Include="Uno.Roslyn" Version="1.3.0-dev.12" />
<PackageVersion Include="Uno.Toolkit" Version="6.1.7" />
<PackageVersion Include="Uno.UI.Adapter.Microsoft.Extensions.Logging" Version="$(UnoVersion)" />
<PackageVersion Include="Uno.UI.RuntimeTests.Engine" Version="0.37.0-dev.126" />
<PackageVersion Include="Uno.WinUI" Version="$(UnoVersion)" />
<PackageVersion Include="Uno.WinUI.Markup" Version="5.3.12" />
<PackageVersion Include="Uno.WinUI.MSAL" Version="$(UnoVersion)" />
<PackageVersion Include="coverlet.collector" Version="3.1.2" />
<PackageVersion Include="xunit" Version="2.4.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.1" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageVersion Include="FluentValidation" Version="11.4.0" />
</ItemGroup>
</Project>
132 changes: 132 additions & 0 deletions src/Uno.Extensions.Http.Kiota/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Kiota.Abstractions;
using Microsoft.Kiota.Abstractions.Authentication;
using Microsoft.Kiota.Http.HttpClientLibrary;
using Uno.Extensions.Authentication;

namespace Uno.Extensions.Http.Kiota;

/// <summary>
/// Provides extension methods for registering Kiota clients within the <see cref="IServiceCollection"/>.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Registers a Kiota client with the specified <paramref name="name"/> and endpoint options.
/// </summary>
/// <typeparam name="TClient">The Kiota client type to register.</typeparam>
/// <param name="services">The <see cref="IServiceCollection"/> to register the client with.</param>
/// <param name="context">The <see cref="HostBuilderContext"/> providing the hosting context.</param>
/// <param name="options">[Optional] The endpoint options for the client (loaded from appsettings if not specified).</param>
/// <param name="name">[Optional] The name for locating endpoint information in appsettings.</param>
/// <param name="configure">[Optional] A callback for configuring the endpoint.</param>
/// <returns>The updated <see cref="IServiceCollection"/> with the registered Kiota client.</returns>
public static IServiceCollection AddKiotaClient<TClient>(
this IServiceCollection services,
HostBuilderContext context,
EndpointOptions? options = null,
string? name = null,
Func<IHttpClientBuilder, EndpointOptions?, IHttpClientBuilder>? configure = null
)
where TClient : class =>
services.AddKiotaClientWithEndpoint<TClient, EndpointOptions>(context, options, name, configure);

/// <summary>
/// Registers a Kiota client with the specified <paramref name="name"/> and supports additional endpoint options.
/// </summary>
/// <typeparam name="TClient">The Kiota client type to register.</typeparam>
/// <typeparam name="TEndpoint">The type of endpoint to register.</typeparam>
/// <param name="services">The <see cref="IServiceCollection"/> to register the client with.</param>
/// <param name="context">The <see cref="HostBuilderContext"/> providing the hosting context.</param>
/// <param name="options">[Optional] The endpoint options for the client (loaded from appsettings if not specified).</param>
/// <param name="name">[Optional] The name for locating endpoint information in appsettings.</param>
/// <param name="configure">[Optional] A callback for configuring the endpoint.</param>
/// <returns>The updated <see cref="IServiceCollection"/> with the registered Kiota client.</returns>
public static IServiceCollection AddKiotaClientWithEndpoint<TClient, TEndpoint>(
this IServiceCollection services,
HostBuilderContext context,
TEndpoint? options = null,
string? name = null,
Func<IHttpClientBuilder, TEndpoint?, IHttpClientBuilder>? configure = null
)
where TClient : class
where TEndpoint : EndpointOptions, new()
{
services.AddKiotaHandlers();
services.AddSingleton<AllowedHostsValidator>(sp => new AllowedHostsValidator());

return services.AddClientWithEndpoint<TClient, TEndpoint>(
context,
options,
name: name ?? typeof(TClient).FullName ?? "DefaultClient",
httpClientFactory: (s, c) => s.AddHttpClient<TClient>(name ?? typeof(TClient).FullName ?? "DefaultClient")
.AttachKiotaHandlers()
.ConfigureHttpClient(client =>
{
if (options?.Url != null)
{
client.BaseAddress = new Uri(options.Url);
}
}),
configure: configure
)
.AddSingleton<IRequestAdapter, HttpClientRequestAdapter>(sp =>
{
var tokenCache = sp.GetRequiredService<ITokenCache>();
var allowedHostsValidator = sp.GetRequiredService<AllowedHostsValidator>();
var accessTokenProvider = new TokenProvider(tokenCache, allowedHostsValidator);
var authProvider = new BaseBearerTokenAuthenticationProvider(accessTokenProvider);

var parseNodeFactory = new Microsoft.Kiota.Serialization.Json.JsonParseNodeFactory();
var serializationWriterFactory = new Microsoft.Kiota.Serialization.Json.JsonSerializationWriterFactory();
var httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient(name ?? typeof(TClient).FullName ?? "DefaultClient");

var requestAdapter = new HttpClientRequestAdapter(authProvider, parseNodeFactory, serializationWriterFactory, httpClient);

if (options?.Url != null)
{
requestAdapter.BaseUrl = options.Url;
}

return requestAdapter;
})
.AddSingleton<TClient>(sp =>
{
var requestAdapter = sp.GetRequiredService<IRequestAdapter>();
return (TClient)Activator.CreateInstance(typeof(TClient), requestAdapter)!;
});
}

/// <summary>
/// Dynamically adds Kiota handlers to the service collection.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to register the handlers with.</param>
/// <returns>The updated <see cref="IServiceCollection"/> with the registered Kiota handlers.</returns>
private static IServiceCollection AddKiotaHandlers(this IServiceCollection services)
{
var kiotaHandlers = KiotaClientFactory.GetDefaultHandlerTypes();
foreach (var handler in kiotaHandlers)
{
services.AddTransient(handler);
}

return services;
}

/// <summary>
/// Attaches Kiota handlers to the <see cref="IHttpClientBuilder"/>.
/// </summary>
/// <param name="builder">The <see cref="IHttpClientBuilder"/> to attach the handlers to.</param>
/// <returns>The updated <see cref="IHttpClientBuilder"/> with the attached Kiota handlers.</returns>
private static IHttpClientBuilder AttachKiotaHandlers(this IHttpClientBuilder builder)
{
var kiotaHandlers = KiotaClientFactory.GetDefaultHandlerTypes();
foreach (var handler in kiotaHandlers)
{
builder.AddHttpMessageHandler((sp) => (DelegatingHandler)sp.GetRequiredService(handler));
}

return builder;
}
}
Loading

0 comments on commit 44ca5be

Please sign in to comment.