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