Skip to content
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

Init Services and ServiceCollectionExtensions #3

Merged
merged 21 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
56c2a56
feat: add initial empty services and GraphServiceClientWrapper
perkops May 17, 2024
dfa0aa9
feat: add nuget packages for Microsoft.Graph, Atc, Logging and Resili…
perkops May 17, 2024
849a4e4
build: suppress a few rules in root .editorconfig
perkops May 17, 2024
545b15e
feat: Introduce MicrosoftGraphConstants
perkops May 17, 2024
b82420d
build: configuring MA0051 maximum_lines_per_method in root .editorconfig
perkops May 17, 2024
2e66930
feat: working on initial services and base class
perkops May 17, 2024
76424a8
feat: add default to all cancellationTokens
perkops May 17, 2024
45a0f2e
build: adding Sharepoint to team-dictionary
perkops May 18, 2024
182c73d
feat: adding Nuget package Azure.Identity
perkops May 18, 2024
c338bd1
feat: introduce RequestConfigurationFactory
perkops May 18, 2024
1d7af5d
feat: add initial draft for ServiceCollectionExtensions
perkops May 18, 2024
2e2875f
feat: adding LoggingEventIdConstants and 3 more logger statements
perkops May 18, 2024
9dd860a
feat: introduce GraphServiceOptions
perkops May 18, 2024
5030695
feat: add SetupSubscription, RenewSubscription and DeleteSubscription…
perkops May 18, 2024
f841fbc
feat: finish first draft on AddMicrosoftGraphServices in ServiceColle…
perkops May 18, 2024
263833f
fix: checking subscription for null in SetupSubscription in Sharepoin…
perkops May 18, 2024
583bd6c
chore: fixing up for rule CA1860 in RequestConfigurationFactory
perkops May 18, 2024
66f8f12
fix: ensuring GraphServiceClientWrapper constructor is protected
perkops May 18, 2024
69a93fa
refact: change GraphServiceOptions to have all parameters as required…
perkops May 18, 2024
8a87ce2
chore: suppress IDE0039 in src .editorconfig
perkops May 18, 2024
de37df1
feat: add more overloads in ServiceCollectionExtensions for supplying…
perkops May 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -519,4 +519,19 @@ dotnet_diagnostic.S6605.severity = none # Collection-specific "Exist
##########################################
# Custom - Code Analyzers Rules
##########################################
[*.{cs,csx,cake}]
[*.{cs,csx,cake}]

MA0051.maximum_lines_per_method = 100

dotnet_diagnostic.SA1010.severity = none #
dotnet_diagnostic.SA1402.severity = none #
dotnet_diagnostic.SA1615.severity = none #

dotnet_diagnostic.CA1002.severity = none #
dotnet_diagnostic.CA1031.severity = none #
dotnet_diagnostic.CA2007.severity = none # Consider calling ConfigureAwait on the awaited task

dotnet_diagnostic.MA0004.severity = none # Use Task.ConfigureAwait(false) as the current SynchronizationContext is not needed
dotnet_diagnostic.MA0016.severity = none # Prefer returning collection abstraction instead of implementation

dotnet_diagnostic.S3267.severity = none #
2 changes: 2 additions & 0 deletions Atc.Microsoft.Graph.Client.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sharepoint/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
4 changes: 3 additions & 1 deletion src/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@

##########################################
# Custom - Code Analyzers Rules
##########################################
##########################################

dotnet_diagnostic.IDE0039.severity = none #
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,12 @@
<None Include="..\..\README.md" Link="README.md" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Atc" Version="2.0.472" />
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.5.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Graph" Version="5.53.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// ReSharper disable ConvertToLocalFunction
namespace Atc.Microsoft.Graph.Client.Extensions;

public static class ServiceCollectionExtensions
{
private static readonly string[] DefaultScopes = { "https://graph.microsoft.com/.default" };

/// <summary>
/// Adds the <see cref="GraphServiceClient"/> to the service collection.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance to augment.</param>
/// <param name="graphServiceClient"><see cref="GraphServiceClient"/> to use for the service. If null, one must be available in the service provider when this service is resolved.</param>
/// <returns>The same instance as <paramref name="services"/>.</returns>
public static IServiceCollection AddMicrosoftGraphServices(
this IServiceCollection services,
GraphServiceClient? graphServiceClient = null)
{
Func<IServiceProvider, GraphServiceClient> factory = (serviceProvider)
=> graphServiceClient ?? serviceProvider.GetRequiredService<GraphServiceClient>();

services.AddSingleton(factory);

RegisterGraphServices(services);

return services;
}

/// <summary>
/// Adds the <see cref="GraphServiceClient"/> to the service collection using the provided <see cref="TokenCredential"/> and optional scopes.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance to augment.</param>
/// <param name="tokenCredential">The <see cref="TokenCredential"/> to use for authentication.</param>
/// <param name="scopes">Optional array of scopes for the <see cref="GraphServiceClient"/>.</param>
/// <returns>The same instance as <paramref name="services"/>.</returns>
public static IServiceCollection AddMicrosoftGraphServices(
this IServiceCollection services,
TokenCredential tokenCredential,
string[]? scopes = null)
{
services.AddSingleton(_ => new GraphServiceClient(tokenCredential, scopes ?? DefaultScopes));

RegisterGraphServices(services);

return services;
}

/// <summary>
/// Adds the <see cref="GraphServiceClient"/> to the service collection using the provided <see cref="GraphServiceOptions"/> and optional scopes.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance to augment.</param>
/// <param name="graphServiceOptions">The <see cref="GraphServiceOptions"/> containing configuration for the service.</param>
/// <param name="scopes">Optional array of scopes for the <see cref="GraphServiceClient"/>.</param>
/// <returns>The same instance as <paramref name="services"/>.</returns>
/// <exception cref="InvalidOperationException">Thrown if the <paramref name="graphServiceOptions"/> are invalid.</exception>
public static IServiceCollection AddMicrosoftGraphServices(
this IServiceCollection services,
GraphServiceOptions graphServiceOptions,
string[]? scopes = null)
{
ArgumentNullException.ThrowIfNull(graphServiceOptions);

if (!graphServiceOptions.IsValid())
{
throw new InvalidOperationException($"Required service '{nameof(GraphServiceOptions)}' is not registered");
}

services.AddSingleton(_ =>
{
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};

var clientSecretCredential = new ClientSecretCredential(
graphServiceOptions.TenantId,
graphServiceOptions.ClientId,
graphServiceOptions.ClientSecret,
options);

return new GraphServiceClient(clientSecretCredential, scopes ?? DefaultScopes);
});

RegisterGraphServices(services);

return services;
}

private static void RegisterGraphServices(
IServiceCollection services)
{
services.AddGraphService<IOneDriveGraphService, OneDriveGraphService>();
services.AddGraphService<IOutlookGraphService, OutlookGraphService>();
services.AddGraphService<ISharepointGraphService, SharepointGraphService>();
services.AddGraphService<ITeamsGraphService, TeamsGraphService>();
services.AddGraphService<IUsersGraphService, UsersGraphService>();
}

private static void AddGraphService<TService, TImplementation>(
this IServiceCollection services)
where TService : class
where TImplementation : GraphServiceClientWrapper, TService
{
services.AddSingleton<TService, TImplementation>(s => (TImplementation)Activator.CreateInstance(
typeof(TImplementation),
s.GetRequiredService<ILoggerFactory>(),
s.GetRequiredService<GraphServiceClient>())!);
}
}
Loading