Commit 450dd303 by dingsongjie

完善 可靠消息

parent 2bb0a31b
Showing with 702 additions and 104 deletions
...@@ -30,7 +30,7 @@ namespace ServiceA ...@@ -30,7 +30,7 @@ namespace ServiceA
{ {
services.AddControllers(); services.AddControllers();
services.AddComteckReliableMessage(option => services.AddPoleReliableMessage(option =>
{ {
option.AddMasstransitRabbitmq(rabbitoption => option.AddMasstransitRabbitmq(rabbitoption =>
{ {
......
using Pole.Application.Cqrs;
using Pole.Grpc.ExtraType;
using PoleSample.Apis.Product;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Product.Api.Application.Command
{
public class AddProductTypeCommand: ICommand<CommonCommandResponse>
{
public AddProductTypeRequest Request { get; set; }
}
}
using NewArchitectureLab.Apps.Product;
using Pole.Application.Cqrs;
using Pole.Grpc.ExtraType;
using PoleSample.Apis.Product;
using Product.Api.Domain.Event;
using Product.Api.Domain.ProductTypeAggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Product.Api.Application.Command.CommandHandler
{
public class AddProductTypeCommandHandler : ICommandHandler<AddProductTypeCommand, CommonCommandResponse>
{
private readonly IProductTypeRepository _productTypeRepository;
public AddProductTypeCommandHandler(IProductTypeRepository productTypeRepository)
{
_productTypeRepository = productTypeRepository;
}
public async Task<CommonCommandResponse> Handle(AddProductTypeCommand request, CancellationToken cancellationToken)
{
var productType = new Domain.ProductTypeAggregate.ProductType(request.Request.Id, request.Request.Name);
_productTypeRepository.Add(productType);
ProductTypeAddedDomainEvent productTypeAddedDomainEvent = new ProductTypeAddedDomainEvent
{
ProductTypeId = productType.Id,
ProductTypeName = productType.Name
};
productType.AddDomainEvent(productTypeAddedDomainEvent);
return await _productTypeRepository.UnitOfWork.CompeleteAsync();
}
}
}
using Pole.Domain;
using Product.Api.Domain.Event;
using Product.Api.Domain.ProductAggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Product.Api.Application.DomainEventHandler
{
public class AddDefaultProductWhenProductTypeAddedDomainEventHandler : IDomainEventHandler<ProductTypeAddedDomainEvent>
{
private readonly IProductRepository _productRepository;
public AddDefaultProductWhenProductTypeAddedDomainEventHandler(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public async Task<DomainHandleResult> Handle(ProductTypeAddedDomainEvent request, CancellationToken cancellationToken)
{
Product.Api.Domain.ProductAggregate.Product product = new Product.Api.Domain.ProductAggregate.Product(Guid.NewGuid().ToString("N"), request.ProductTypeName, 100, request.ProductTypeId);
_productRepository.Add(product);
return await _productRepository.UnitOfWork.CompeleteAsync();
}
}
}
using Pole.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Product.Api.Domain.ProductAggregate
{
public class Product : Entity, IAggregateRoot
{
public Product(string id ,string name,long price, string productTypeId)
{
Id = id;
Name = name;
Price = price;
ProductTypeId = productTypeId;
}
public string Name { get;private set; }
public long Price { get;private set; }
public string ProductTypeId { get;private set; }
}
}
...@@ -6,8 +6,7 @@ using System.Threading.Tasks; ...@@ -6,8 +6,7 @@ using System.Threading.Tasks;
namespace Product.Api.Domain.ProductTypeAggregate namespace Product.Api.Domain.ProductTypeAggregate
{ {
public class ProductType : Entity, IAggregateRoot public interface IProductTypeRepository:IRepository<ProductType>
{ {
public string Name { get; set; }
} }
} }
using Pole.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Product.Api.Domain.ProductTypeAggregate
{
public class ProductType : Entity, IAggregateRoot
{
public ProductType(string id,string name)
{
Id = id;
Name = name;
}
public string Name { get;private set; }
}
}
using Pole.Domain; using Pole.Domain;
using PoleSample.Apis.Product;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Product.Api.Domain.ProductAggregate namespace Product.Api.Domain.Event
{ {
public class Product : Entity, IAggregateRoot public class ProductTypeAddedDomainEvent: IDomainEvent
{ {
public string Name { get; set; } public string ProductTypeName { get; set; }
public long Price { get; set; } public string ProductTypeId { get; set; }
public string ProductId { get; set; }
} }
} }
using Grpc.Core;
using NewArchitectureLab.Apps.Product;
using Pole.Application.Cqrs;
using Pole.Grpc.ExtraType;
using PoleSample.Apis.Product;
using Product.Api.Application.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Product.Api.Grpc
{
public class ProductTypeService: PoleSample.Apis.Product.ProductType.ProductTypeBase
{
private readonly ICommandBus _commandBus;
public ProductTypeService(ICommandBus commandBus)
{
_commandBus = commandBus;
}
public override Task<CommonCommandResponse> Add(AddProductTypeRequest request, ServerCallContext context)
{
var cpmmand = new AddProductTypeCommand { Request = request };
return _commandBus.Send(cpmmand);
}
}
}
...@@ -15,11 +15,11 @@ namespace Product.Api.Infrastructure.EntityConfigurations ...@@ -15,11 +15,11 @@ namespace Product.Api.Infrastructure.EntityConfigurations
builder.Property(m => m.Id).HasMaxLength(32); builder.Property(m => m.Id).HasMaxLength(32);
builder.Property(m => m.Name).HasMaxLength(256).IsRequired(); builder.Property(m => m.Name).HasMaxLength(256).IsRequired();
builder.Property(m => m.ProductId).HasMaxLength(32).IsRequired(); builder.Property(m => m.ProductTypeId).HasMaxLength(32).IsRequired();
builder.Ignore(m => m.DomainEvents); builder.Ignore(m => m.DomainEvents);
builder.HasIndex(m => m.ProductId); builder.HasIndex(m => m.ProductTypeId);
builder.HasKey(m => m.Id); builder.HasKey(m => m.Id);
} }
} }
......
...@@ -11,6 +11,8 @@ namespace Product.Api.Infrastructure ...@@ -11,6 +11,8 @@ namespace Product.Api.Infrastructure
{ {
public class ProductDbContext : DbContextBase public class ProductDbContext : DbContextBase
{ {
public DbSet<Product.Api.Domain.ProductAggregate.Product> Products { get; set; }
public DbSet<Product.Api.Domain.ProductTypeAggregate.ProductType> ProductTypes { get; set; }
public ProductDbContext(DbContextOptions options, IMediator mediator) : base(options, mediator) public ProductDbContext(DbContextOptions options, IMediator mediator) : base(options, mediator)
{ {
...@@ -21,10 +23,6 @@ namespace Product.Api.Infrastructure ...@@ -21,10 +23,6 @@ namespace Product.Api.Infrastructure
builder.ApplyConfiguration(new ProductEntityTypeEntityTypeConfiguration()); builder.ApplyConfiguration(new ProductEntityTypeEntityTypeConfiguration());
builder.ApplyConfiguration(new ProductTypeEntityTypeConfiguration()); builder.ApplyConfiguration(new ProductTypeEntityTypeConfiguration());
//builder.ApplyConfiguration(new ThinkNestDirectSalesManagerEntityTypeConfiguration());
//builder.ApplyConfiguration(new ThinkNestInDirectSalesManagerEntityTypeConfiguration());
} }
} }
} }
using Pole.Domain.UnitOfWork;
using Product.Api.Domain.ProductAggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Product.Api.Infrastructure.Repository
{
public class ProductRepository : IProductRepository
{
private readonly ProductDbContext _productDbContext;
public ProductRepository(ProductDbContext productDbContext)
{
_productDbContext = productDbContext;
}
public IUnitOfWork UnitOfWork => _productDbContext;
public void Add(Domain.ProductAggregate.Product entity)
{
_productDbContext.Products.Add(entity);
}
public void Delete(Domain.ProductAggregate.Product entity)
{
throw new NotImplementedException();
}
public Task<Domain.ProductAggregate.Product> Get(string id)
{
throw new NotImplementedException();
}
public void Update(Domain.ProductAggregate.Product entity)
{
throw new NotImplementedException();
}
}
}
using Pole.Domain.UnitOfWork;
using Product.Api.Domain.ProductTypeAggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Product.Api.Infrastructure.Repository
{
public class ProductTypeRepository : IProductTypeRepository
{
private readonly ProductDbContext _productDbContext;
public ProductTypeRepository(ProductDbContext productDbContext)
{
_productDbContext = productDbContext;
}
public IUnitOfWork UnitOfWork => _productDbContext;
public void Add(ProductType entity)
{
_productDbContext.ProductTypes.Add(entity);
}
public void Delete(ProductType entity)
{
throw new NotImplementedException();
}
public Task<ProductType> Get(string id)
{
throw new NotImplementedException();
}
public void Update(ProductType entity)
{
throw new NotImplementedException();
}
}
}
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Product.Api.Infrastructure;
namespace Product.Api.Migrations
{
[DbContext(typeof(ProductDbContext))]
[Migration("20200114090656_Add_Product")]
partial class Add_Product
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("Product.Api.Domain.ProductAggregate.Product", b =>
{
b.Property<string>("Id")
.HasColumnType("character varying(32)")
.HasMaxLength(32);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(256)")
.HasMaxLength(256);
b.Property<long>("Price")
.HasColumnType("bigint");
b.Property<string>("ProductTypeId")
.IsRequired()
.HasColumnType("character varying(32)")
.HasMaxLength(32);
b.HasKey("Id");
b.HasIndex("ProductTypeId");
b.ToTable("Product");
});
modelBuilder.Entity("Product.Api.Domain.ProductTypeAggregate.ProductType", b =>
{
b.Property<string>("Id")
.HasColumnType("character varying(32)")
.HasMaxLength(32);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.ToTable("ProductType");
});
#pragma warning restore 612, 618
}
}
}
using Microsoft.EntityFrameworkCore.Migrations;
namespace Product.Api.Migrations
{
public partial class Add_Product : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_Product_ProductId",
table: "Product");
migrationBuilder.DropColumn(
name: "ProductId",
table: "Product");
migrationBuilder.AddColumn<string>(
name: "ProductTypeId",
table: "Product",
maxLength: 32,
nullable: false,
defaultValue: "");
migrationBuilder.CreateTable(
name: "ProductType",
columns: table => new
{
Id = table.Column<string>(maxLength: 32, nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ProductType", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_Product_ProductTypeId",
table: "Product",
column: "ProductTypeId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ProductType");
migrationBuilder.DropIndex(
name: "IX_Product_ProductTypeId",
table: "Product");
migrationBuilder.DropColumn(
name: "ProductTypeId",
table: "Product");
migrationBuilder.AddColumn<string>(
name: "ProductId",
table: "Product",
type: "character varying(32)",
maxLength: 32,
nullable: false,
defaultValue: "");
migrationBuilder.CreateIndex(
name: "IX_Product_ProductId",
table: "Product",
column: "ProductId");
}
}
}
...@@ -32,17 +32,33 @@ namespace Product.Api.Migrations ...@@ -32,17 +32,33 @@ namespace Product.Api.Migrations
b.Property<long>("Price") b.Property<long>("Price")
.HasColumnType("bigint"); .HasColumnType("bigint");
b.Property<string>("ProductId") b.Property<string>("ProductTypeId")
.IsRequired() .IsRequired()
.HasColumnType("character varying(32)") .HasColumnType("character varying(32)")
.HasMaxLength(32); .HasMaxLength(32);
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("ProductId"); b.HasIndex("ProductTypeId");
b.ToTable("Product"); b.ToTable("Product");
}); });
modelBuilder.Entity("Product.Api.Domain.ProductTypeAggregate.ProductType", b =>
{
b.Property<string>("Id")
.HasColumnType("character varying(32)")
.HasMaxLength(32);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.ToTable("ProductType");
});
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }
......
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Protobuf Include="..\..\proto\service\Product\*.proto" AdditionalImportDirs="..\..\proto" GrpcServices="Server" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.26.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.0"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.0">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
...@@ -17,10 +19,13 @@ ...@@ -17,10 +19,13 @@
</PackageReference> </PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.0" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\src\Pole.Application\Pole.Application.csproj" />
<ProjectReference Include="..\..\..\src\Pole.Domain.EntityframeworkCore\Pole.Domain.EntityframeworkCore.csproj" /> <ProjectReference Include="..\..\..\src\Pole.Domain.EntityframeworkCore\Pole.Domain.EntityframeworkCore.csproj" />
<ProjectReference Include="..\..\..\src\Pole.Domain\Pole.Domain.csproj" /> <ProjectReference Include="..\..\..\src\Pole.Domain\Pole.Domain.csproj" />
<ProjectReference Include="..\..\..\src\Pole.Grpc\Pole.Grpc.csproj" />
<ProjectReference Include="..\..\..\src\Pole.ReliableMessage.Masstransit\Pole.ReliableMessage.Masstransit.csproj" />
<ProjectReference Include="..\..\..\src\Pole.ReliableMessage.Storage.Mongodb\Pole.ReliableMessage.Storage.Mongodb.csproj" />
<ProjectReference Include="..\..\..\src\Pole.ReliableMessage\Pole.ReliableMessage.csproj" />
</ItemGroup> </ItemGroup>
</Project>
</Project> \ No newline at end of file
{ {
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:21635",
"sslPort": 0
}
},
"profiles": { "profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Product.Api": { "Product.Api": {
"commandName": "Project", "commandName": "Project",
"launchBrowser": true, "launchBrowser": false,
"applicationUrl": "http://localhost:5000", "applicationUrl": "http://localhost:5000",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }
} }
} }
} }
\ No newline at end of file
...@@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore; ...@@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Pole.ReliableMessage.Storage.Mongodb;
using Product.Api.Grpc;
using Product.Api.Infrastructure; using Product.Api.Infrastructure;
namespace Product.Api namespace Product.Api
...@@ -19,8 +21,8 @@ namespace Product.Api ...@@ -19,8 +21,8 @@ namespace Product.Api
private IWebHostEnvironment Environment { get; } private IWebHostEnvironment Environment { get; }
public Startup(IConfiguration configuration, IWebHostEnvironment env) public Startup(IConfiguration configuration, IWebHostEnvironment env)
{ {
this.Configuration = configuration; Configuration = configuration;
this.Environment = env; Environment = env;
} }
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
...@@ -29,7 +31,33 @@ namespace Product.Api ...@@ -29,7 +31,33 @@ namespace Product.Api
services.AddDbContext<ProductDbContext>(options => services.AddDbContext<ProductDbContext>(options =>
options.UseNpgsql(Configuration["postgres:main"])); options.UseNpgsql(Configuration["postgres:main"]));
services.AddPoleDomain(); services.AddGrpc(option=> {
if (Environment.IsDevelopment())
{
option.EnableDetailedErrors = true;
}
});
services.AddPoleGrpc(this.GetType().Assembly);
services.AddPoleReliableMessage(option =>
{
option.AddMasstransitRabbitmq(rabbitoption =>
{
rabbitoption.RabbitMqHostAddress = Configuration["RabbitmqConfig:HostAddress"];
rabbitoption.RabbitMqHostUserName = Configuration["RabbitmqConfig:HostUserName"];
rabbitoption.RabbitMqHostPassword = Configuration["RabbitmqConfig:HostPassword"];
rabbitoption.QueueNamePrefix = Configuration["ServiceName"];
});
option.AddMongodb(mongodbOption =>
{
mongodbOption.ServiceCollectionName = Configuration["ServiceName"];
mongodbOption.Servers = Configuration.GetSection("MongoConfig:Servers").Get<MongoHost[]>();
});
option.AddEventAssemblies(typeof(Startup).Assembly)
.AddEventHandlerAssemblies(typeof(Startup).Assembly);
option.NetworkInterfaceGatewayAddress = Configuration["ReliableMessageOption:NetworkInterfaceGatewayAddress"];
});
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
...@@ -44,9 +72,10 @@ namespace Product.Api ...@@ -44,9 +72,10 @@ namespace Product.Api
app.UseEndpoints(endpoints => app.UseEndpoints(endpoints =>
{ {
endpoints.MapGrpcService<ProductTypeService>();
endpoints.MapGet("/", async context => endpoints.MapGet("/", async context =>
{ {
await context.Response.WriteAsync("Hello World!"); await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
}); });
}); });
} }
......
...@@ -3,10 +3,28 @@ ...@@ -3,10 +3,28 @@
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
"Microsoft": "Warning", "Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information" "Microsoft.Hosting.Lifetime": "Information",
"Grpc": "Information"
} }
}, },
"postgres": { "postgres": {
"main": "Server=192.168.0.248;Port=5432;Username=postgres;Password=comteck2020!@#;Database=Pole_samples_Product;Enlist=True;Timeout=0;Command Timeout=600;Pooling=false;MinPoolSize=20;MaxPoolSize=500;" "main": "Server=192.168.0.248;Port=5432;Username=postgres;Password=comteck2020!@#;Database=Pole_samples_Product;Enlist=True;Timeout=0;Command Timeout=600;Pooling=false;MinPoolSize=20;MaxPoolSize=500;"
},
"ServiceName": "Product",
"RabbitmqConfig": {
"HostAddress": "rabbitmq://192.168.0.248/",
"HostUserName": "comteck",
"HostPassword": "comteck3030"
},
"MongoConfig": {
"Servers": [
{
"Host": "192.168.0.248",
"Port": "27017"
}
]
},
"ReliableMessageOption": {
"NetworkInterfaceGatewayAddress": "192.168.0.1"
} }
} }
...@@ -3,8 +3,33 @@ ...@@ -3,8 +3,33 @@
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
"Microsoft": "Warning", "Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information" "Microsoft.Hosting.Lifetime": "Information",
"Grpc": "Information"
} }
}, },
"AllowedHosts": "*" "postgres": {
"main": "Server=192.168.0.248;Port=5432;Username=postgres;Password=comteck2020!@#;Database=Pole_samples_Product;Enlist=True;Timeout=0;Command Timeout=600;Pooling=false;MinPoolSize=20;MaxPoolSize=500;"
},
"ServiceName": "Product",
"RabbitmqConfig": {
"HostAddress": "rabbitmq://192.168.0.248/",
"HostUserName": "comteck",
"HostPassword": "comteck3030"
},
"MongoConfig": {
"Servers": [
{
"Host": "192.168.0.248",
"Port": "27017"
}
]
},
"ReliableMessageOption": {
"NetworkInterfaceGatewayAddress": "192.168.0.1"
},
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
}
}
} }
syntax = "proto3";
package pole.Grpc.ExtraType;
message CommonCommandResponse {
// 1 成功 2 失败
int32 status = 1;
string message = 2;
}
\ No newline at end of file
syntax = "proto3"; syntax = "proto3";
import "common/commonCommandResponse.proto";
package poleSample.apis.product;
package newArchitectureLab.apps.product;
// The greeting service definition. // The greeting service definition.
service ProductType { service ProductType {
// Sends a greeting // Sends a greeting
rpc GetById (GetProductTypeRequest) returns (GetProductTypeResponse); rpc Add(AddProductTypeRequest) returns (pole.Grpc.ExtraType.CommonCommandResponse);
} }
// The request message containing the user's name. // The request message containing the user's name.
message GetProductTypeRequest { message AddProductTypeRequest {
string id = 1;
}
// The response message containing the greetings.
message GetProductTypeResponse {
string id = 1; string id = 1;
string name = 2; string name = 2;
} }
\ No newline at end of file
...@@ -4,18 +4,18 @@ using System.Text; ...@@ -4,18 +4,18 @@ using System.Text;
namespace Pole.Application.Cqrs namespace Pole.Application.Cqrs
{ {
public class CommandResult //public class CommandResult
{ //{
public CommandResult(int status,string message) // public CommandResult(int status,string message)
{ // {
Status = status; // Status = status;
Message = message; // Message = message;
} // }
public static CommandResult SuccessResult = new CommandResult(1, "操作成功"); // public static CommandResult SuccessResult = new CommandResult(1, "操作成功");
/// <summary> // /// <summary>
/// 1 Command Success 2 Command Faild ... // /// 1 Command Success 2 Command Faild ...
/// </summary> // /// </summary>
public int Status { get;private set; } // public int Status { get;private set; }
public string Message { get;private set; } // public string Message { get;private set; }
} //}
} }
using MediatR;
using System;
using System.Collections.Generic;
using System.Text;
namespace Pole.Application.Cqrs
{
public interface ICommand<TResponse>:IRequest<TResponse>
{
}
}
...@@ -5,7 +5,7 @@ using System.Text; ...@@ -5,7 +5,7 @@ using System.Text;
namespace Pole.Application.Cqrs namespace Pole.Application.Cqrs
{ {
public interface ICommandHandler<TCommand,TResult>: IRequestHandler<TCommand, TResult> where TCommand : IRequest<TResult> public interface ICommandHandler<TCommand,TResult>: IRequestHandler<TCommand, TResult> where TCommand : ICommand<TResult>
{ {
} }
} }
...@@ -6,8 +6,13 @@ using System.Text; ...@@ -6,8 +6,13 @@ using System.Text;
namespace Pole.Application namespace Pole.Application
{ {
public class Options public class PoleApplicationOptions
{ {
public PoleApplicationOptions(IServiceCollection services, params Assembly [] applicationAssemblies)
{
Services = services;
ApplicationAssemblies = applicationAssemblies;
}
public IServiceCollection Services { get; set; } public IServiceCollection Services { get; set; }
public IEnumerable<Assembly> ApplicationAssemblies { get; set; } public IEnumerable<Assembly> ApplicationAssemblies { get; set; }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Pole.Application.Cqrs; using Pole.Application.Cqrs;
using Pole.Application.MediatR; using Pole.Application.MediatR;
using Pole.Core.DependencyInjection;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
...@@ -10,29 +11,22 @@ using System.Text; ...@@ -10,29 +11,22 @@ using System.Text;
namespace Pole.Application namespace Pole.Application
{ {
public static class OptionsExtensions public static class PoleApplicationOptionsExtensions
{ {
public static Options AutoInjectionQueries(this Options options) public static PoleApplicationOptions AutoInjectionDependency(this PoleApplicationOptions options)
{ {
var assemblies = options.ApplicationAssemblies; var assemblies = options.ApplicationAssemblies;
foreach (var assembly in assemblies) foreach (var assembly in assemblies)
{ {
var queriesImplements = assembly.GetTypes().Where(m => typeof(IQueries).IsAssignableFrom(m) && m.IsClass && !m.IsAbstract); AddScoped(options, assembly);
foreach (var queriesImplement in queriesImplements) AddTransient(options, assembly);
{ AddSingleton(options, assembly);
var queriesService = queriesImplement.GetInterfaces().FirstOrDefault();
options.Services.AddScoped(queriesService, queriesImplement);
}
} }
return options; return options;
} }
public static Options AddApplicationAssemblies(this Options options, params Assembly[] assemblies)
{ public static PoleApplicationOptions AutoInjectionCommandHandlersAndDomainEventHandlers(this PoleApplicationOptions options, ServiceLifetime lifetime = ServiceLifetime.Scoped)
options.ApplicationAssemblies = assemblies.AsEnumerable();
return options;
}
public static Options AutoInjectionCommandHandlersAndDomainEventHandlers(this Options options, ServiceLifetime lifetime = ServiceLifetime.Scoped)
{ {
options.Services.AddMediatR(config => options.Services.AddMediatR(config =>
{ {
...@@ -40,5 +34,36 @@ namespace Pole.Application ...@@ -40,5 +34,36 @@ namespace Pole.Application
}, options.ApplicationAssemblies.ToArray()); }, options.ApplicationAssemblies.ToArray());
return options; return options;
} }
private static void AddScoped(PoleApplicationOptions options, Assembly assembly)
{
var queriesImplements = assembly.GetTypes().Where(m => typeof(IScopedDenpendency).IsAssignableFrom(m) && m.IsClass && !m.IsAbstract);
foreach (var queriesImplement in queriesImplements)
{
var queriesService = queriesImplement.GetInterfaces().FirstOrDefault();
options.Services.AddScoped(queriesService, queriesImplement);
}
}
private static void AddTransient(PoleApplicationOptions options, Assembly assembly)
{
var queriesImplements = assembly.GetTypes().Where(m => typeof(ITransientDependency).IsAssignableFrom(m) && m.IsClass && !m.IsAbstract);
foreach (var queriesImplement in queriesImplements)
{
var queriesService = queriesImplement.GetInterfaces().FirstOrDefault();
options.Services.AddTransient(queriesService, queriesImplement);
}
}
private static void AddSingleton(PoleApplicationOptions options, Assembly assembly)
{
var queriesImplements = assembly.GetTypes().Where(m => typeof(ISingleDependency).IsAssignableFrom(m) && m.IsClass && !m.IsAbstract);
foreach (var queriesImplement in queriesImplements)
{
var queriesService = queriesImplement.GetInterfaces().FirstOrDefault();
options.Services.AddSingleton(queriesService, queriesImplement);
}
}
} }
} }
using Microsoft.Extensions.DependencyInjection; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using MediatR; using MediatR;
using System.Reflection; using System.Reflection;
using Pole.Application.Cqrs; using Pole.Application.Cqrs;
using Pole.Application.Cqrs.Internal; using Pole.Application.Cqrs.Internal;
using Microsoft.Extensions.DependencyInjection;
namespace Pole.Application namespace Pole.Application
{ {
public static class ServiceCollectionExtensions public static class ServiceCollectionExtensions
{ {
public static IServiceCollection AddPoleApplication(this IServiceCollection services, Options options) public static IServiceCollection AddPoleApplication(this IServiceCollection services, Action<PoleApplicationOptions> config, params Assembly[] assemblies)
{ {
PoleApplicationOptions poleApplicationOptions = new PoleApplicationOptions(services, assemblies);
config(poleApplicationOptions);
services.AddScoped<ICommandBus, DefaultCommandBus>(); services.AddScoped<ICommandBus, DefaultCommandBus>();
return services; return services;
......
using System; using Pole.Domain.UnitOfWork;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
...@@ -12,6 +13,10 @@ namespace Pole.Domain ...@@ -12,6 +13,10 @@ namespace Pole.Domain
Message = message; Message = message;
} }
public static DomainHandleResult SuccessResult = new DomainHandleResult(1, "处理成功"); public static DomainHandleResult SuccessResult = new DomainHandleResult(1, "处理成功");
public static implicit operator DomainHandleResult(CompleteResult completeResult)
{
return new DomainHandleResult(completeResult.Status, completeResult.Message);
}
/// <summary> /// <summary>
/// 1 Success 2 Faild ... /// 1 Success 2 Faild ...
/// </summary> /// </summary>
......
...@@ -7,7 +7,7 @@ using System.Threading.Tasks; ...@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace Pole.Domain namespace Pole.Domain
{ {
public interface IDomainEventHandler<TCommand, TResult> : IRequestHandler<TCommand, TResult> where TCommand : IRequest<TResult> public interface IDomainEventHandler<TCommand> : IRequestHandler<TCommand, DomainHandleResult> where TCommand : IRequest<DomainHandleResult>
{ {
} }
......
using Pole.Domain.UnitOfWork; using Pole.Core.DependencyInjection;
using Pole.Domain.UnitOfWork;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
...@@ -11,11 +12,11 @@ namespace Pole.Domain ...@@ -11,11 +12,11 @@ namespace Pole.Domain
{ {
void Update(T entity); void Update(T entity);
void Delete(T entity); void Delete(T entity);
Task<T> Add(T entity); void Add(T entity);
Task<T> Get(string id); Task<T> Get(string id);
IUnitOfWork UnitOfWork { get; } IUnitOfWork UnitOfWork { get; }
} }
public interface IRepository public interface IRepository: IScopedDenpendency
{ {
} }
......
...@@ -4,7 +4,7 @@ using System; ...@@ -4,7 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace Microsoft.Extensions.DependencyInjection namespace Pole.Domain
{ {
public static class ServiceCollectionExtensions public static class ServiceCollectionExtensions
{ {
......
using Pole.Application.Cqrs;
using Pole.Domain;
using Pole.Domain.UnitOfWork;
using System;
using System.Collections.Generic;
using System.Text;
namespace Pole.Grpc.ExtraType
{
public partial class CommonCommandResponse
{
public static implicit operator CommonCommandResponse(CompleteResult domainHandleResult)
{
return new CompleteResult(domainHandleResult.Status, domainHandleResult.Message);
}
}
}
syntax = "proto3";
package pole.Grpc.ExtraType;
message CommonCommandResponse {
// 1 成功 2 失败
int32 status = 1;
string message = 2;
}
\ No newline at end of file
...@@ -11,4 +11,9 @@ ...@@ -11,4 +11,9 @@
<PackageReference Include="FluentValidation" Version="8.6.0" /> <PackageReference Include="FluentValidation" Version="8.6.0" />
<PackageReference Include="Grpc.AspNetCore" Version="2.26.0" /> <PackageReference Include="Grpc.AspNetCore" Version="2.26.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pole.Application\Pole.Application.csproj" />
<ProjectReference Include="..\Pole.Domain\Pole.Domain.csproj" />
</ItemGroup>
</Project> </Project>
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Pole.Grpc
{
public class PoleGrpcOptions
{
public PoleGrpcOptions(IServiceCollection services,params Assembly [] assemblies)
{
Services = services;
ApplicationAssemblies = assemblies.ToList();
AutoInject = true;
}
public IServiceCollection Services { get;private set; }
public IEnumerable<Assembly> ApplicationAssemblies { get; set; }
public bool AutoInject { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pole.Application;
using Pole.Domain;
namespace Pole.Grpc
{
public static class PoleGrpcOptionExtensions
{
public static PoleGrpcOptions AddPoleApplication(this PoleGrpcOptions poleGrpcOptions)
{
poleGrpcOptions.Services.AddPoleApplication(options => {
options.AutoInjectionCommandHandlersAndDomainEventHandlers();
if (poleGrpcOptions.AutoInject)
{
options.AutoInjectionDependency();
}
}, poleGrpcOptions.ApplicationAssemblies.ToArray());
return poleGrpcOptions;
}
public static PoleGrpcOptions AddPoleDomain(this PoleGrpcOptions poleGrpcOptions)
{
poleGrpcOptions.Services.AddPoleDomain();
return poleGrpcOptions;
}
}
}
using Microsoft.Extensions.DependencyInjection;
using Pole.Grpc;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddPoleGrpc(this IServiceCollection services, params Assembly[] assemblies)
{
PoleGrpcOptions poleGrpcOptions = new PoleGrpcOptions(services, assemblies);
poleGrpcOptions.AddPoleApplication();
poleGrpcOptions.AddPoleDomain();
// poleGrpcOptions.Services.AddGrpcValidation();
return services;
}
}
}
...@@ -11,7 +11,7 @@ using System.Text; ...@@ -11,7 +11,7 @@ using System.Text;
namespace Microsoft.Extensions.DependencyInjection namespace Microsoft.Extensions.DependencyInjection
{ {
public static class ServiceCollectionExtensions public static class ServiceCollectionValidationExtensions
{ {
public static IServiceCollection AddGrpcValidation(this IServiceCollection services) public static IServiceCollection AddGrpcValidation(this IServiceCollection services)
{ {
......
...@@ -43,11 +43,5 @@ namespace Pole.ReliableMessage ...@@ -43,11 +43,5 @@ namespace Pole.ReliableMessage
{ {
return Start(stoppingToken); return Start(stoppingToken);
} }
public override void Dispose()
{
// 等待 10秒 待 消息处理完
_compositeTask?.Wait((int)TimeSpan.FromSeconds(10).TotalMilliseconds);
base.Dispose();
}
} }
} }
...@@ -14,9 +14,9 @@ using System.Text; ...@@ -14,9 +14,9 @@ using System.Text;
namespace Microsoft.Extensions.DependencyInjection namespace Microsoft.Extensions.DependencyInjection
{ {
public static class ComteckReliableMessageServiceCollectionExtensions public static class PoleReliableMessageServiceCollectionExtensions
{ {
public static IServiceCollection AddComteckReliableMessage(this IServiceCollection services, Action<ReliableMessageOption> optionConfig) public static IServiceCollection AddPoleReliableMessage(this IServiceCollection services, Action<ReliableMessageOption> optionConfig)
{ {
ReliableMessageOption reliableMessageOption = new ReliableMessageOption(); ReliableMessageOption reliableMessageOption = new ReliableMessageOption();
optionConfig(reliableMessageOption); optionConfig(reliableMessageOption);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment