Commit 450dd303 by dingsongjie

完善 可靠消息

parent 2bb0a31b
Showing with 702 additions and 104 deletions
......@@ -30,7 +30,7 @@ namespace ServiceA
{
services.AddControllers();
services.AddComteckReliableMessage(option =>
services.AddPoleReliableMessage(option =>
{
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;
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 PoleSample.Apis.Product;
using System;
using System.Collections.Generic;
using System.Linq;
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 long Price { get; set; }
public string ProductId { get; set; }
public string ProductTypeName { get; set; }
public string ProductTypeId { 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
builder.Property(m => m.Id).HasMaxLength(32);
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.HasIndex(m => m.ProductId);
builder.HasIndex(m => m.ProductTypeId);
builder.HasKey(m => m.Id);
}
}
......
......@@ -11,6 +11,8 @@ namespace Product.Api.Infrastructure
{
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)
{
......@@ -21,10 +23,6 @@ namespace Product.Api.Infrastructure
builder.ApplyConfiguration(new ProductEntityTypeEntityTypeConfiguration());
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
b.Property<long>("Price")
.HasColumnType("bigint");
b.Property<string>("ProductId")
b.Property<string>("ProductTypeId")
.IsRequired()
.HasColumnType("character varying(32)")
.HasMaxLength(32);
b.HasKey("Id");
b.HasIndex("ProductId");
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
}
}
......
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<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.Design" Version="3.1.0">
<PrivateAssets>all</PrivateAssets>
......@@ -17,10 +19,13 @@
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.0" />
</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\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>
</Project>
</Project>
\ No newline at end of file
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:21635",
"sslPort": 0
}
},
{
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Product.Api": {
"commandName": "Project",
"launchBrowser": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
}
\ No newline at end of file
......@@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Pole.ReliableMessage.Storage.Mongodb;
using Product.Api.Grpc;
using Product.Api.Infrastructure;
namespace Product.Api
......@@ -19,8 +21,8 @@ namespace Product.Api
private IWebHostEnvironment Environment { get; }
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
this.Configuration = configuration;
this.Environment = env;
Configuration = configuration;
Environment = env;
}
// 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
......@@ -29,7 +31,33 @@ namespace Product.Api
services.AddDbContext<ProductDbContext>(options =>
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.
......@@ -44,9 +72,10 @@ namespace Product.Api
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<ProductTypeService>();
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 @@
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
"Microsoft.Hosting.Lifetime": "Information",
"Grpc": "Information"
}
},
"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"
}
}
......@@ -3,8 +3,33 @@
"LogLevel": {
"Default": "Information",
"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";
import "common/commonCommandResponse.proto";
package poleSample.apis.product;
package newArchitectureLab.apps.product;
// The greeting service definition.
service ProductType {
// Sends a greeting
rpc GetById (GetProductTypeRequest) returns (GetProductTypeResponse);
rpc Add(AddProductTypeRequest) returns (pole.Grpc.ExtraType.CommonCommandResponse);
}
// The request message containing the user's name.
message GetProductTypeRequest {
string id = 1;
}
// The response message containing the greetings.
message GetProductTypeResponse {
message AddProductTypeRequest {
string id = 1;
string name = 2;
}
\ No newline at end of file
}
......@@ -4,18 +4,18 @@ using System.Text;
namespace Pole.Application.Cqrs
{
public class CommandResult
{
public CommandResult(int status,string message)
{
Status = status;
Message = message;
}
public static CommandResult SuccessResult = new CommandResult(1, "操作成功");
/// <summary>
/// 1 Command Success 2 Command Faild ...
/// </summary>
public int Status { get;private set; }
public string Message { get;private set; }
}
//public class CommandResult
//{
// public CommandResult(int status,string message)
// {
// Status = status;
// Message = message;
// }
// public static CommandResult SuccessResult = new CommandResult(1, "操作成功");
// /// <summary>
// /// 1 Command Success 2 Command Faild ...
// /// </summary>
// public int Status { 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;
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;
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 IEnumerable<Assembly> ApplicationAssemblies { get; set; }
......
......@@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Pole.Application.Cqrs;
using Pole.Application.MediatR;
using Pole.Core.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
......@@ -10,29 +11,22 @@ using System.Text;
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;
foreach (var assembly in assemblies)
{
var queriesImplements = assembly.GetTypes().Where(m => typeof(IQueries).IsAssignableFrom(m) && m.IsClass && !m.IsAbstract);
foreach (var queriesImplement in queriesImplements)
{
var queriesService = queriesImplement.GetInterfaces().FirstOrDefault();
options.Services.AddScoped(queriesService, queriesImplement);
}
AddScoped(options, assembly);
AddTransient(options, assembly);
AddSingleton(options, assembly);
}
return options;
}
public static Options AddApplicationAssemblies(this Options options, params Assembly[] assemblies)
{
options.ApplicationAssemblies = assemblies.AsEnumerable();
return options;
}
public static Options AutoInjectionCommandHandlersAndDomainEventHandlers(this Options options, ServiceLifetime lifetime = ServiceLifetime.Scoped)
public static PoleApplicationOptions AutoInjectionCommandHandlersAndDomainEventHandlers(this PoleApplicationOptions options, ServiceLifetime lifetime = ServiceLifetime.Scoped)
{
options.Services.AddMediatR(config =>
{
......@@ -40,5 +34,36 @@ namespace Pole.Application
}, options.ApplicationAssemblies.ToArray());
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.Text;
using MediatR;
using System.Reflection;
using Pole.Application.Cqrs;
using Pole.Application.Cqrs.Internal;
using Microsoft.Extensions.DependencyInjection;
namespace Pole.Application
{
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>();
return services;
......
using System;
using Pole.Domain.UnitOfWork;
using System;
using System.Collections.Generic;
using System.Text;
......@@ -12,6 +13,10 @@ namespace Pole.Domain
Message = message;
}
public static DomainHandleResult SuccessResult = new DomainHandleResult(1, "处理成功");
public static implicit operator DomainHandleResult(CompleteResult completeResult)
{
return new DomainHandleResult(completeResult.Status, completeResult.Message);
}
/// <summary>
/// 1 Success 2 Faild ...
/// </summary>
......
......@@ -7,7 +7,7 @@ using System.Threading.Tasks;
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.Collections.Generic;
using System.Text;
......@@ -11,11 +12,11 @@ namespace Pole.Domain
{
void Update(T entity);
void Delete(T entity);
Task<T> Add(T entity);
void Add(T entity);
Task<T> Get(string id);
IUnitOfWork UnitOfWork { get; }
}
public interface IRepository
public interface IRepository: IScopedDenpendency
{
}
......
......@@ -4,7 +4,7 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Microsoft.Extensions.DependencyInjection
namespace Pole.Domain
{
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 @@
<PackageReference Include="FluentValidation" Version="8.6.0" />
<PackageReference Include="Grpc.AspNetCore" Version="2.26.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pole.Application\Pole.Application.csproj" />
<ProjectReference Include="..\Pole.Domain\Pole.Domain.csproj" />
</ItemGroup>
</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;
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionExtensions
public static class ServiceCollectionValidationExtensions
{
public static IServiceCollection AddGrpcValidation(this IServiceCollection services)
{
......
......@@ -43,11 +43,5 @@ namespace Pole.ReliableMessage
{
return Start(stoppingToken);
}
public override void Dispose()
{
// 等待 10秒 待 消息处理完
_compositeTask?.Wait((int)TimeSpan.FromSeconds(10).TotalMilliseconds);
base.Dispose();
}
}
}
......@@ -14,9 +14,9 @@ using System.Text;
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();
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