@@ -16,32 +16,32 @@ CAP | |||||
这是CAP集在ASP.NET Core 微服务架构中的一个示意图: | 这是CAP集在ASP.NET Core 微服务架构中的一个示意图: | ||||
![](http://images2015.cnblogs.com/blog/250417/201706/250417-20170630143600289-1065294295.png) | |||||
![](http://images2015.cnblogs.com/blog/250417/201707/250417-20170705175827128-1203291469.png) | |||||
> 图中实线部分代表用户代码,虚线部分代表CAP内部实现。 | > 图中实线部分代表用户代码,虚线部分代表CAP内部实现。 | ||||
## Getting Started | ## Getting Started | ||||
### NuGet 暂未发布 | |||||
### NuGet | |||||
你可以运行以下下命令在你的项目中安装 CAP。 | 你可以运行以下下命令在你的项目中安装 CAP。 | ||||
如果你的消息队列使用的是 Kafka 的话,你可以: | 如果你的消息队列使用的是 Kafka 的话,你可以: | ||||
``` | ``` | ||||
PM> Install-Package DotNetCore.CAP.Kafka | |||||
PM> Install-Package DotNetCore.CAP.Kafka -Pre | |||||
``` | ``` | ||||
如果你的消息队列使用的是 RabbitMQ 的话,你可以: | 如果你的消息队列使用的是 RabbitMQ 的话,你可以: | ||||
``` | ``` | ||||
PM> Install-Package DotNetCore.CAP.RabbitMQ | |||||
PM> Install-Package DotNetCore.CAP.RabbitMQ -Pre | |||||
``` | ``` | ||||
CAP 默认提供了 Entity Framwork 作为数据库存储: | CAP 默认提供了 Entity Framwork 作为数据库存储: | ||||
``` | ``` | ||||
PM> Install-Package DotNetCore.CAP.EntityFrameworkCore | |||||
PM> Install-Package DotNetCore.CAP.EntityFrameworkCore -Pre | |||||
``` | ``` | ||||
### Configuration | ### Configuration | ||||
@@ -57,7 +57,7 @@ public void ConfigureServices(IServiceCollection services) | |||||
services.AddCap() | services.AddCap() | ||||
.AddEntityFrameworkStores<AppDbContext>() | .AddEntityFrameworkStores<AppDbContext>() | ||||
.AddKafka(x => x.Servers = "localhost:9453"); | |||||
.AddKafka(x => x.Servers = "localhost:9092"); | |||||
} | } | ||||
public void Configure(IApplicationBuilder app) | public void Configure(IApplicationBuilder app) | ||||
@@ -100,9 +100,7 @@ public class PublishController : Controller | |||||
**Action Method** | **Action Method** | ||||
在Action上添加 Attribute 来订阅相关消息。 | |||||
如果你使用的是 Kafak 则使用 `[KafkaTopic()]`, 如果是 RabbitMQ 则使用 `[RabbitMQTopic()]` | |||||
在 Action 上添加 CapSubscribeAttribute 来订阅相关消息。 | |||||
```cs | ```cs | ||||
public class PublishController : Controller | public class PublishController : Controller | ||||
@@ -116,7 +114,7 @@ public class PublishController : Controller | |||||
[NoAction] | [NoAction] | ||||
[KafkaTopic("xxx.services.account.check")] | |||||
[CapSubscribe("xxx.services.account.check")] | |||||
public async Task CheckReceivedMessage(Person person) | public async Task CheckReceivedMessage(Person person) | ||||
{ | { | ||||
Console.WriteLine(person.Name); | Console.WriteLine(person.Name); | ||||
@@ -129,7 +127,7 @@ public class PublishController : Controller | |||||
**Service Method** | **Service Method** | ||||
如果你的订阅方法没有位于 Controller 中,则你订阅的类需要继承 `IConsumerService`: | |||||
如果你的订阅方法没有位于 Controller 中,则你订阅的类需要继承 `ICapSubscribe`: | |||||
```cs | ```cs | ||||
@@ -141,7 +139,7 @@ namespace xxx.Service | |||||
} | } | ||||
public class SubscriberService: ISubscriberService, IConsumerService | |||||
public class SubscriberService: ISubscriberService, ICapSubscribe | |||||
{ | { | ||||
[KafkaTopic("xxx.services.account.check")] | [KafkaTopic("xxx.services.account.check")] | ||||
public void CheckReceivedMessage(Person person) | public void CheckReceivedMessage(Person person) | ||||
@@ -8,12 +8,12 @@ | |||||
<PropertyGroup Label="Package"> | <PropertyGroup Label="Package"> | ||||
<Product>CAP</Product> | <Product>CAP</Product> | ||||
<Authors>Savorboard;dotnetcore</Authors> | |||||
<Authors>savorboard;dotnetcore</Authors> | |||||
<RepositoryUrl>https://github.com/dotnetcore/CAP</RepositoryUrl> | <RepositoryUrl>https://github.com/dotnetcore/CAP</RepositoryUrl> | ||||
<RepositoryType>git</RepositoryType> | <RepositoryType>git</RepositoryType> | ||||
<PackageIconUrl>https://avatars2.githubusercontent.com/u/19404084</PackageIconUrl> | <PackageIconUrl>https://avatars2.githubusercontent.com/u/19404084</PackageIconUrl> | ||||
<PackageProjectUrl>https://github.com/dotnetcore/CAP</PackageProjectUrl> | <PackageProjectUrl>https://github.com/dotnetcore/CAP</PackageProjectUrl> | ||||
<PackageLicenseUrl>https://github.com/dotnetcore/CAP/blob/master/LICENSE</PackageLicenseUrl> | |||||
<PackageLicenseUrl>https://github.com/dotnetcore/CAP/blob/master/LICENSE.txt</PackageLicenseUrl> | |||||
<PackageTags>aspnetcore;cap;consistency</PackageTags> | <PackageTags>aspnetcore;cap;consistency</PackageTags> | ||||
<Description>Eventually consistency in distributed architectures.</Description> | <Description>Eventually consistency in distributed architectures.</Description> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
@@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Mvc; | |||||
namespace Sample.Kafka.Controllers | namespace Sample.Kafka.Controllers | ||||
{ | { | ||||
[Route("api/[controller]")] | [Route("api/[controller]")] | ||||
public class ValuesController : Controller, IConsumerService | |||||
public class ValuesController : Controller, ICapSubscribe | |||||
{ | { | ||||
private readonly ICapProducerService _producer; | private readonly ICapProducerService _producer; | ||||
@@ -24,7 +24,7 @@ namespace Sample.Kafka.Controllers | |||||
} | } | ||||
public string ServerPath => ((IHostingEnvironment)HttpContext.RequestServices.GetService(typeof(IHostingEnvironment))).ContentRootPath; | public string ServerPath => ((IHostingEnvironment)HttpContext.RequestServices.GetService(typeof(IHostingEnvironment))).ContentRootPath; | ||||
[KafkaTopic("zzwl.topic.finace.callBack", Group = "test")] | |||||
[CapSubscribe("zzwl.topic.finace.callBack", Group = "test")] | |||||
public void KafkaTest(Person person) | public void KafkaTest(Person person) | ||||
{ | { | ||||
Console.WriteLine(person.Name); | Console.WriteLine(person.Name); | ||||
@@ -2,15 +2,21 @@ | |||||
namespace DotNetCore.CAP.Kafka | namespace DotNetCore.CAP.Kafka | ||||
{ | { | ||||
public class KafkaTopicAttribute : TopicAttribute | |||||
public class CapSubscribeAttribute : TopicAttribute | |||||
{ | { | ||||
public KafkaTopicAttribute(string topicName) | |||||
public CapSubscribeAttribute(string topicName) | |||||
: this(topicName, 0) { } | : this(topicName, 0) { } | ||||
public KafkaTopicAttribute(string topicName, int partition) | |||||
/// <summary> | |||||
/// Not support | |||||
/// </summary> | |||||
public CapSubscribeAttribute(string topicName, int partition) | |||||
: this(topicName, partition, 0) { } | : this(topicName, partition, 0) { } | ||||
public KafkaTopicAttribute(string topicName, int partition, long offset) | |||||
/// <summary> | |||||
/// Not support | |||||
/// </summary> | |||||
public CapSubscribeAttribute(string topicName, int partition, long offset) | |||||
: base(topicName) | : base(topicName) | ||||
{ | { | ||||
Offset = offset; | Offset = offset; |
@@ -0,0 +1,12 @@ | |||||
using DotNetCore.CAP.Abstractions; | |||||
namespace DotNetCore.CAP.RabbitMQ | |||||
{ | |||||
public class CapSubscribeAttribute : TopicAttribute | |||||
{ | |||||
public CapSubscribeAttribute(string routingKey) : base(routingKey) | |||||
{ | |||||
} | |||||
} | |||||
} |
@@ -1,11 +0,0 @@ | |||||
using DotNetCore.CAP.Abstractions; | |||||
namespace DotNetCore.CAP.RabbitMQ | |||||
{ | |||||
public class RabbitMQTopicAttribute : TopicAttribute | |||||
{ | |||||
public RabbitMQTopicAttribute(string routingKey) : base(routingKey) | |||||
{ | |||||
} | |||||
} | |||||
} |
@@ -67,9 +67,9 @@ namespace Microsoft.Extensions.DependencyInjection | |||||
foreach (var rejectedServices in services) | foreach (var rejectedServices in services) | ||||
{ | { | ||||
if (rejectedServices.ImplementationType != null | if (rejectedServices.ImplementationType != null | ||||
&& typeof(IConsumerService).IsAssignableFrom(rejectedServices.ImplementationType)) | |||||
&& typeof(ICapSubscribe).IsAssignableFrom(rejectedServices.ImplementationType)) | |||||
consumerListenerServices.Add(typeof(IConsumerService), rejectedServices.ImplementationType); | |||||
consumerListenerServices.Add(typeof(ICapSubscribe), rejectedServices.ImplementationType); | |||||
} | } | ||||
foreach (var service in consumerListenerServices) | foreach (var service in consumerListenerServices) | ||||
@@ -3,7 +3,7 @@ | |||||
/// <summary> | /// <summary> | ||||
/// An empty interface, which is used to mark the current class have a CAP methods. | /// An empty interface, which is used to mark the current class have a CAP methods. | ||||
/// </summary> | /// </summary> | ||||
public interface IConsumerService | |||||
public interface ICapSubscribe | |||||
{ | { | ||||
} | } | ||||
} | } |
@@ -54,11 +54,11 @@ namespace DotNetCore.CAP.Internal | |||||
{ | { | ||||
var executorDescriptorList = new List<ConsumerExecutorDescriptor>(); | var executorDescriptorList = new List<ConsumerExecutorDescriptor>(); | ||||
var consumerServices = provider.GetServices<IConsumerService>(); | |||||
var consumerServices = provider.GetServices<ICapSubscribe>(); | |||||
foreach (var service in consumerServices) | foreach (var service in consumerServices) | ||||
{ | { | ||||
var typeInfo = service.GetType().GetTypeInfo(); | var typeInfo = service.GetType().GetTypeInfo(); | ||||
if (!typeof(IConsumerService).GetTypeInfo().IsAssignableFrom(typeInfo)) | |||||
if (!typeof(ICapSubscribe).GetTypeInfo().IsAssignableFrom(typeInfo)) | |||||
{ | { | ||||
continue; | continue; | ||||
} | } | ||||
@@ -58,7 +58,7 @@ namespace DotNetCore.CAP.Test | |||||
public interface IFooTest { } | public interface IFooTest { } | ||||
public interface IBarTest { } | public interface IBarTest { } | ||||
public class CandidatesFooTest : IFooTest, IConsumerService | |||||
public class CandidatesFooTest : IFooTest, ICapSubscribe | |||||
{ | { | ||||
[CandidatesTopic("Candidates.Foo")] | [CandidatesTopic("Candidates.Foo")] | ||||
public Task GetFoo() | public Task GetFoo() | ||||