diff --git a/src/Beffyman.AspNetCore.Client.Generator/Constants.cs b/src/Beffyman.AspNetCore.Client.Generator/Constants.cs index dc9e7f6..7e06f46 100644 --- a/src/Beffyman.AspNetCore.Client.Generator/Constants.cs +++ b/src/Beffyman.AspNetCore.Client.Generator/Constants.cs @@ -18,6 +18,7 @@ public static class Constants public const string HttpOverrideGetMethod = nameof(IHttpOverride.GetResponseAsync); public const string HttpOverrideOnNonOverridedResponse = nameof(IHttpOverride.OnNonOverridedResponseAsync); + public const string RepositoryLazyProviderName = "provider"; public const string Serializer = nameof(IHttpSerializer); public const string SerializerField = "Serializer"; diff --git a/src/Beffyman.AspNetCore.Client.Generator/GeneratorTask.cs b/src/Beffyman.AspNetCore.Client.Generator/GeneratorTask.cs index 76375db..f7207da 100644 --- a/src/Beffyman.AspNetCore.Client.Generator/GeneratorTask.cs +++ b/src/Beffyman.AspNetCore.Client.Generator/GeneratorTask.cs @@ -21,18 +21,25 @@ public class GeneratorTask : #endif { public string CurrentDirectory { get; set; } + public string RouteToServiceProjectFolder { get; set; } public string ClientInterfaceName { get; set; } public string RegisterName { get; set; } + public string UseValueTask { get; set; } public string UseInternalClients { get; set; } public string ClientRouteConstraints { get; set; } public string ErrorOnUnhandledCallback { get; set; } public string MultipleFiles { get; set; } public string GenerateStaticRoutes { get; set; } + + public string GenerateClientRepository { get; set; } + public string GenerateLazyClientRepository { get; set; } + public string RoutesNamespace { get; set; } public string ClientNamespace { get; set; } public string HubNamespace { get; set; } + public string AllowedNamespaces { get; set; } public string ExcludedNamespaces { get; set; } @@ -41,15 +48,21 @@ public void Fill(IDictionary properties) RouteToServiceProjectFolder = properties.GetValueOrDefault(nameof(RouteToServiceProjectFolder)); ClientInterfaceName = properties.GetValueOrDefault(nameof(ClientInterfaceName)); RegisterName = properties.GetValueOrDefault(nameof(RegisterName)); + UseValueTask = properties.GetValueOrDefault(nameof(UseValueTask)); UseInternalClients = properties.GetValueOrDefault(nameof(UseInternalClients)); ClientRouteConstraints = properties.GetValueOrDefault(nameof(ClientRouteConstraints)); ErrorOnUnhandledCallback = properties.GetValueOrDefault(nameof(ErrorOnUnhandledCallback)); MultipleFiles = properties.GetValueOrDefault(nameof(MultipleFiles)); GenerateStaticRoutes = properties.GetValueOrDefault(nameof(GenerateStaticRoutes)); + + GenerateClientRepository = properties.GetValueOrDefault(nameof(GenerateClientRepository)); + GenerateLazyClientRepository = properties.GetValueOrDefault(nameof(GenerateLazyClientRepository)); + RoutesNamespace = properties.GetValueOrDefault(nameof(RoutesNamespace)); ClientNamespace = properties.GetValueOrDefault(nameof(ClientNamespace)); HubNamespace = properties.GetValueOrDefault(nameof(HubNamespace)); + AllowedNamespaces = properties.GetValueOrDefault(nameof(AllowedNamespaces)); ExcludedNamespaces = properties.GetValueOrDefault(nameof(ExcludedNamespaces)); } @@ -84,15 +97,21 @@ protected override bool ExecuteIsolated() Settings.RouteToServiceProjectFolder = RouteToServiceProjectFolder; Settings.ClientInterfaceName = ClientInterfaceName; Settings.RegisterName = RegisterName; + Settings.UseValueTask = bool.Parse(UseValueTask ?? "false"); Settings.UseInternalClients = bool.Parse(UseInternalClients ?? "false"); Settings.ClientRouteConstraints = bool.Parse(ClientRouteConstraints ?? "false"); Settings.ErrorOnUnhandledCallback = bool.Parse(ErrorOnUnhandledCallback ?? "false"); Settings.MultipleFiles = bool.Parse(MultipleFiles ?? "false"); Settings.GenerateStaticRoutes = bool.Parse(GenerateStaticRoutes ?? "false"); + + Settings.GenerateClientRepository = bool.Parse(GenerateClientRepository ?? "true"); + Settings.GenerateLazyClientRepository = bool.Parse(GenerateLazyClientRepository ?? "false"); + Settings.RoutesNamespace = RoutesNamespace; Settings.ClientNamespace = ClientNamespace; Settings.HubNamespace = HubNamespace; + Settings.AllowedNamespaces = AllowedNamespaces?.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); Settings.ExcludedNamespaces = ExcludedNamespaces?.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); diff --git a/src/Beffyman.AspNetCore.Client.Generator/Output/ClassWriter.cs b/src/Beffyman.AspNetCore.Client.Generator/Output/ClassWriter.cs index f377648..7e63717 100644 --- a/src/Beffyman.AspNetCore.Client.Generator/Output/ClassWriter.cs +++ b/src/Beffyman.AspNetCore.Client.Generator/Output/ClassWriter.cs @@ -49,7 +49,8 @@ public static void WriteClientsFile(GenerationContext context) var usings = new List { - @"using Beffyman.AspNetCore.Client;", + @"//Requires nuget Beffyman.AspNetCore.Client", + "using Beffyman.AspNetCore.Client;", "using Beffyman.AspNetCore.Client.Authorization;", "using Beffyman.AspNetCore.Client.Exceptions;", "using Beffyman.AspNetCore.Client.Http;", @@ -405,6 +406,11 @@ public static string GetRelativePath(string file) public static string WriteRepositoryRegistration(string version) { + if (!Settings.GenerateClientRepository) + { + return string.Empty; + } + return $@" services.AddScoped();"; } @@ -477,6 +483,11 @@ private static string WriteRouteRepositoryEndpoint(AspNetCoreHttpController cont public static string WriteRepositories(GenerationContext context) { + if (!Settings.GenerateClientRepository) + { + return string.Empty; + } + var versions = context.HttpClients.Where(x => x.Generated) .GroupBy(x => x.NamespaceVersion) .OrderBy(x => x.Key) @@ -493,8 +504,6 @@ public static string WriteRepositories(GenerationContext context) public static string WriteRepository(IGrouping version) { - - return $@" public interface I{Settings.ClientInterfaceName}{version.Key}Repository @@ -504,39 +513,96 @@ public interface I{Settings.ClientInterfaceName}{version.Key}Repository {(Settings.UseInternalClients ? "internal" : "public")} class {Settings.ClientInterfaceName}{version.Key}Repository : I{Settings.ClientInterfaceName}{version.Key}Repository {{ +{WriteRepositoryLazyProvider()} {string.Join($@"{Environment.NewLine}", version.OrderBy(x => x.Name).Select(x => WriteRepositoryProperty(version.Key, x)))} public {Settings.ClientInterfaceName}{version.Key}Repository ( -{string.Join($@",{Environment.NewLine}", version.OrderBy(x => x.Name).Select(x => WriteRepositoryParameter(version.Key, x)))} +{WriteRepositoryLazyProviderParameter(version)} +{string.Join($@",{Environment.NewLine}", version.OrderBy(x => x.Name).Select(x => WriteRepositoryParameter(version.Key, x)).NotNull())} ) {{ +{WriteRepositoryLazyProviderAssignment()} {string.Join($@"{Environment.NewLine}", version.OrderBy(x => x.Name).Select(x => WriteRepositoryAssignment(version.Key, x)))} }} }} - "; + + } + + private static string WriteRepositoryLazyProviderParameter(IGrouping version) + { + if (!Settings.GenerateLazyClientRepository) + { + return string.Empty; + } + + return $"IServiceProvider {Constants.RepositoryLazyProviderName}"; + } + + private static string WriteRepositoryLazyProviderAssignment() + { + if (!Settings.GenerateLazyClientRepository) + { + return string.Empty; + } + + return $"this._{Constants.RepositoryLazyProviderName} = {Constants.RepositoryLazyProviderName};"; } + private static string WriteRepositoryLazyProvider() + { + if (!Settings.GenerateLazyClientRepository) + { + return string.Empty; + } + + return $"protected readonly IServiceProvider _{Constants.RepositoryLazyProviderName};"; + } - public static string WriteRepositoryInterfaceProperty(string key, AspNetCoreHttpController controller) + private static string WriteRepositoryInterfaceProperty(string key, AspNetCoreHttpController controller) { return $@"{key}{(key != null ? "." : "")}{(controller.NamespaceSuffix != null ? $"{controller.NamespaceSuffix}." : string.Empty)}I{controller.ClientName} {controller.Name} {{ get; }}"; } public static string WriteRepositoryProperty(string key, AspNetCoreHttpController controller) { - return $@"public {key}{(key != null ? "." : "")}{(controller.NamespaceSuffix != null ? $"{controller.NamespaceSuffix}." : string.Empty)}I{controller.ClientName} {controller.Name} {{ get; }}"; + string type = $"{key}{(key != null ? "." : "")}{(controller.NamespaceSuffix != null ? $"{controller.NamespaceSuffix}." : string.Empty)}I{controller.ClientName}"; + string name = controller.Name; + if (!Settings.GenerateLazyClientRepository) + { + return $@"public {type} {name} {{ get; }}"; + } + + return +$@"private readonly Lazy<{type}> lazy_{name}; +public {type} {name} => lazy_{name}.Value;"; + } public static string WriteRepositoryParameter(string key, AspNetCoreHttpController controller) { + if (Settings.GenerateLazyClientRepository) + { + return null; + } + return $@"{key}{(key != null ? "." : "")}{(controller.NamespaceSuffix != null ? $"{controller.NamespaceSuffix}." : string.Empty)}I{controller.ClientName} param_{controller.Name.ToLower()}"; } public static string WriteRepositoryAssignment(string key, AspNetCoreHttpController controller) { - return $@"this.{controller.Name} = param_{controller.Name.ToLower()};"; + if (!Settings.GenerateLazyClientRepository) + { + return $@"this.{controller.Name} = param_{controller.Name.ToLower()};"; + } + else + { + string type = $"{key}{(key != null ? "." : "")}{(controller.NamespaceSuffix != null ? $"{controller.NamespaceSuffix}." : string.Empty)}I{controller.ClientName}"; + + return +$@"this.lazy_{controller.Name} = new Lazy<{type}>(() => _{Constants.RepositoryLazyProviderName}.GetService<{type}>());"; + } } diff --git a/src/Beffyman.AspNetCore.Client.Generator/Settings.cs b/src/Beffyman.AspNetCore.Client.Generator/Settings.cs index 167940b..3e0183a 100644 --- a/src/Beffyman.AspNetCore.Client.Generator/Settings.cs +++ b/src/Beffyman.AspNetCore.Client.Generator/Settings.cs @@ -5,16 +5,23 @@ internal static class Settings public static string RouteToServiceProjectFolder { get; set; } public static string ClientInterfaceName { get; set; } public static string RegisterName { get; set; } + public static bool UseValueTask { get; set; } public static bool UseInternalClients { get; set; } public static bool ClientRouteConstraints { get; set; } public static bool ErrorOnUnhandledCallback { get; set; } public static bool MultipleFiles { get; set; } public static bool GenerateStaticRoutes { get; set; } + + public static bool GenerateClientRepository { get; set; } + public static bool GenerateLazyClientRepository { get; set; } + public static string RoutesNamespace { get; set; } public static string ClientNamespace { get; set; } public static string HubNamespace { get; set; } + + public static string[] AllowedNamespaces { get; set; } public static string[] ExcludedNamespaces { get; set; } diff --git a/src/Beffyman.AspNetCore.Client.Generator/build/Beffyman.AspNetCore.Client.Generator.props b/src/Beffyman.AspNetCore.Client.Generator/build/Beffyman.AspNetCore.Client.Generator.props index 3ea0651..0bb0802 100644 --- a/src/Beffyman.AspNetCore.Client.Generator/build/Beffyman.AspNetCore.Client.Generator.props +++ b/src/Beffyman.AspNetCore.Client.Generator/build/Beffyman.AspNetCore.Client.Generator.props @@ -10,15 +10,21 @@ MyServiceClient MyService + true true true true false true + + true + true + Routes MyService.Clients MyService.Hubs + System*; diff --git a/src/Beffyman.AspNetCore.Client.Generator/build/Beffyman.AspNetCore.Client.Generator.targets b/src/Beffyman.AspNetCore.Client.Generator/build/Beffyman.AspNetCore.Client.Generator.targets index 3557649..9deca48 100644 --- a/src/Beffyman.AspNetCore.Client.Generator/build/Beffyman.AspNetCore.Client.Generator.targets +++ b/src/Beffyman.AspNetCore.Client.Generator/build/Beffyman.AspNetCore.Client.Generator.targets @@ -10,15 +10,21 @@ RouteToServiceProjectFolder="$(RouteToServiceProjectFolder)" ClientInterfaceName="$(ClientInterfaceName)" RegisterName="$(RegisterName)" + UseValueTask="$(UseValueTask)" UseInternalClients="$(UseInternalClients)" ClientRouteConstraints="$(ClientRouteConstraints)" ErrorOnUnhandledCallback="$(ErrorOnUnhandledCallback)" MultipleFiles="$(MultipleFiles)" GenerateStaticRoutes ="$(GenerateStaticRoutes)" + + GenerateClientRepository ="$(GenerateClientRepository)" + GenerateLazyClientRepository ="$(GenerateLazyClientRepository)" + RoutesNamespace ="$(RoutesNamespace)" ClientNamespace="$(ClientNamespace)" HubNamespace="$(HubNamespace)" + AllowedNamespaces="$(AllowedNamespaces)" ExcludedNamespaces="$(ExcludedNamespaces)"/> diff --git a/tests/FunctionApp2.Clients/Clients.cs b/tests/FunctionApp2.Clients/Clients.cs index 18c182b..c817017 100644 --- a/tests/FunctionApp2.Clients/Clients.cs +++ b/tests/FunctionApp2.Clients/Clients.cs @@ -5,6 +5,7 @@ // Manual changes to this file will be overwritten if the code is regenerated. // //------------------------------------------------------------------------------ +//Requires nuget Beffyman.AspNetCore.Client using Beffyman.AspNetCore.Client.Authorization; using Beffyman.AspNetCore.Client.Exceptions; using Beffyman.AspNetCore.Client.GeneratorExtensions; diff --git a/tests/TestAzureFunction.Clients/Clients.cs b/tests/TestAzureFunction.Clients/Clients.cs index 6d68ab2..bd7b17d 100644 --- a/tests/TestAzureFunction.Clients/Clients.cs +++ b/tests/TestAzureFunction.Clients/Clients.cs @@ -5,6 +5,7 @@ // Manual changes to this file will be overwritten if the code is regenerated. // //------------------------------------------------------------------------------ +//Requires nuget Beffyman.AspNetCore.Client using Beffyman.AspNetCore.Client.Authorization; using Beffyman.AspNetCore.Client.Exceptions; using Beffyman.AspNetCore.Client.GeneratorExtensions; diff --git a/tests/TestAzureFunction.Clients/TestAzureFunction.Clients.csproj b/tests/TestAzureFunction.Clients/TestAzureFunction.Clients.csproj index d681d35..1700c3d 100644 --- a/tests/TestAzureFunction.Clients/TestAzureFunction.Clients.csproj +++ b/tests/TestAzureFunction.Clients/TestAzureFunction.Clients.csproj @@ -15,6 +15,8 @@ true false true + false + false Routes TestAzureFunction.Clients $(AllowedNamespaces);TestAzureFunction.*; diff --git a/tests/TestBlazorApp.Clients/Clients.cs b/tests/TestBlazorApp.Clients/Clients.cs index 809b6cd..f367e7d 100644 --- a/tests/TestBlazorApp.Clients/Clients.cs +++ b/tests/TestBlazorApp.Clients/Clients.cs @@ -5,6 +5,7 @@ // Manual changes to this file will be overwritten if the code is regenerated. // //------------------------------------------------------------------------------ +//Requires nuget Beffyman.AspNetCore.Client using Beffyman.AspNetCore.Client.Authorization; using Beffyman.AspNetCore.Client.Exceptions; using Beffyman.AspNetCore.Client.GeneratorExtensions; diff --git a/tests/TestBlazorApp.Clients/Installer.cs b/tests/TestBlazorApp.Clients/Installer.cs index 8fa4ee4..c66a78f 100644 --- a/tests/TestBlazorApp.Clients/Installer.cs +++ b/tests/TestBlazorApp.Clients/Installer.cs @@ -5,6 +5,7 @@ // Manual changes to this file will be overwritten if the code is regenerated. // //------------------------------------------------------------------------------ +//Requires nuget Beffyman.AspNetCore.Client using Beffyman.AspNetCore.Client.Authorization; using Beffyman.AspNetCore.Client.Exceptions; using Beffyman.AspNetCore.Client.GeneratorExtensions; @@ -41,7 +42,6 @@ public static IServiceCollection AddTestBlazorClients(this IServiceCollection se configuration.RegisterClientWrapperCreator(TestBlazorAppClientWrapper.Create); configuration.UseClientWrapper((provider) => new TestBlazorAppClientWrapper(provider.GetService>(), configuration.GetSettings(), provider)); configure?.Invoke(configuration); - services.AddScoped(); services.AddScoped(); return configuration.ApplyConfiguration(services); } @@ -85,25 +85,4 @@ public static ITestBlazorAppClientWrapper Create(Func //------------------------------------------------------------------------------ +//Requires nuget Beffyman.AspNetCore.Client using Beffyman.AspNetCore.Client.Authorization; using Beffyman.AspNetCore.Client.Exceptions; using Beffyman.AspNetCore.Client.GeneratorExtensions; diff --git a/tests/TestBlazorApp.Clients/TestBlazorApp.Clients.csproj b/tests/TestBlazorApp.Clients/TestBlazorApp.Clients.csproj index 729513e..efb7b08 100644 --- a/tests/TestBlazorApp.Clients/TestBlazorApp.Clients.csproj +++ b/tests/TestBlazorApp.Clients/TestBlazorApp.Clients.csproj @@ -15,6 +15,8 @@ false true true + false + true Routes TestBlazorApp.Clients TestBlazorApp.Hubs diff --git a/tests/TestWebApp.Clients/Clients.cs b/tests/TestWebApp.Clients/Clients.cs index d73266e..c5145f2 100644 --- a/tests/TestWebApp.Clients/Clients.cs +++ b/tests/TestWebApp.Clients/Clients.cs @@ -5,6 +5,7 @@ // Manual changes to this file will be overwritten if the code is regenerated. // //------------------------------------------------------------------------------ +//Requires nuget Beffyman.AspNetCore.Client //Requires nuget Microsoft.AspNetCore.SignalR.Client //Requires nuget Microsoft.Extensions.Logging //Requires nuget System.Threading.Channels @@ -611,38 +612,25 @@ IValuesClient Values internal class TestWebAppClientRepository : ITestWebAppClientRepository { - public IFullClient Full - { - get; - } - - public IInheritanceGenerationClient InheritanceGeneration - { - get; - } - - public FancySuffix.INamespacedClient Namespaced - { - get; - } - - public IRouteInheritanceClient RouteInheritance - { - get; - } - - public IValuesClient Values - { - get; - } - - public TestWebAppClientRepository(IFullClient param_full, IInheritanceGenerationClient param_inheritancegeneration, FancySuffix.INamespacedClient param_namespaced, IRouteInheritanceClient param_routeinheritance, IValuesClient param_values) - { - this.Full = param_full; - this.InheritanceGeneration = param_inheritancegeneration; - this.Namespaced = param_namespaced; - this.RouteInheritance = param_routeinheritance; - this.Values = param_values; + protected readonly IServiceProvider _provider; + private readonly Lazy lazy_Full; + public IFullClient Full => lazy_Full.Value; + private readonly Lazy lazy_InheritanceGeneration; + public IInheritanceGenerationClient InheritanceGeneration => lazy_InheritanceGeneration.Value; + private readonly Lazy lazy_Namespaced; + public FancySuffix.INamespacedClient Namespaced => lazy_Namespaced.Value; + private readonly Lazy lazy_RouteInheritance; + public IRouteInheritanceClient RouteInheritance => lazy_RouteInheritance.Value; + private readonly Lazy lazy_Values; + public IValuesClient Values => lazy_Values.Value; + public TestWebAppClientRepository(IServiceProvider provider) + { + this._provider = provider; + this.lazy_Full = new Lazy(() => _provider.GetService()); + this.lazy_InheritanceGeneration = new Lazy(() => _provider.GetService()); + this.lazy_Namespaced = new Lazy(() => _provider.GetService()); + this.lazy_RouteInheritance = new Lazy(() => _provider.GetService()); + this.lazy_Values = new Lazy(() => _provider.GetService()); } } @@ -656,14 +644,13 @@ V1.ITestClient Test internal class TestWebAppClientV1Repository : ITestWebAppClientV1Repository { - public V1.ITestClient Test + protected readonly IServiceProvider _provider; + private readonly Lazy lazy_Test; + public V1.ITestClient Test => lazy_Test.Value; + public TestWebAppClientV1Repository(IServiceProvider provider) { - get; - } - - public TestWebAppClientV1Repository(V1.ITestClient param_test) - { - this.Test = param_test; + this._provider = provider; + this.lazy_Test = new Lazy(() => _provider.GetService()); } } @@ -677,14 +664,13 @@ V2.ITestClient Test internal class TestWebAppClientV2Repository : ITestWebAppClientV2Repository { - public V2.ITestClient Test - { - get; - } - - public TestWebAppClientV2Repository(V2.ITestClient param_test) + protected readonly IServiceProvider _provider; + private readonly Lazy lazy_Test; + public V2.ITestClient Test => lazy_Test.Value; + public TestWebAppClientV2Repository(IServiceProvider provider) { - this.Test = param_test; + this._provider = provider; + this.lazy_Test = new Lazy(() => _provider.GetService()); } } @@ -698,14 +684,13 @@ V3.ITestQueryClient TestQuery internal class TestWebAppClientV3Repository : ITestWebAppClientV3Repository { - public V3.ITestQueryClient TestQuery - { - get; - } - - public TestWebAppClientV3Repository(V3.ITestQueryClient param_testquery) + protected readonly IServiceProvider _provider; + private readonly Lazy lazy_TestQuery; + public V3.ITestQueryClient TestQuery => lazy_TestQuery.Value; + public TestWebAppClientV3Repository(IServiceProvider provider) { - this.TestQuery = param_testquery; + this._provider = provider; + this.lazy_TestQuery = new Lazy(() => _provider.GetService()); } } @@ -719,14 +704,13 @@ V3_0.ITestRouteClient TestRoute internal class TestWebAppClientV3_0Repository : ITestWebAppClientV3_0Repository { - public V3_0.ITestRouteClient TestRoute - { - get; - } - - public TestWebAppClientV3_0Repository(V3_0.ITestRouteClient param_testroute) + protected readonly IServiceProvider _provider; + private readonly Lazy lazy_TestRoute; + public V3_0.ITestRouteClient TestRoute => lazy_TestRoute.Value; + public TestWebAppClientV3_0Repository(IServiceProvider provider) { - this.TestRoute = param_testroute; + this._provider = provider; + this.lazy_TestRoute = new Lazy(() => _provider.GetService()); } } } diff --git a/tests/TestWebApp.Clients/TestWebApp.Clients.csproj b/tests/TestWebApp.Clients/TestWebApp.Clients.csproj index f15a041..6738052 100644 --- a/tests/TestWebApp.Clients/TestWebApp.Clients.csproj +++ b/tests/TestWebApp.Clients/TestWebApp.Clients.csproj @@ -15,6 +15,8 @@ false false true + true + true Routes TestWebApp.Clients TestWebApp.Hubs