diff --git a/build/version.props b/build/version.props
index 1d665af..2181d53 100644
--- a/build/version.props
+++ b/build/version.props
@@ -2,7 +2,7 @@
5
1
- 3
+ 4
$(VersionMajor).$(VersionMinor).$(VersionPatch)
diff --git a/docs/content/user-guide/en/transport/general.md b/docs/content/user-guide/en/transport/general.md
index f0c0074..a34071d 100644
--- a/docs/content/user-guide/en/transport/general.md
+++ b/docs/content/user-guide/en/transport/general.md
@@ -10,6 +10,7 @@ CAP supports several transport methods:
* [Kafka](kafka.md)
* [Azure Service Bus](azure-service-bus.md)
* [Amazon SQS](aws-sqs.md)
+* [NATS](nats.md)
* [In-Memory Queue](in-memory-queue.md)
* [Redis Streams](redis-streams.md)
diff --git a/docs/content/user-guide/en/transport/nats.md b/docs/content/user-guide/en/transport/nats.md
new file mode 100644
index 0000000..4efcd4f
--- /dev/null
+++ b/docs/content/user-guide/en/transport/nats.md
@@ -0,0 +1,56 @@
+# NATS
+
+[NATS](https://nats.io/) is a simple, secure and performant communications system for digital systems, services and devices. NATS is part of the Cloud Native Computing Foundation (CNCF).
+
+## Configuration
+
+To use NATS transporter, you need to install the following package from NuGet:
+
+```powershell
+
+PM> Install-Package DotNetCore.CAP.NATS
+
+```
+
+Then you can add configuration items to the `ConfigureServices` method of `Startup.cs`.
+
+```csharp
+
+public void ConfigureServices(IServiceCollection services)
+{
+ services.AddCap(capOptions =>
+ {
+ capOptions.UseNATS(natsOptions=>{
+ //NATS Options
+ });
+ });
+}
+
+```
+
+#### NATS Options
+
+NATS configuration parameters provided directly by the CAP:
+
+NAME | DESCRIPTION | TYPE | DEFAULT
+:---|:---|---|:---
+Options | NATS client configuration | Options | Options
+Servers | Server url/urls used to connect to the NATs server. | string | NULL
+ConnectionPoolSize | number of connections pool | uint | 10
+
+#### NATS ConfigurationOptions
+
+If you need **more** native NATS related configuration options, you can set them in the `Options` option:
+
+```csharp
+services.AddCap(capOptions =>
+{
+ capOptions.UseNATS(natsOptions=>
+ {
+ // NATS options.
+ natsOptions.Options.Url="";
+ });
+});
+```
+
+`Options` is a NATS.Client ConfigurationOptions , you can find more details through this [link](http://nats-io.github.io/nats.net/class_n_a_t_s_1_1_client_1_1_options.html)
diff --git a/docs/content/user-guide/zh/transport/general.md b/docs/content/user-guide/zh/transport/general.md
index b402aea..13736ef 100644
--- a/docs/content/user-guide/zh/transport/general.md
+++ b/docs/content/user-guide/zh/transport/general.md
@@ -10,6 +10,7 @@ CAP 支持以下几种运输方式:
* [Kafka](kafka.md)
* [Azure Service Bus](azure-service-bus.md)
* [Amazon SQS](aws-sqs.md)
+* [NATS](nats.md)
* [In-Memory Queue](in-memory-queue.md)
* [Redis Streams](redis-streams.md)
diff --git a/docs/content/user-guide/zh/transport/nats.md b/docs/content/user-guide/zh/transport/nats.md
new file mode 100644
index 0000000..3ed0e41
--- /dev/null
+++ b/docs/content/user-guide/zh/transport/nats.md
@@ -0,0 +1,57 @@
+# NATS
+
+[NATS](https://nats.io/)是一个简单、安全、高性能的数字系统、服务和设备通信系统。NATS 是 CNCF 的一部分。
+
+## 配置
+
+要使用NATS 传输器,你需要安装下面的NuGet包:
+
+```powershell
+
+PM> Install-Package DotNetCore.CAP.NATS
+
+```
+
+你可以通过在 `Startup.cs` 文件中配置 `ConfigureServices` 来添加配置:
+
+```csharp
+
+public void ConfigureServices(IServiceCollection services)
+{
+ services.AddCap(capOptions =>
+ {
+ capOptions.UseNATS(natsOptions=>{
+ //NATS Options
+ });
+ });
+}
+
+```
+
+#### NATS 配置
+
+CAP 直接提供的关于 NATS 的配置参数:
+
+
+NAME | DESCRIPTION | TYPE | DEFAULT
+:---|:---|---|:---
+Options | NATS 客户端配置 | Options | Options
+Servers | 服务器Urls地址 | string | NULL
+ConnectionPoolSize | 连接池数量 | uint | 10
+
+#### NATS ConfigurationOptions
+
+如果你需要 **更多** 原生相关的配置项,可以通过 `Options` 配置项进行设定:
+
+```csharp
+services.AddCap(capOptions =>
+{
+ capOptions.UseNATS(natsOptions=>
+ {
+ // NATS options.
+ natsOptions.Options.Url="";
+ });
+});
+```
+
+`Options` 是 NATS.Client 客户端提供的配置, 你可以在这个[链接](http://nats-io.github.io/nats.net/class_n_a_t_s_1_1_client_1_1_options.html)找到更多详细信息。
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index fae7efb..0b57828 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -98,6 +98,7 @@ nav:
- Amazon SQS: user-guide/en/transport/aws-sqs.md
- Apache Kafka®: user-guide/en/transport/kafka.md
- Azure Service Bus: user-guide/en/transport/azure-service-bus.md
+ - NATS: user-guide/en/transport/nats.md
- RabbitMQ: user-guide/en/transport/rabbitmq.md
- Redis Streams: user-guide/en/transport/redis-streams.md
- In-Memory Queue: user-guide/en/transport/in-memory-queue.md
@@ -133,6 +134,7 @@ nav:
- Amazon SQS: user-guide/zh/transport/aws-sqs.md
- Apache Kafka®: user-guide/zh/transport/kafka.md
- Azure Service Bus: user-guide/zh/transport/azure-service-bus.md
+ - NATS: user-guide/zh/transport/nats.md
- RabbitMQ: user-guide/zh/transport/rabbitmq.md
- Redis Streams: user-guide/zh/transport/redis-streams.md
- In-Memory Queue: user-guide/zh/transport/in-memory-queue.md
diff --git a/src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj b/src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj
index 09fcb2e..6055118 100644
--- a/src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj
+++ b/src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj
@@ -6,19 +6,18 @@
+
+
-
-
-
-
+
-
+
diff --git a/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/AwaitableInfo.cs b/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/AwaitableInfo.cs
deleted file mode 100644
index 7046303..0000000
--- a/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/AwaitableInfo.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-namespace Microsoft.Extensions.Internal
-{
- internal struct AwaitableInfo
- {
- public Type AwaiterType { get; }
- public PropertyInfo AwaiterIsCompletedProperty { get; }
- public MethodInfo AwaiterGetResultMethod { get; }
- public MethodInfo AwaiterOnCompletedMethod { get; }
- public MethodInfo AwaiterUnsafeOnCompletedMethod { get; }
- public Type ResultType { get; }
- public MethodInfo GetAwaiterMethod { get; }
-
- public AwaitableInfo(
- Type awaiterType,
- PropertyInfo awaiterIsCompletedProperty,
- MethodInfo awaiterGetResultMethod,
- MethodInfo awaiterOnCompletedMethod,
- MethodInfo awaiterUnsafeOnCompletedMethod,
- Type resultType,
- MethodInfo getAwaiterMethod)
- {
- AwaiterType = awaiterType;
- AwaiterIsCompletedProperty = awaiterIsCompletedProperty;
- AwaiterGetResultMethod = awaiterGetResultMethod;
- AwaiterOnCompletedMethod = awaiterOnCompletedMethod;
- AwaiterUnsafeOnCompletedMethod = awaiterUnsafeOnCompletedMethod;
- ResultType = resultType;
- GetAwaiterMethod = getAwaiterMethod;
- }
-
- public static bool IsTypeAwaitable(Type type, out AwaitableInfo awaitableInfo)
- {
- // Based on Roslyn code: http://source.roslyn.io/#Microsoft.CodeAnalysis.Workspaces/Shared/Extensions/ISymbolExtensions.cs,db4d48ba694b9347
-
- // Awaitable must have method matching "object GetAwaiter()"
- var getAwaiterMethod = type.GetRuntimeMethods().FirstOrDefault(m =>
- m.Name.Equals("GetAwaiter", StringComparison.OrdinalIgnoreCase)
- && m.GetParameters().Length == 0
- && m.ReturnType != null);
- if (getAwaiterMethod == null)
- {
- awaitableInfo = default(AwaitableInfo);
- return false;
- }
-
- var awaiterType = getAwaiterMethod.ReturnType;
-
- // Awaiter must have property matching "bool IsCompleted { get; }"
- var isCompletedProperty = awaiterType.GetRuntimeProperties().FirstOrDefault(p =>
- p.Name.Equals("IsCompleted", StringComparison.OrdinalIgnoreCase)
- && p.PropertyType == typeof(bool)
- && p.GetMethod != null);
- if (isCompletedProperty == null)
- {
- awaitableInfo = default(AwaitableInfo);
- return false;
- }
-
- // Awaiter must implement INotifyCompletion
- var awaiterInterfaces = awaiterType.GetInterfaces();
- var implementsINotifyCompletion = awaiterInterfaces.Any(t => t == typeof(INotifyCompletion));
- if (!implementsINotifyCompletion)
- {
- awaitableInfo = default(AwaitableInfo);
- return false;
- }
-
- // INotifyCompletion supplies a method matching "void OnCompleted(Action action)"
- var iNotifyCompletionMap = awaiterType
- .GetTypeInfo()
- .GetRuntimeInterfaceMap(typeof(INotifyCompletion));
- var onCompletedMethod = iNotifyCompletionMap.InterfaceMethods.Single(m =>
- m.Name.Equals("OnCompleted", StringComparison.OrdinalIgnoreCase)
- && m.ReturnType == typeof(void)
- && m.GetParameters().Length == 1
- && m.GetParameters()[0].ParameterType == typeof(Action));
-
- // Awaiter optionally implements ICriticalNotifyCompletion
- var implementsICriticalNotifyCompletion =
- awaiterInterfaces.Any(t => t == typeof(ICriticalNotifyCompletion));
- MethodInfo unsafeOnCompletedMethod;
- if (implementsICriticalNotifyCompletion)
- {
- // ICriticalNotifyCompletion supplies a method matching "void UnsafeOnCompleted(Action action)"
- var iCriticalNotifyCompletionMap = awaiterType
- .GetTypeInfo()
- .GetRuntimeInterfaceMap(typeof(ICriticalNotifyCompletion));
- unsafeOnCompletedMethod = iCriticalNotifyCompletionMap.InterfaceMethods.Single(m =>
- m.Name.Equals("UnsafeOnCompleted", StringComparison.OrdinalIgnoreCase)
- && m.ReturnType == typeof(void)
- && m.GetParameters().Length == 1
- && m.GetParameters()[0].ParameterType == typeof(Action));
- }
- else
- {
- unsafeOnCompletedMethod = null;
- }
-
- // Awaiter must have method matching "void GetResult" or "T GetResult()"
- var getResultMethod = awaiterType.GetRuntimeMethods().FirstOrDefault(m =>
- m.Name.Equals("GetResult")
- && m.GetParameters().Length == 0);
- if (getResultMethod == null)
- {
- awaitableInfo = default(AwaitableInfo);
- return false;
- }
-
- awaitableInfo = new AwaitableInfo(
- awaiterType,
- isCompletedProperty,
- getResultMethod,
- onCompletedMethod,
- unsafeOnCompletedMethod,
- getResultMethod.ReturnType,
- getAwaiterMethod);
- return true;
- }
- }
-}
\ No newline at end of file
diff --git a/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/CoercedAwaitableInfo.cs b/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/CoercedAwaitableInfo.cs
deleted file mode 100644
index 3f923e0..0000000
--- a/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/CoercedAwaitableInfo.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Linq.Expressions;
-
-namespace Microsoft.Extensions.Internal
-{
- internal struct CoercedAwaitableInfo
- {
- public AwaitableInfo AwaitableInfo { get; }
- public Expression CoercerExpression { get; }
- public Type CoercerResultType { get; }
- public bool RequiresCoercion => CoercerExpression != null;
-
- public CoercedAwaitableInfo(AwaitableInfo awaitableInfo)
- {
- AwaitableInfo = awaitableInfo;
- CoercerExpression = null;
- CoercerResultType = null;
- }
-
- public CoercedAwaitableInfo(Expression coercerExpression, Type coercerResultType,
- AwaitableInfo coercedAwaitableInfo)
- {
- CoercerExpression = coercerExpression;
- CoercerResultType = coercerResultType;
- AwaitableInfo = coercedAwaitableInfo;
- }
-
- public static bool IsTypeAwaitable(Type type, out CoercedAwaitableInfo info)
- {
- if (AwaitableInfo.IsTypeAwaitable(type, out var directlyAwaitableInfo))
- {
- info = new CoercedAwaitableInfo(directlyAwaitableInfo);
- return true;
- }
-
- // It's not directly awaitable, but maybe we can coerce it.
- // Currently we support coercing FSharpAsync.
- if (ObjectMethodExecutorFSharpSupport.TryBuildCoercerFromFSharpAsyncToAwaitable(type,
- out var coercerExpression,
- out var coercerResultType))
- {
- if (AwaitableInfo.IsTypeAwaitable(coercerResultType, out var coercedAwaitableInfo))
- {
- info = new CoercedAwaitableInfo(coercerExpression, coercerResultType, coercedAwaitableInfo);
- return true;
- }
- }
-
- info = default(CoercedAwaitableInfo);
- return false;
- }
- }
-}
\ No newline at end of file
diff --git a/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/ObjectMethodExecutor.cs b/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/ObjectMethodExecutor.cs
deleted file mode 100644
index 26708a2..0000000
--- a/src/DotNetCore.CAP.Dashboard/ObjectMethodExecutor/ObjectMethodExecutor.cs
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-using System.Reflection;
-
-// ReSharper disable once CheckNamespace
-namespace Microsoft.Extensions.Internal
-{
- internal class ObjectMethodExecutor
- {
- // ReSharper disable once InconsistentNaming
- private static readonly ConstructorInfo _objectMethodExecutorAwaitableConstructor =
- typeof(ObjectMethodExecutorAwaitable).GetConstructor(new[]
- {
- typeof(object), // customAwaitable
- typeof(Func