committed by
GitHub
17 changed files with 604 additions and 498 deletions
@ -1,13 +1,18 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Dapr.Client" Version="1.4.0" /> |
|||
<PackageReference Include="Volo.Abp.Http.Client" Version="4.4.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Dapr\LINGYUN.Abp.Dapr.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
|
|||
@ -1,24 +1,24 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Dapr.Client |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpHttpClientModule) |
|||
)] |
|||
public class AbpDaprClientModule : AbpModule |
|||
{ |
|||
/// <summary>
|
|||
/// 与AbpHttpClient集成,创建一个命名HttpClient
|
|||
/// </summary>
|
|||
internal const string DaprHttpClient = "_AbpDaprProxyClient"; |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
Configure<AbpDaprRemoteServiceOptions>(configuration); |
|||
context.Services.AddHttpClient(DaprHttpClient); |
|||
} |
|||
} |
|||
} |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Dapr.Client |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpHttpClientModule) |
|||
)] |
|||
public class AbpDaprClientModule : AbpModule |
|||
{ |
|||
/// <summary>
|
|||
/// 与AbpHttpClient集成,创建一个命名HttpClient
|
|||
/// </summary>
|
|||
internal const string DaprHttpClient = "_AbpDaprProxyClient"; |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
Configure<AbpDaprRemoteServiceOptions>(configuration); |
|||
context.Services.AddHttpClient(DaprHttpClient); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,257 +1,172 @@ |
|||
using Castle.DynamicProxy; |
|||
using Dapr.Client; |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.Dapr.Client; |
|||
using LINGYUN.Abp.Dapr.Client.DynamicProxying; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Castle.DynamicProxy; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public static class ServiceCollectionDynamicDaprClientProxyExtensions |
|||
{ |
|||
private static readonly ProxyGenerator ProxyGeneratorInstance = new ProxyGenerator(); |
|||
|
|||
#region Add DaprClient Builder
|
|||
|
|||
public static IServiceCollection AddDaprClient( |
|||
[NotNull] this IServiceCollection services) |
|||
{ |
|||
if (services == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
services.AddLogging(); |
|||
services.AddOptions(); |
|||
|
|||
services.TryAddSingleton<DefaultDaprClientFactory>(); |
|||
services.TryAddSingleton<IDaprClientFactory>(serviceProvider => serviceProvider.GetRequiredService<DefaultDaprClientFactory>()); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
public static IDaprClientBuilder AddDaprClient( |
|||
[NotNull] this IServiceCollection services, |
|||
string name) |
|||
{ |
|||
if (services == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
services.AddDaprClient(); |
|||
|
|||
return new DefaultDaprClientBuilder(services, name); |
|||
} |
|||
|
|||
public static IDaprClientBuilder AddDaprClient( |
|||
[NotNull] this IServiceCollection services, |
|||
string name, |
|||
Action<DaprClientBuilder> configureClient) |
|||
{ |
|||
if (services == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
if (name == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(name)); |
|||
} |
|||
|
|||
if (configureClient == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureClient)); |
|||
} |
|||
|
|||
services.AddDaprClient(); |
|||
|
|||
var builder = new DefaultDaprClientBuilder(services, name); |
|||
builder.ConfigureDaprClient(configureClient); |
|||
return builder; |
|||
} |
|||
|
|||
public static IDaprClientBuilder AddDaprClient( |
|||
[NotNull] this IServiceCollection services, |
|||
string name, |
|||
Action<IServiceProvider, DaprClientBuilder> configureClient) |
|||
{ |
|||
if (services == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
if (name == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(name)); |
|||
} |
|||
|
|||
if (configureClient == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureClient)); |
|||
} |
|||
|
|||
services.AddDaprClient(); |
|||
var builder = new DefaultDaprClientBuilder(services, name); |
|||
builder.ConfigureDaprClient(configureClient); |
|||
return builder; |
|||
} |
|||
|
|||
|
|||
#endregion
|
|||
|
|||
#region Add DaprClient Proxies
|
|||
|
|||
public static IServiceCollection AddDaprClientProxies( |
|||
[NotNull] this IServiceCollection services, |
|||
[NotNull] Assembly assembly, |
|||
[NotNull] string remoteServiceConfigurationName = DaprRemoteServiceConfigurationDictionary.DefaultName, |
|||
bool asDefaultServices = true) |
|||
{ |
|||
Check.NotNull(services, nameof(assembly)); |
|||
|
|||
var serviceTypes = assembly.GetTypes().Where(IsSuitableForDynamicActorProxying).ToArray(); |
|||
|
|||
foreach (var serviceType in serviceTypes) |
|||
{ |
|||
services.AddDaprClientProxy( |
|||
serviceType, |
|||
remoteServiceConfigurationName, |
|||
asDefaultServices |
|||
); |
|||
} |
|||
|
|||
return services; |
|||
} |
|||
|
|||
public static IServiceCollection AddDaprClientProxy<T>( |
|||
[NotNull] this IServiceCollection services, |
|||
[NotNull] string remoteServiceConfigurationName = DaprRemoteServiceConfigurationDictionary.DefaultName, |
|||
bool asDefaultService = true) |
|||
{ |
|||
return services.AddDaprClientProxy( |
|||
typeof(T), |
|||
remoteServiceConfigurationName, |
|||
asDefaultService |
|||
); |
|||
} |
|||
|
|||
public static IServiceCollection AddDaprClientProxy( |
|||
[NotNull] this IServiceCollection services, |
|||
[NotNull] Type type, |
|||
[NotNull] string remoteServiceConfigurationName = DaprRemoteServiceConfigurationDictionary.DefaultName, |
|||
bool asDefaultService = true) |
|||
{ |
|||
Check.NotNull(services, nameof(services)); |
|||
Check.NotNull(type, nameof(type)); |
|||
Check.NotNullOrWhiteSpace(remoteServiceConfigurationName, nameof(remoteServiceConfigurationName)); |
|||
|
|||
services.AddDaprClientFactory(remoteServiceConfigurationName); |
|||
|
|||
services.Configure<AbpDaprClientProxyOptions>(options => |
|||
{ |
|||
options.DaprClientProxies[type] = new DynamicDaprClientProxyConfig(type, remoteServiceConfigurationName); |
|||
}); |
|||
|
|||
var interceptorType = typeof(DynamicDaprClientProxyInterceptor<>).MakeGenericType(type); |
|||
services.AddTransient(interceptorType); |
|||
|
|||
var interceptorAdapterType = typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptorType); |
|||
|
|||
var validationInterceptorAdapterType = |
|||
typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(typeof(ValidationInterceptor)); |
|||
|
|||
if (asDefaultService) |
|||
{ |
|||
services.AddTransient( |
|||
type, |
|||
serviceProvider => ProxyGeneratorInstance |
|||
.CreateInterfaceProxyWithoutTarget( |
|||
type, |
|||
(IInterceptor)serviceProvider.GetRequiredService(validationInterceptorAdapterType), |
|||
(IInterceptor)serviceProvider.GetRequiredService(interceptorAdapterType) |
|||
) |
|||
); |
|||
} |
|||
|
|||
services.AddTransient( |
|||
typeof(IDaprClientProxy<>).MakeGenericType(type), |
|||
serviceProvider => |
|||
{ |
|||
var service = ProxyGeneratorInstance |
|||
.CreateInterfaceProxyWithoutTarget( |
|||
type, |
|||
(IInterceptor)serviceProvider.GetRequiredService(validationInterceptorAdapterType), |
|||
(IInterceptor)serviceProvider.GetRequiredService(interceptorAdapterType) |
|||
); |
|||
|
|||
return Activator.CreateInstance( |
|||
typeof(DaprClientProxy<>).MakeGenericType(type), |
|||
service |
|||
); |
|||
}); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
private static IServiceCollection AddDaprClientFactory( |
|||
[NotNull] this IServiceCollection services, |
|||
[NotNull] string remoteServiceConfigurationName = DaprRemoteServiceConfigurationDictionary.DefaultName) |
|||
{ |
|||
var preOptions = services.ExecutePreConfiguredActions<AbpDaprClientBuilderOptions>(); |
|||
|
|||
if (preOptions.ConfiguredProxyClients.Contains(remoteServiceConfigurationName)) |
|||
{ |
|||
return services; |
|||
} |
|||
|
|||
var clientBuilder = services.AddDaprClient(remoteServiceConfigurationName, (IServiceProvider provider, DaprClientBuilder builder) => |
|||
{ |
|||
var options = provider.GetRequiredService<IOptions<AbpDaprRemoteServiceOptions>>().Value; |
|||
builder.UseHttpEndpoint( |
|||
options.RemoteServices |
|||
.GetConfigurationOrDefault(remoteServiceConfigurationName).BaseUrl); |
|||
|
|||
foreach (var clientBuildAction in preOptions.ProxyClientBuildActions) |
|||
{ |
|||
clientBuildAction(remoteServiceConfigurationName, provider, builder); |
|||
} |
|||
}); |
|||
|
|||
clientBuilder.ConfigureDaprClient((client) => |
|||
{ |
|||
foreach (var clientBuildAction in preOptions.ProxyClientActions) |
|||
{ |
|||
clientBuildAction(remoteServiceConfigurationName, client); |
|||
} |
|||
}); |
|||
|
|||
|
|||
services.PreConfigure<AbpDaprClientBuilderOptions>(options => |
|||
{ |
|||
options.ConfiguredProxyClients.Add(remoteServiceConfigurationName); |
|||
}); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
private static bool IsSuitableForDynamicActorProxying(Type type) |
|||
{ |
|||
//TODO: Add option to change type filter
|
|||
|
|||
return type.IsInterface |
|||
&& type.IsPublic |
|||
&& !type.IsGenericType |
|||
&& typeof(IRemoteService).IsAssignableFrom(type); |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
using Castle.DynamicProxy; |
|||
using Dapr.Client; |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.Dapr.Client; |
|||
using LINGYUN.Abp.Dapr.Client.DynamicProxying; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Castle.DynamicProxy; |
|||
using Volo.Abp.Json.SystemTextJson; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public static class ServiceCollectionDynamicDaprClientProxyExtensions |
|||
{ |
|||
private static readonly ProxyGenerator ProxyGeneratorInstance = new ProxyGenerator(); |
|||
|
|||
#region Add DaprClient Proxies
|
|||
|
|||
public static IServiceCollection AddDaprClientProxies( |
|||
[NotNull] this IServiceCollection services, |
|||
[NotNull] Assembly assembly, |
|||
[NotNull] string remoteServiceConfigurationName = DaprRemoteServiceConfigurationDictionary.DefaultName, |
|||
bool asDefaultServices = true) |
|||
{ |
|||
Check.NotNull(services, nameof(assembly)); |
|||
|
|||
var serviceTypes = assembly.GetTypes().Where(IsSuitableForDynamicActorProxying).ToArray(); |
|||
|
|||
foreach (var serviceType in serviceTypes) |
|||
{ |
|||
services.AddDaprClientProxy( |
|||
serviceType, |
|||
remoteServiceConfigurationName, |
|||
asDefaultServices |
|||
); |
|||
} |
|||
|
|||
return services; |
|||
} |
|||
|
|||
public static IServiceCollection AddDaprClientProxy<T>( |
|||
[NotNull] this IServiceCollection services, |
|||
[NotNull] string remoteServiceConfigurationName = DaprRemoteServiceConfigurationDictionary.DefaultName, |
|||
bool asDefaultService = true) |
|||
{ |
|||
return services.AddDaprClientProxy( |
|||
typeof(T), |
|||
remoteServiceConfigurationName, |
|||
asDefaultService |
|||
); |
|||
} |
|||
|
|||
public static IServiceCollection AddDaprClientProxy( |
|||
[NotNull] this IServiceCollection services, |
|||
[NotNull] Type type, |
|||
[NotNull] string remoteServiceConfigurationName = DaprRemoteServiceConfigurationDictionary.DefaultName, |
|||
bool asDefaultService = true) |
|||
{ |
|||
Check.NotNull(services, nameof(services)); |
|||
Check.NotNull(type, nameof(type)); |
|||
Check.NotNullOrWhiteSpace(remoteServiceConfigurationName, nameof(remoteServiceConfigurationName)); |
|||
|
|||
services.AddDaprClientFactory(remoteServiceConfigurationName); |
|||
|
|||
services.Configure<AbpDaprClientProxyOptions>(options => |
|||
{ |
|||
options.DaprClientProxies[type] = new DynamicDaprClientProxyConfig(type, remoteServiceConfigurationName); |
|||
}); |
|||
|
|||
var interceptorType = typeof(DynamicDaprClientProxyInterceptor<>).MakeGenericType(type); |
|||
services.AddTransient(interceptorType); |
|||
|
|||
var interceptorAdapterType = typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptorType); |
|||
|
|||
var validationInterceptorAdapterType = |
|||
typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(typeof(ValidationInterceptor)); |
|||
|
|||
if (asDefaultService) |
|||
{ |
|||
services.AddTransient( |
|||
type, |
|||
serviceProvider => ProxyGeneratorInstance |
|||
.CreateInterfaceProxyWithoutTarget( |
|||
type, |
|||
(IInterceptor)serviceProvider.GetRequiredService(validationInterceptorAdapterType), |
|||
(IInterceptor)serviceProvider.GetRequiredService(interceptorAdapterType) |
|||
) |
|||
); |
|||
} |
|||
|
|||
services.AddTransient( |
|||
typeof(IDaprClientProxy<>).MakeGenericType(type), |
|||
serviceProvider => |
|||
{ |
|||
var service = ProxyGeneratorInstance |
|||
.CreateInterfaceProxyWithoutTarget( |
|||
type, |
|||
(IInterceptor)serviceProvider.GetRequiredService(validationInterceptorAdapterType), |
|||
(IInterceptor)serviceProvider.GetRequiredService(interceptorAdapterType) |
|||
); |
|||
|
|||
return Activator.CreateInstance( |
|||
typeof(DaprClientProxy<>).MakeGenericType(type), |
|||
service |
|||
); |
|||
}); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
private static IServiceCollection AddDaprClientFactory( |
|||
[NotNull] this IServiceCollection services, |
|||
[NotNull] string remoteServiceConfigurationName = DaprRemoteServiceConfigurationDictionary.DefaultName) |
|||
{ |
|||
var preOptions = services.ExecutePreConfiguredActions<AbpDaprClientBuilderOptions>(); |
|||
|
|||
if (preOptions.ConfiguredProxyClients.Contains(remoteServiceConfigurationName)) |
|||
{ |
|||
return services; |
|||
} |
|||
|
|||
var clientBuilder = services.AddDaprClient(remoteServiceConfigurationName, (IServiceProvider provider, DaprClientBuilder builder) => |
|||
{ |
|||
// TODO: 是否有必要? 使用框架的序列化配置
|
|||
var jsonOptions = provider.GetRequiredService<IOptions<AbpSystemTextJsonSerializerOptions>>().Value; |
|||
builder.UseJsonSerializationOptions(jsonOptions.JsonSerializerOptions); |
|||
|
|||
var options = provider.GetRequiredService<IOptions<AbpDaprRemoteServiceOptions>>().Value; |
|||
builder.UseHttpEndpoint( |
|||
options.RemoteServices |
|||
.GetConfigurationOrDefault(remoteServiceConfigurationName).BaseUrl); |
|||
|
|||
foreach (var clientBuildAction in preOptions.ProxyClientBuildActions) |
|||
{ |
|||
clientBuildAction(remoteServiceConfigurationName, provider, builder); |
|||
} |
|||
}); |
|||
|
|||
clientBuilder.ConfigureDaprClient((client) => |
|||
{ |
|||
foreach (var clientBuildAction in preOptions.ProxyClientActions) |
|||
{ |
|||
clientBuildAction(remoteServiceConfigurationName, client); |
|||
} |
|||
}); |
|||
|
|||
|
|||
services.PreConfigure<AbpDaprClientBuilderOptions>(options => |
|||
{ |
|||
options.ConfiguredProxyClients.Add(remoteServiceConfigurationName); |
|||
}); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
private static bool IsSuitableForDynamicActorProxying(Type type) |
|||
{ |
|||
//TODO: Add option to change type filter
|
|||
|
|||
return type.IsInterface |
|||
&& type.IsPublic |
|||
&& !type.IsGenericType |
|||
&& typeof(IRemoteService).IsAssignableFrom(type); |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
|
|||
@ -1,72 +1,72 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
public static class DaprClientBuilderExtensions |
|||
{ |
|||
public static IDaprClientBuilder ConfigureDaprClient(this IDaprClientBuilder builder, Action<DaprClient> configureClient) |
|||
{ |
|||
if (builder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(builder)); |
|||
} |
|||
|
|||
if (configureClient == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureClient)); |
|||
} |
|||
|
|||
builder.Services.Configure<DaprClientFactoryOptions>(builder.Name, options => |
|||
{ |
|||
options.DaprClientActions.Add(configureClient); |
|||
}); |
|||
|
|||
return builder; |
|||
} |
|||
|
|||
public static IDaprClientBuilder ConfigureDaprClient(this IDaprClientBuilder builder, Action<DaprClientBuilder> configureBuilder) |
|||
{ |
|||
if (builder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(builder)); |
|||
} |
|||
|
|||
if (configureBuilder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureBuilder)); |
|||
} |
|||
|
|||
builder.Services.Configure<DaprClientFactoryOptions>(builder.Name, options => |
|||
{ |
|||
options.DaprClientBuilderActions.Add(configureBuilder); |
|||
}); |
|||
|
|||
return builder; |
|||
} |
|||
|
|||
public static IDaprClientBuilder ConfigureDaprClient(this IDaprClientBuilder builder, Action<IServiceProvider, DaprClientBuilder> configureClientBuilder) |
|||
{ |
|||
if (builder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(builder)); |
|||
} |
|||
|
|||
if (configureClientBuilder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureClientBuilder)); |
|||
} |
|||
|
|||
builder.Services.AddTransient<IConfigureOptions<DaprClientFactoryOptions>>(services => |
|||
{ |
|||
return new ConfigureNamedOptions<DaprClientFactoryOptions>(builder.Name, (options) => |
|||
{ |
|||
options.DaprClientBuilderActions.Add(client => configureClientBuilder(services, client)); |
|||
}); |
|||
}); |
|||
|
|||
return builder; |
|||
} |
|||
} |
|||
} |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
public static class DaprClientBuilderExtensions |
|||
{ |
|||
public static IDaprClientBuilder ConfigureDaprClient(this IDaprClientBuilder builder, Action<DaprClient> configureClient) |
|||
{ |
|||
if (builder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(builder)); |
|||
} |
|||
|
|||
if (configureClient == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureClient)); |
|||
} |
|||
|
|||
builder.Services.Configure<DaprClientFactoryOptions>(builder.Name, options => |
|||
{ |
|||
options.DaprClientActions.Add(configureClient); |
|||
}); |
|||
|
|||
return builder; |
|||
} |
|||
|
|||
public static IDaprClientBuilder ConfigureDaprClient(this IDaprClientBuilder builder, Action<DaprClientBuilder> configureBuilder) |
|||
{ |
|||
if (builder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(builder)); |
|||
} |
|||
|
|||
if (configureBuilder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureBuilder)); |
|||
} |
|||
|
|||
builder.Services.Configure<DaprClientFactoryOptions>(builder.Name, options => |
|||
{ |
|||
options.DaprClientBuilderActions.Add(configureBuilder); |
|||
}); |
|||
|
|||
return builder; |
|||
} |
|||
|
|||
public static IDaprClientBuilder ConfigureDaprClient(this IDaprClientBuilder builder, Action<IServiceProvider, DaprClientBuilder> configureClientBuilder) |
|||
{ |
|||
if (builder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(builder)); |
|||
} |
|||
|
|||
if (configureClientBuilder == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureClientBuilder)); |
|||
} |
|||
|
|||
builder.Services.AddTransient<IConfigureOptions<DaprClientFactoryOptions>>(services => |
|||
{ |
|||
return new ConfigureNamedOptions<DaprClientFactoryOptions>(builder.Name, (options) => |
|||
{ |
|||
options.DaprClientBuilderActions.Add(client => configureClientBuilder(services, client)); |
|||
}); |
|||
}); |
|||
|
|||
return builder; |
|||
} |
|||
} |
|||
} |
|||
@ -1,21 +1,21 @@ |
|||
using Grpc.Net.Client; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
public class DaprClientFactoryOptions |
|||
{ |
|||
public string DaprApiToken{ get; set; } |
|||
public string HttpEndpoint { get; set; } |
|||
public string GrpcEndpoint { get; set; } |
|||
public GrpcChannelOptions GrpcChannelOptions { get; set; } |
|||
public JsonSerializerOptions JsonSerializerOptions { get; set; } |
|||
public IList<Action<DaprClient>> DaprClientActions { get; } = new List<Action<DaprClient>>(); |
|||
public IList<Action<DaprClientBuilder>> DaprClientBuilderActions { get; } = new List<Action<DaprClientBuilder>>(); |
|||
public DaprClientFactoryOptions() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
using Grpc.Net.Client; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
public class DaprClientFactoryOptions |
|||
{ |
|||
public string DaprApiToken{ get; set; } |
|||
public string HttpEndpoint { get; set; } |
|||
public string GrpcEndpoint { get; set; } |
|||
public GrpcChannelOptions GrpcChannelOptions { get; set; } |
|||
public JsonSerializerOptions JsonSerializerOptions { get; set; } |
|||
public IList<Action<DaprClient>> DaprClientActions { get; } = new List<Action<DaprClient>>(); |
|||
public IList<Action<DaprClientBuilder>> DaprClientBuilderActions { get; } = new List<Action<DaprClientBuilder>>(); |
|||
public DaprClientFactoryOptions() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,17 +1,17 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
internal class DefaultDaprClientBuilder : IDaprClientBuilder |
|||
{ |
|||
public DefaultDaprClientBuilder(IServiceCollection services, string name) |
|||
{ |
|||
Services = services; |
|||
Name = name; |
|||
} |
|||
|
|||
public string Name { get; } |
|||
|
|||
public IServiceCollection Services { get; } |
|||
} |
|||
} |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
internal class DefaultDaprClientBuilder : IDaprClientBuilder |
|||
{ |
|||
public DefaultDaprClientBuilder(IServiceCollection services, string name) |
|||
{ |
|||
Services = services; |
|||
Name = name; |
|||
} |
|||
|
|||
public string Name { get; } |
|||
|
|||
public IServiceCollection Services { get; } |
|||
} |
|||
} |
|||
@ -1,82 +1,82 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Collections.Concurrent; |
|||
using System.Threading; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
public class DefaultDaprClientFactory : IDaprClientFactory |
|||
{ |
|||
private readonly IOptionsMonitor<DaprClientFactoryOptions> _optionsMonitor; |
|||
|
|||
private readonly Func<string, Lazy<DaprClient>> _daprClientFactory; |
|||
internal readonly ConcurrentDictionary<string, Lazy<DaprClient>> _daprClients; |
|||
|
|||
public DefaultDaprClientFactory( |
|||
IOptionsMonitor<DaprClientFactoryOptions> optionsMonitor) |
|||
{ |
|||
_optionsMonitor = optionsMonitor ?? throw new ArgumentNullException(nameof(optionsMonitor)); |
|||
|
|||
_daprClients = new ConcurrentDictionary<string, Lazy<DaprClient>>(); |
|||
|
|||
_daprClientFactory = (name) => |
|||
{ |
|||
return new Lazy<DaprClient>(() => |
|||
{ |
|||
return InternalCreateDaprClient(name); |
|||
}, LazyThreadSafetyMode.ExecutionAndPublication); |
|||
}; |
|||
} |
|||
|
|||
public DaprClient CreateClient(string name) |
|||
{ |
|||
if (name == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(name)); |
|||
} |
|||
|
|||
var client = _daprClients.GetOrAdd(name, _daprClientFactory).Value; |
|||
|
|||
var options = _optionsMonitor.Get(name); |
|||
for (int i = 0; i < options.DaprClientActions.Count; i++) |
|||
{ |
|||
options.DaprClientActions[i](client); |
|||
} |
|||
|
|||
return client; |
|||
} |
|||
|
|||
internal DaprClient InternalCreateDaprClient(string name) |
|||
{ |
|||
var builder = new DaprClientBuilder(); |
|||
|
|||
var options = _optionsMonitor.Get(name); |
|||
|
|||
if (!string.IsNullOrWhiteSpace(options.HttpEndpoint)) |
|||
{ |
|||
builder.UseHttpEndpoint(options.HttpEndpoint); |
|||
} |
|||
if (!string.IsNullOrWhiteSpace(options.GrpcEndpoint)) |
|||
{ |
|||
builder.UseGrpcEndpoint(options.GrpcEndpoint); |
|||
} |
|||
if (options.GrpcChannelOptions != null) |
|||
{ |
|||
builder.UseGrpcChannelOptions(options.GrpcChannelOptions); |
|||
} |
|||
if (options.JsonSerializerOptions != null) |
|||
{ |
|||
builder.UseJsonSerializationOptions(options.JsonSerializerOptions); |
|||
} |
|||
|
|||
builder.UseDaprApiToken(options.DaprApiToken); |
|||
|
|||
for (int i = 0; i < options.DaprClientBuilderActions.Count; i++) |
|||
{ |
|||
options.DaprClientBuilderActions[i](builder); |
|||
} |
|||
|
|||
return builder.Build(); |
|||
} |
|||
} |
|||
} |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Collections.Concurrent; |
|||
using System.Threading; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
public class DefaultDaprClientFactory : IDaprClientFactory |
|||
{ |
|||
private readonly IOptionsMonitor<DaprClientFactoryOptions> _optionsMonitor; |
|||
|
|||
private readonly Func<string, Lazy<DaprClient>> _daprClientFactory; |
|||
internal readonly ConcurrentDictionary<string, Lazy<DaprClient>> _daprClients; |
|||
|
|||
public DefaultDaprClientFactory( |
|||
IOptionsMonitor<DaprClientFactoryOptions> optionsMonitor) |
|||
{ |
|||
_optionsMonitor = optionsMonitor ?? throw new ArgumentNullException(nameof(optionsMonitor)); |
|||
|
|||
_daprClients = new ConcurrentDictionary<string, Lazy<DaprClient>>(); |
|||
|
|||
_daprClientFactory = (name) => |
|||
{ |
|||
return new Lazy<DaprClient>(() => |
|||
{ |
|||
return InternalCreateDaprClient(name); |
|||
}, LazyThreadSafetyMode.ExecutionAndPublication); |
|||
}; |
|||
} |
|||
|
|||
public DaprClient CreateClient(string name) |
|||
{ |
|||
if (name == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(name)); |
|||
} |
|||
|
|||
var client = _daprClients.GetOrAdd(name, _daprClientFactory).Value; |
|||
|
|||
var options = _optionsMonitor.Get(name); |
|||
for (int i = 0; i < options.DaprClientActions.Count; i++) |
|||
{ |
|||
options.DaprClientActions[i](client); |
|||
} |
|||
|
|||
return client; |
|||
} |
|||
|
|||
internal DaprClient InternalCreateDaprClient(string name) |
|||
{ |
|||
var builder = new DaprClientBuilder(); |
|||
|
|||
var options = _optionsMonitor.Get(name); |
|||
|
|||
if (!string.IsNullOrWhiteSpace(options.HttpEndpoint)) |
|||
{ |
|||
builder.UseHttpEndpoint(options.HttpEndpoint); |
|||
} |
|||
if (!string.IsNullOrWhiteSpace(options.GrpcEndpoint)) |
|||
{ |
|||
builder.UseGrpcEndpoint(options.GrpcEndpoint); |
|||
} |
|||
if (options.GrpcChannelOptions != null) |
|||
{ |
|||
builder.UseGrpcChannelOptions(options.GrpcChannelOptions); |
|||
} |
|||
if (options.JsonSerializerOptions != null) |
|||
{ |
|||
builder.UseJsonSerializationOptions(options.JsonSerializerOptions); |
|||
} |
|||
|
|||
builder.UseDaprApiToken(options.DaprApiToken); |
|||
|
|||
for (int i = 0; i < options.DaprClientBuilderActions.Count; i++) |
|||
{ |
|||
options.DaprClientBuilderActions[i](builder); |
|||
} |
|||
|
|||
return builder.Build(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,10 +1,10 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
public interface IDaprClientBuilder |
|||
{ |
|||
string Name { get; } |
|||
IServiceCollection Services { get; } |
|||
} |
|||
} |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace Dapr.Client |
|||
{ |
|||
public interface IDaprClientBuilder |
|||
{ |
|||
string Name { get; } |
|||
IServiceCollection Services { get; } |
|||
} |
|||
} |
|||
@ -1,7 +1,7 @@ |
|||
namespace Dapr.Client |
|||
{ |
|||
public interface IDaprClientFactory |
|||
{ |
|||
DaprClient CreateClient(string name); |
|||
} |
|||
} |
|||
namespace Dapr.Client |
|||
{ |
|||
public interface IDaprClientFactory |
|||
{ |
|||
DaprClient CreateClient(string name); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Core" Version="4.4.0" /> |
|||
<PackageReference Include="Dapr.Client" Version="1.5.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Dapr |
|||
{ |
|||
public class AbpDaprModule : AbpModule |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,99 @@ |
|||
using Dapr.Client; |
|||
using JetBrains.Annotations; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using System; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public static class ServiceCollectionDaprClientExtensions |
|||
{ |
|||
#region Add DaprClient Builder
|
|||
|
|||
public static IServiceCollection AddDaprClient( |
|||
[NotNull] this IServiceCollection services) |
|||
{ |
|||
if (services == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
services.AddLogging(); |
|||
services.AddOptions(); |
|||
|
|||
services.TryAddSingleton<DefaultDaprClientFactory>(); |
|||
services.TryAddSingleton<IDaprClientFactory>(serviceProvider => serviceProvider.GetRequiredService<DefaultDaprClientFactory>()); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
public static IDaprClientBuilder AddDaprClient( |
|||
[NotNull] this IServiceCollection services, |
|||
string name) |
|||
{ |
|||
if (services == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
services.AddDaprClient(); |
|||
|
|||
return new DefaultDaprClientBuilder(services, name); |
|||
} |
|||
|
|||
public static IDaprClientBuilder AddDaprClient( |
|||
[NotNull] this IServiceCollection services, |
|||
string name, |
|||
Action<DaprClientBuilder> configureClient) |
|||
{ |
|||
if (services == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
if (name == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(name)); |
|||
} |
|||
|
|||
if (configureClient == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureClient)); |
|||
} |
|||
|
|||
services.AddDaprClient(); |
|||
|
|||
var builder = new DefaultDaprClientBuilder(services, name); |
|||
builder.ConfigureDaprClient(configureClient); |
|||
return builder; |
|||
} |
|||
|
|||
public static IDaprClientBuilder AddDaprClient( |
|||
[NotNull] this IServiceCollection services, |
|||
string name, |
|||
Action<IServiceProvider, DaprClientBuilder> configureClient) |
|||
{ |
|||
if (services == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
if (name == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(name)); |
|||
} |
|||
|
|||
if (configureClient == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(configureClient)); |
|||
} |
|||
|
|||
services.AddDaprClient(); |
|||
var builder = new DefaultDaprClientBuilder(services, name); |
|||
builder.ConfigureDaprClient(configureClient); |
|||
return builder; |
|||
} |
|||
|
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
# LINGYUN.Abp.Dapr |
|||
|
|||
Dapr 集成基础模块, 实现dapr文档中的命名单例DaprClient |
|||
|
|||
See: https://docs.dapr.io/developing-applications/sdks/dotnet/dotnet-client/dotnet-daprclient-usage |
|||
|
|||
## 配置使用 |
|||
|
|||
模块按需引用 |
|||
|
|||
```csharp |
|||
[DependsOn(typeof(AbpDaprModule))] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
// 创建一个DaprClient |
|||
context.Services.AddDaprClient(); |
|||
|
|||
// 创建一个具名DaprClient |
|||
context.Services.AddDaprClient("__DaprClient"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## 其他 |
|||
Loading…
Reference in new issue