Browse Source

Merge pull request #64 from colinin/3.0

backlog of enhancements
pull/81/head
cKey 5 years ago
committed by GitHub
parent
commit
b3bc042974
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      aspnet-core/LINGYUN.MicroService.sln
  2. 7
      aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json
  3. 7
      aspnet-core/configuration/admin/LINGYUN.BackendAdminApp.Host/appsettings.Development.json
  4. 7
      aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json
  5. 7
      aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json
  6. 7
      aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json
  7. 12
      aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN.Abp.Domain.Entities.Events.csproj
  8. 10
      aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/AbpDddDomainEntitesEventsModule.cs
  9. 151
      aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/EntityChangeEventHelper.cs
  10. 10
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionSubscriber.cs
  11. 6
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs
  12. 57
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
  13. 50
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs
  14. 5
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs
  15. 10
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationType.cs
  16. 2
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
  17. 11
      aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantCreateEventHandler.cs
  18. 11
      aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantUpdateEventHandler.cs
  19. 11
      aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/TenantStore.cs
  20. 20
      aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/TenantAppService.cs
  21. 30
      aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
  22. 8
      aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
  23. 30
      aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs
  24. 8
      aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj
  25. 38
      aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs
  26. 14
      aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj
  27. 15
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs
  28. 2
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantCreateEventHandler.cs
  29. 8
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj
  30. 37
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs
  31. 29
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs
  32. 8
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj

11
aspnet-core/LINGYUN.MicroService.sln

@ -209,9 +209,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.EntityFrameworkCore", "modules\identityServer\LINGYUN.Abp.IdentityServer.EntityFrameworkCore\LINGYUN.Abp.IdentityServer.EntityFrameworkCore.csproj", "{5D0ED1FC-3A7C-4531-9512-832E73AD9555}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.EntityFrameworkCore", "modules\identityServer\LINGYUN.Abp.IdentityServer.EntityFrameworkCore\LINGYUN.Abp.IdentityServer.EntityFrameworkCore.csproj", "{5D0ED1FC-3A7C-4531-9512-832E73AD9555}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.Domain", "modules\identity\LINGYUN.Abp.Identity.Domain\LINGYUN.Abp.Identity.Domain.csproj", "{2BF7FB73-0C62-4ECF-99F0-0583855D2777}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Domain", "modules\identity\LINGYUN.Abp.Identity.Domain\LINGYUN.Abp.Identity.Domain.csproj", "{2BF7FB73-0C62-4ECF-99F0-0583855D2777}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.EntityFrameworkCore", "modules\identity\LINGYUN.Abp.Identity.EntityFrameworkCore\LINGYUN.Abp.Identity.EntityFrameworkCore.csproj", "{6FE7E243-2D99-4567-8786-6C9283D608EF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.EntityFrameworkCore", "modules\identity\LINGYUN.Abp.Identity.EntityFrameworkCore\LINGYUN.Abp.Identity.EntityFrameworkCore.csproj", "{6FE7E243-2D99-4567-8786-6C9283D608EF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Domain.Entities.Events", "modules\common\LINGYUN.Abp.Domain.Entities.Events\LINGYUN.Abp.Domain.Entities.Events.csproj", "{AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -567,6 +569,10 @@ Global
{6FE7E243-2D99-4567-8786-6C9283D608EF}.Debug|Any CPU.Build.0 = Debug|Any CPU {6FE7E243-2D99-4567-8786-6C9283D608EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6FE7E243-2D99-4567-8786-6C9283D608EF}.Release|Any CPU.ActiveCfg = Release|Any CPU {6FE7E243-2D99-4567-8786-6C9283D608EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FE7E243-2D99-4567-8786-6C9283D608EF}.Release|Any CPU.Build.0 = Release|Any CPU {6FE7E243-2D99-4567-8786-6C9283D608EF}.Release|Any CPU.Build.0 = Release|Any CPU
{AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -674,6 +680,7 @@ Global
{5D0ED1FC-3A7C-4531-9512-832E73AD9555} = {0439B173-F41E-4CE0-A44A-CCB70328F272} {5D0ED1FC-3A7C-4531-9512-832E73AD9555} = {0439B173-F41E-4CE0-A44A-CCB70328F272}
{2BF7FB73-0C62-4ECF-99F0-0583855D2777} = {52B5D4F7-237B-4E0A-A167-68442164F70A} {2BF7FB73-0C62-4ECF-99F0-0583855D2777} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{6FE7E243-2D99-4567-8786-6C9283D608EF} = {52B5D4F7-237B-4E0A-A167-68442164F70A} {6FE7E243-2D99-4567-8786-6C9283D608EF} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

7
aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json

@ -48,9 +48,10 @@
"VirtualHost": "multi.service.test" "VirtualHost": "multi.service.test"
} }
}, },
"RedisCache": { "Redis": {
"ConnectString": "127.0.0.1", "Configuration": "127.0.0.1",
"RedisPrefix": "AuthServer" "InstanceName": "LINGYUN.AbpApplication",
"DefaultDatabase": 10
}, },
"AuthServer": { "AuthServer": {
"Authority": "http://localhost:44385/", "Authority": "http://localhost:44385/",

7
aspnet-core/configuration/admin/LINGYUN.BackendAdminApp.Host/appsettings.Development.json

@ -69,9 +69,10 @@
"VirtualHost": "Name of your RabbitMQ server VirtualHost" "VirtualHost": "Name of your RabbitMQ server VirtualHost"
} }
}, },
"RedisCache": { "Redis": {
"RedisPrefix": "Platform_Test_Cache", "Configuration": "127.0.0.1",
"ConnectString": "127.0.0.1" "InstanceName": "LINGYUN.AbpApplication",
"DefaultDatabase": 10
}, },
"AuthServer": { "AuthServer": {
"Authority": "http://localhost:44385/", "Authority": "http://localhost:44385/",

7
aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json

@ -6,9 +6,10 @@
"AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456"
}, },
"RedisCache": { "Redis": {
"RedisPrefix": "ApiGateway_Test_Cache", "Configuration": "127.0.0.1",
"ConnectString": "127.0.0.1" "InstanceName": "LINGYUN.AbpApplication",
"DefaultDatabase": 10
}, },
"CAP": { "CAP": {
"EventBus": { "EventBus": {

7
aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json

@ -6,9 +6,10 @@
"AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456", "AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456" "AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456"
}, },
"RedisCache": { "Redis": {
"RedisPrefix": "Platform_Test_Cache", "Configuration": "127.0.0.1",
"ConnectString": "127.0.0.1" "InstanceName": "LINGYUN.AbpApplication",
"DefaultDatabase": 10
}, },
"AuthServer": { "AuthServer": {
"Authority": "http://localhost:44385/", "Authority": "http://localhost:44385/",

7
aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json

@ -22,9 +22,10 @@
"VirtualHost": "Name of your RabbitMQ server VirtualHost" "VirtualHost": "Name of your RabbitMQ server VirtualHost"
} }
}, },
"RedisCache": { "Redis": {
"RedisPrefix": "Platform_Test_Cache", "Configuration": "127.0.0.1",
"ConnectString": "127.0.0.1" "InstanceName": "LINGYUN.AbpApplication",
"DefaultDatabase": 10
}, },
"AuthServer": { "AuthServer": {
"Authority": "http://localhost:44385/", "Authority": "http://localhost:44385/",

12
aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN.Abp.Domain.Entities.Events.csproj

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="3.0.0" />
</ItemGroup>
</Project>

10
aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/AbpDddDomainEntitesEventsModule.cs

@ -0,0 +1,10 @@
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Domain.Entities.Events
{
[DependsOn(typeof(AbpDddDomainModule))]
public class AbpDddDomainEntitesEventsModule : AbpModule
{
}
}

151
aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/EntityChangeEventHelper.cs

@ -0,0 +1,151 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.DynamicProxy;
using Volo.Abp.EventBus;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.Domain.Entities.Events
{
[Dependency(Microsoft.Extensions.DependencyInjection.ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IEntityChangeEventHelper), typeof(Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper))]
[Obsolete("the component will be removed when the abp framework is upgraded to 3.1.0")]
public class EntityChangeEventHelper : Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper
{
public EntityChangeEventHelper(
IUnitOfWorkManager unitOfWorkManager,
IEntityToEtoMapper entityToEtoMapper,
IOptions<AbpDistributedEntityEventOptions> distributedEntityEventOptions)
: base(unitOfWorkManager, entityToEtoMapper, distributedEntityEventOptions)
{
}
protected override async Task TriggerEventWithEntity(
IEventBus eventPublisher,
Type genericEventType,
object entityOrEto,
object originalEntity,
bool triggerInCurrentUnitOfWork)
{
var entityType = ProxyHelper.UnProxy(entityOrEto).GetType();
var eventType = genericEventType.MakeGenericType(entityType);
var currentUow = UnitOfWorkManager.Current;
if (triggerInCurrentUnitOfWork || currentUow == null)
{
await eventPublisher.PublishAsync(
eventType,
Activator.CreateInstance(eventType, entityOrEto)
);
return;
}
var eventList = GetEventList(currentUow);
var isFirstEvent = !eventList.Any();
eventList.AddUniqueEvent(eventPublisher, eventType, entityOrEto, originalEntity);
/* Register to OnCompleted if this is the first item.
* Other items will already be in the list once the UOW completes.
*/
if (isFirstEvent)
{
currentUow.OnCompleted(
async () =>
{
foreach (var eventEntry in eventList)
{
try
{
// TODO: abp.io 3.1修复
await eventEntry.EventBus.PublishAsync(
eventEntry.EventType,
Activator.CreateInstance(eventEntry.EventType, eventEntry.EntityOrEto)
);
}
catch (Exception ex)
{
Logger.LogError(
$"Caught an exception while publishing the event '{eventType.FullName}' for the entity '{entityOrEto}'");
Logger.LogException(ex);
}
}
}
);
}
}
private EntityChangeEventList GetEventList(IUnitOfWork currentUow)
{
return (EntityChangeEventList)currentUow.Items.GetOrAdd(
"AbpEntityChangeEventList",
() => new EntityChangeEventList()
);
}
private class EntityChangeEventList : List<EntityChangeEventEntry>
{
public void AddUniqueEvent(IEventBus eventBus, Type eventType, object entityOrEto, object originalEntity)
{
var newEntry = new EntityChangeEventEntry(eventBus, eventType, entityOrEto, originalEntity);
//Latest "same" event overrides the previous events.
for (var i = 0; i < Count; i++)
{
if (this[i].IsSameEvent(newEntry))
{
this[i] = newEntry;
return;
}
}
//If this is a "new" event, add to the end
Add(newEntry);
}
}
private class EntityChangeEventEntry
{
public IEventBus EventBus { get; }
public Type EventType { get; }
public object EntityOrEto { get; }
public object OriginalEntity { get; }
public EntityChangeEventEntry(IEventBus eventBus, Type eventType, object entityOrEto, object originalEntity)
{
EventType = eventType;
EntityOrEto = entityOrEto;
OriginalEntity = originalEntity;
EventBus = eventBus;
}
public bool IsSameEvent(EntityChangeEventEntry otherEntry)
{
if (EventBus != otherEntry.EventBus || EventType != otherEntry.EventType)
{
return false;
}
var originalEntityRef = OriginalEntity as IEntity;
var otherOriginalEntityRef = otherEntry.OriginalEntity as IEntity;
if (originalEntityRef == null || otherOriginalEntityRef == null)
{
return false;
}
return EntityHelper.EntityEquals(originalEntityRef, otherOriginalEntityRef);
}
}
}
}

10
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionSubscriber.cs

@ -24,7 +24,15 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications
var notificationDispatcher = context.ServiceProvider.GetRequiredService<INotificationDispatcher>(); var notificationDispatcher = context.ServiceProvider.GetRequiredService<INotificationDispatcher>();
var notificationName = NotificationNameNormalizer var notificationName = NotificationNameNormalizer
.NormalizerName(AbpExceptionHandlingNotificationNames.NotificationName); .NormalizerName(AbpExceptionHandlingNotificationNames.NotificationName);
var notificationData = new NotificationData(); NotificationData notificationData;
if (CurrentTenant.IsAvailable)
{
notificationData = NotificationData.CreateTenantNotificationData(CurrentTenant.Id.Value);
}
else
{
notificationData = NotificationData.CreateNotificationData();
}
// 写入通知数据 // 写入通知数据
//TODO:集成TextTemplate完成格式化的推送 //TODO:集成TextTemplate完成格式化的推送
notificationData.WriteStandardData( notificationData.WriteStandardData(

6
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs

@ -1,6 +1,5 @@
using LINGYUN.Abp.RealTime.Client; using LINGYUN.Abp.RealTime.Client;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -26,6 +25,11 @@ namespace LINGYUN.Abp.Notifications.SignalR
IOnlineClient onlineClient = CreateClientForCurrentConnection(); IOnlineClient onlineClient = CreateClientForCurrentConnection();
Logger.LogDebug("A client is connected: " + onlineClient.ToString()); Logger.LogDebug("A client is connected: " + onlineClient.ToString());
OnlineClientManager.Add(onlineClient); OnlineClientManager.Add(onlineClient);
if (onlineClient.TenantId.HasValue)
{
// 以租户为分组,将用户加入租户通讯组
await Groups.AddToGroupAsync(onlineClient.ConnectionId, onlineClient.TenantId.Value.ToString());
}
} }
public override async Task OnDisconnectedAsync(Exception exception) public override async Task OnDisconnectedAsync(Exception exception)

57
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs

@ -30,31 +30,48 @@ namespace LINGYUN.Abp.Notifications.SignalR
public override async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers) public override async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers)
{ {
// 返回标准数据给前端 if (notification.Data.HasTenantNotification(out Guid tenantId))
notification.Data = NotificationData.ToStandardData(notification.Data);
foreach (var identifier in identifiers)
{ {
Logger.LogDebug($"Find online client with user {identifier.UserId} - {identifier.UserName}"); // 返回标准数据给前端
var onlineClientContext = new OnlineClientContext(notification.TenantId, identifier.UserId); notification.Data = NotificationData.ToStandardData(notification.Data);
var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext); var singalRGroup = _hubContext.Clients.Group(tenantId.ToString());
foreach (var onlineClient in onlineClients) if (singalRGroup == null)
{ {
try Logger.LogDebug("Can not get group " + tenantId + " from SignalR hub!");
return;
}
// 租户通知群发
Logger.LogDebug($"Found a singalr group, begin senging notifications");
await singalRGroup.SendAsync("getNotification", notification);
}
else
{
// 返回标准数据给前端
notification.Data = NotificationData.ToStandardData(notification.Data);
foreach (var identifier in identifiers)
{
Logger.LogDebug($"Find online client with user {identifier.UserId} - {identifier.UserName}");
var onlineClientContext = new OnlineClientContext(notification.TenantId, identifier.UserId);
var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext);
foreach (var onlineClient in onlineClients)
{ {
Logger.LogDebug($"Find online client {onlineClient.UserId} - {onlineClient.ConnectionId}"); try
var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId);
if (signalRClient == null)
{ {
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!"); Logger.LogDebug($"Find online client {onlineClient.UserId} - {onlineClient.ConnectionId}");
continue; var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId);
if (signalRClient == null)
{
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
continue;
}
Logger.LogDebug($"Found a singalr client, begin senging notifications");
await signalRClient.SendAsync("getNotification", notification);
}
catch (Exception ex)
{
Logger.LogWarning("Could not send notifications to user: {0}", identifier.UserId);
Logger.LogWarning("Send to user notifications error: {0}", ex.Message);
} }
Logger.LogDebug($"Found a singalr client, begin senging notifications");
await signalRClient.SendAsync("getNotification", notification);
}
catch (Exception ex)
{
Logger.LogWarning("Could not send notifications to user: {0}", identifier.UserId);
Logger.LogWarning("Send to user notifications error: {0}", ex.Message);
} }
} }
} }

50
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs

@ -5,6 +5,10 @@ namespace LINGYUN.Abp.Notifications
{ {
public class NotificationData public class NotificationData
{ {
public const string NotificationKey = "N:G";
public const string UserIdNotificationKey = "N:UI";
public const string UserNameNotificationKey = "N:UN";
public const string TenantNotificationKey = "N:T";
public virtual string Type => GetType().FullName; public virtual string Type => GetType().FullName;
public object this[string key] public object this[string key]
@ -45,6 +49,29 @@ namespace LINGYUN.Abp.Notifications
{ {
_properties = new Dictionary<string, object>(); _properties = new Dictionary<string, object>();
} }
public static NotificationData CreateNotificationData()
{
var data = new NotificationData();
data.TrySetData(NotificationKey, "AbpNotification");
return data;
}
public static NotificationData CreateUserNotificationData(Guid userId, string userName)
{
var data = new NotificationData();
data.TrySetData(UserIdNotificationKey, userId);
data.TrySetData(UserNameNotificationKey, userName);
return data;
}
public static NotificationData CreateTenantNotificationData(Guid tenantId)
{
var data = new NotificationData();
data.TrySetData(TenantNotificationKey, tenantId);
return data;
}
/// <summary> /// <summary>
/// 写入标准数据 /// 写入标准数据
/// </summary> /// </summary>
@ -123,5 +150,28 @@ namespace LINGYUN.Abp.Notifications
Properties[key] = value; Properties[key] = value;
} }
} }
public bool HasUserNotification(out Guid userId, out string userName)
{
if (Properties.TryGetValue(UserIdNotificationKey, out object userKey))
{
userId = (Guid)userKey;
var name = TryGetData(UserNameNotificationKey);
userName = name != null ? name.ToString() : "";
return true;
}
userName = "";
return false;
}
public bool HasTenantNotification(out Guid tenantId)
{
if (Properties.TryGetValue(TenantNotificationKey, out object tenantKey))
{
tenantId = (Guid)tenantKey;
return true;
}
return false;
}
} }
} }

5
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs

@ -9,6 +9,11 @@ using Volo.Abp.Localization;
* ,,,Catalog * ,,,Catalog
* Prefix * Prefix
* *
* TODO: 2020-08-26 ?
* 宿,
* NotificationData[FormUser]
* NotificationData[FormTenant]
* NotificationData[FormGlobal]
*/ */
namespace LINGYUN.Abp.Notifications namespace LINGYUN.Abp.Notifications

10
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationType.cs

@ -6,12 +6,16 @@
public enum NotificationType public enum NotificationType
{ {
/// <summary> /// <summary>
/// 应用 /// 应用(对应租户)
/// </summary> /// </summary>
Application = 0, Application = 0,
/// <summary> /// <summary>
/// 系统 /// 系统(对应宿主)
/// </summary> /// </summary>
System = 10 System = 10,
/// <summary>
/// 用户(对应用户)
/// </summary>
User = 20
} }
} }

2
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs

@ -61,7 +61,7 @@ namespace LINGYUN.Abp.MessageService.EventBus
//await _notificationStore.InsertUserSubscriptionAsync(eventData.Entity.TenantId, //await _notificationStore.InsertUserSubscriptionAsync(eventData.Entity.TenantId,
// userIdentifer, UserNotificationNames.WelcomeToApplication); // userIdentifer, UserNotificationNames.WelcomeToApplication);
var userWelcomeNotifictionData = new NotificationData(); var userWelcomeNotifictionData = NotificationData.CreateUserNotificationData(eventData.Entity.Id, eventData.Entity.UserName);
userWelcomeNotifictionData.WriteStandardData( userWelcomeNotifictionData.WriteStandardData(
L("WelcomeToApplicationFormUser", eventData.Entity.Name ?? eventData.Entity.UserName), L("WelcomeToApplicationFormUser", eventData.Entity.Name ?? eventData.Entity.UserName),

11
aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantCreateEventHandler.cs

@ -6,29 +6,30 @@ using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement; using Volo.Abp.TenantManagement;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.MultiTenancy.DbFinder.EventBus.Distributed namespace LINGYUN.Abp.MultiTenancy.DbFinder.EventBus.Distributed
{ {
public class TenantCreateEventHandler : IDistributedEventHandler<EntityCreatedEto<TenantEto>>, ITransientDependency public class TenantCreateEventHandler : IDistributedEventHandler<EntityCreatedEto<TenantEto>>, ITransientDependency
{ {
private readonly IDataFilter _dataFilter; private readonly ICurrentTenant _currentTenant;
private readonly ITenantRepository _tenantRepository; private readonly ITenantRepository _tenantRepository;
private readonly IDistributedCache<TenantConfigurationCacheItem> _cache; private readonly IDistributedCache<TenantConfigurationCacheItem> _cache;
public TenantCreateEventHandler( public TenantCreateEventHandler(
IDataFilter dataFilter, ICurrentTenant currentTenant,
ITenantRepository tenantRepository, ITenantRepository tenantRepository,
IDistributedCache<TenantConfigurationCacheItem> cache) IDistributedCache<TenantConfigurationCacheItem> cache)
{ {
_cache = cache; _cache = cache;
_dataFilter = dataFilter; _currentTenant = currentTenant;
_tenantRepository = tenantRepository; _tenantRepository = tenantRepository;
} }
[UnitOfWork]
public virtual async Task HandleEventAsync(EntityCreatedEto<TenantEto> eventData) public virtual async Task HandleEventAsync(EntityCreatedEto<TenantEto> eventData)
{ {
// 禁用租户过滤器 using (_currentTenant.Change(null))
using (_dataFilter.Disable<IMultiTenant>())
{ {
var tenant = await _tenantRepository.FindAsync(eventData.Entity.Id, true); var tenant = await _tenantRepository.FindAsync(eventData.Entity.Id, true);
if (tenant == null) if (tenant == null)

11
aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantUpdateEventHandler.cs

@ -6,29 +6,30 @@ using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement; using Volo.Abp.TenantManagement;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.MultiTenancy.DbFinder.EventBus.Distributed namespace LINGYUN.Abp.MultiTenancy.DbFinder.EventBus.Distributed
{ {
public class TenantUpdateEventHandler : IDistributedEventHandler<EntityUpdatedEto<TenantEto>>, ITransientDependency public class TenantUpdateEventHandler : IDistributedEventHandler<EntityUpdatedEto<TenantEto>>, ITransientDependency
{ {
private readonly IDataFilter _dataFilter; private readonly ICurrentTenant _currentTenant;
private readonly ITenantRepository _tenantRepository; private readonly ITenantRepository _tenantRepository;
private readonly IDistributedCache<TenantConfigurationCacheItem> _cache; private readonly IDistributedCache<TenantConfigurationCacheItem> _cache;
public TenantUpdateEventHandler( public TenantUpdateEventHandler(
IDataFilter dataFilter, ICurrentTenant currentTenant,
ITenantRepository tenantRepository, ITenantRepository tenantRepository,
IDistributedCache<TenantConfigurationCacheItem> cache) IDistributedCache<TenantConfigurationCacheItem> cache)
{ {
_cache = cache; _cache = cache;
_dataFilter = dataFilter; _currentTenant = currentTenant;
_tenantRepository = tenantRepository; _tenantRepository = tenantRepository;
} }
[UnitOfWork]
public virtual async Task HandleEventAsync(EntityUpdatedEto<TenantEto> eventData) public virtual async Task HandleEventAsync(EntityUpdatedEto<TenantEto> eventData)
{ {
// 禁用租户过滤器 using (_currentTenant.Change(null))
using (_dataFilter.Disable<IMultiTenant>())
{ {
var tenant = await _tenantRepository.FindAsync(eventData.Entity.Id, true); var tenant = await _tenantRepository.FindAsync(eventData.Entity.Id, true);
if (tenant == null) if (tenant == null)

11
aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/TenantStore.cs

@ -19,16 +19,16 @@ namespace LINGYUN.Abp.MultiTenancy.DbFinder
{ {
public ILogger<TenantStore> Logger { protected get; set; } public ILogger<TenantStore> Logger { protected get; set; }
private readonly IDistributedCache<TenantConfigurationCacheItem> _cache; private readonly IDistributedCache<TenantConfigurationCacheItem> _cache;
private readonly IDataFilter _dataFilter; private readonly ICurrentTenant _currentTenant;
private readonly ITenantRepository _tenantRepository; private readonly ITenantRepository _tenantRepository;
public TenantStore( public TenantStore(
IDataFilter dataFilter, ICurrentTenant currentTenant,
ITenantRepository tenantRepository, ITenantRepository tenantRepository,
IDistributedCache<TenantConfigurationCacheItem> cache) IDistributedCache<TenantConfigurationCacheItem> cache)
{ {
_cache = cache; _cache = cache;
_dataFilter = dataFilter; _currentTenant = currentTenant;
_tenantRepository = tenantRepository; _tenantRepository = tenantRepository;
Logger = NullLogger<TenantStore>.Instance; Logger = NullLogger<TenantStore>.Instance;
@ -91,8 +91,7 @@ namespace LINGYUN.Abp.MultiTenancy.DbFinder
} }
Logger.LogDebug($"Not found in the cache, getting from the repository: {cacheKey}"); Logger.LogDebug($"Not found in the cache, getting from the repository: {cacheKey}");
// 禁用租户过滤器 using (_currentTenant.Change(null))
using (_dataFilter.Disable<IMultiTenant>())
{ {
var tenant = await _tenantRepository.FindAsync(id, true); var tenant = await _tenantRepository.FindAsync(id, true);
if (tenant == null) if (tenant == null)
@ -129,7 +128,7 @@ namespace LINGYUN.Abp.MultiTenancy.DbFinder
} }
Logger.LogDebug($"Not found in the cache, getting from the repository: {cacheKey}"); Logger.LogDebug($"Not found in the cache, getting from the repository: {cacheKey}");
using (_dataFilter.Disable<IMultiTenant>()) using (_currentTenant.Change(null))
{ {
var tenant = await _tenantRepository.FindByNameAsync(name); var tenant = await _tenantRepository.FindByNameAsync(name);
if (tenant == null) if (tenant == null)

20
aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/TenantAppService.cs

@ -146,7 +146,16 @@ namespace LINGYUN.Abp.TenantManagement
{ {
var tenant = await TenantRepository.GetAsync(id); var tenant = await TenantRepository.GetAsync(id);
tenant.SetConnectionString(tenantConnectionStringCreateOrUpdate.Name, tenantConnectionStringCreateOrUpdate.Value); tenant.SetConnectionString(tenantConnectionStringCreateOrUpdate.Name, tenantConnectionStringCreateOrUpdate.Value);
var updateEventData = new UpdateEventData
{
Id = tenant.Id,
OriginName = tenant.Name,
Name = tenant.Name
};
// abp当前版本(3.0.0)在EntityChangeEventHelper中存在一个问题,无法发送框架默认的Eto,预计3.1.0修复
// 发送自定义的事件数据来确保缓存被更新
await EventBus.PublishAsync(updateEventData);
return new TenantConnectionStringDto return new TenantConnectionStringDto
{ {
Name = tenantConnectionStringCreateOrUpdate.Name, Name = tenantConnectionStringCreateOrUpdate.Name,
@ -160,6 +169,15 @@ namespace LINGYUN.Abp.TenantManagement
var tenant = await TenantRepository.GetAsync(tenantConnectionGetByName.Id); var tenant = await TenantRepository.GetAsync(tenantConnectionGetByName.Id);
tenant.RemoveConnectionString(tenantConnectionGetByName.Name); tenant.RemoveConnectionString(tenantConnectionGetByName.Name);
var updateEventData = new UpdateEventData
{
Id = tenant.Id,
OriginName = tenant.Name,
Name = tenant.Name
};
await EventBus.PublishAsync(updateEventData);
await TenantRepository.UpdateAsync(tenant); await TenantRepository.UpdateAsync(tenant);
} }
} }

30
aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs

@ -1,10 +1,13 @@
using DotNetCore.CAP; using DotNetCore.CAP;
using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.IdentityServer; using LINGYUN.Abp.IdentityServer;
using LINGYUN.Abp.MultiTenancy.DbFinder;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -17,6 +20,7 @@ using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL; using Volo.Abp.EntityFrameworkCore.MySQL;
@ -39,6 +43,9 @@ namespace AuthServer.Host
typeof(AbpAutofacModule), typeof(AbpAutofacModule),
typeof(AbpCAPEventBusModule), typeof(AbpCAPEventBusModule),
typeof(AbpIdentityAspNetCoreModule), typeof(AbpIdentityAspNetCoreModule),
typeof(AbpDbFinderMultiTenancyModule),
typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpIdentityServerSmsValidatorModule), typeof(AbpIdentityServerSmsValidatorModule),
typeof(AbpIdentityServerWeChatValidatorModule), typeof(AbpIdentityServerWeChatValidatorModule),
typeof(AbpEntityFrameworkCoreMySQLModule), typeof(AbpEntityFrameworkCoreMySQLModule),
@ -88,13 +95,27 @@ namespace AuthServer.Host
Configure<AbpDistributedCacheOptions>(options => Configure<AbpDistributedCacheOptions>(options =>
{ {
// 最好统一命名,不然某个缓存变动其他应用服务有例外发生
options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天 // 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天 // 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddDays(60);
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
}); });
Configure<RedisCacheOptions>(options =>
{
var redisConfig = ConfigurationOptions.Parse(options.Configuration);
// 单独一个缓存数据库
var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
if (databaseConfig.Exists())
{
redisConfig.DefaultDatabase = databaseConfig.Get<int>();
}
options.ConfigurationOptions = redisConfig;
options.InstanceName = configuration["Redis:InstanceName"];
});
Configure<AbpLocalizationOptions>(options => Configure<AbpLocalizationOptions>(options =>
{ {
options.Languages.Add(new LanguageInfo("en", "en", "English")); options.Languages.Add(new LanguageInfo("en", "en", "English"));
@ -121,13 +142,6 @@ namespace AuthServer.Host
options.IsEnabled = true; options.IsEnabled = true;
}); });
context.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["RedisCache:ConnectString"];
var instanceName = configuration["RedisCache:RedisPrefix"];
options.InstanceName = instanceName.IsNullOrEmpty() ? "MessageService_Cache" : instanceName;
});
if (!hostingEnvironment.IsDevelopment()) if (!hostingEnvironment.IsDevelopment())
{ {
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]); var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);

8
aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj

@ -15,12 +15,12 @@
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" /> <PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" /> <PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.4" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.5" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.4">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" /> <PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" />
<PackageReference Include="Volo.Abp.Identity.AspNetCore" Version="3.0.0" /> <PackageReference Include="Volo.Abp.Identity.AspNetCore" Version="3.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="3.0.0" /> <PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="3.0.0" />
@ -33,9 +33,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Domain.Entities.Events\LINGYUN.Abp.Domain.Entities.Events.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.IdentityServer.WeChatValidator\LINGYUN.Abp.IdentityServer.WeChatValidator.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.IdentityServer.WeChatValidator\LINGYUN.Abp.IdentityServer.WeChatValidator.csproj" />
<ProjectReference Include="..\..\..\modules\identityServer\LINGYUN.Abp.IdentityServer.SmsValidator\LINGYUN.Abp.IdentityServer.SmsValidator.csproj" /> <ProjectReference Include="..\..\..\modules\identityServer\LINGYUN.Abp.IdentityServer.SmsValidator\LINGYUN.Abp.IdentityServer.SmsValidator.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj" /> <ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj" />
</ItemGroup> </ItemGroup>

30
aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs

@ -1,11 +1,13 @@
using DotNetCore.CAP; using DotNetCore.CAP;
using IdentityModel; using IdentityModel;
using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing; using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.FileManagement; using LINGYUN.Abp.FileManagement;
using LINGYUN.Abp.Location.Tencent; using LINGYUN.Abp.Location.Tencent;
using LINGYUN.Abp.MessageService; using LINGYUN.Abp.MessageService;
using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.Abp.SettingManagement; using LINGYUN.Abp.SettingManagement;
using LINGYUN.Abp.TenantManagement; using LINGYUN.Abp.TenantManagement;
using LINGYUN.ApiGateway; using LINGYUN.ApiGateway;
@ -16,6 +18,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -31,10 +34,10 @@ using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL; using Volo.Abp.EntityFrameworkCore.MySQL;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Identity.Localization; using Volo.Abp.Identity.Localization;
using Volo.Abp.IdentityServer.EntityFrameworkCore; using Volo.Abp.IdentityServer.EntityFrameworkCore;
using Volo.Abp.Localization; using Volo.Abp.Localization;
@ -87,6 +90,9 @@ namespace LINGYUN.BackendAdmin
typeof(AbpCAPEventBusModule), typeof(AbpCAPEventBusModule),
typeof(AbpAliyunSmsModule), typeof(AbpAliyunSmsModule),
typeof(AbpTencentLocationModule), typeof(AbpTencentLocationModule),
typeof(AbpDbFinderMultiTenancyModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpAutofacModule) typeof(AbpAutofacModule)
)] )]
public class BackendAdminHostModule : AbpModule public class BackendAdminHostModule : AbpModule
@ -158,12 +164,27 @@ namespace LINGYUN.BackendAdmin
Configure<AbpDistributedCacheOptions>(options => Configure<AbpDistributedCacheOptions>(options =>
{ {
// 最好统一命名,不然某个缓存变动其他应用服务有例外发生
options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天 // 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天 // 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
}); });
Configure<RedisCacheOptions>(options =>
{
var redisConfig = ConfigurationOptions.Parse(options.Configuration);
// 单独一个缓存数据库
var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
if (databaseConfig.Exists())
{
redisConfig.DefaultDatabase = databaseConfig.Get<int>();
}
options.ConfigurationOptions = redisConfig;
options.InstanceName = configuration["Redis:InstanceName"];
});
Configure<AbpVirtualFileSystemOptions>(options => Configure<AbpVirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<BackendAdminHostModule>("LINGYUN.BackendAdmin"); options.FileSets.AddEmbedded<BackendAdminHostModule>("LINGYUN.BackendAdmin");
@ -222,13 +243,6 @@ namespace LINGYUN.BackendAdmin
AbpClaimTypes.Email = JwtClaimTypes.Email; AbpClaimTypes.Email = JwtClaimTypes.Email;
}); });
context.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["RedisCache:ConnectString"];
var instanceName = configuration["RedisCache:RedisPrefix"];
options.InstanceName = instanceName.IsNullOrEmpty() ? "BackendAdmin_Cache" : instanceName;
});
if (!hostingEnvironment.IsDevelopment()) if (!hostingEnvironment.IsDevelopment())
{ {
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]); var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);

8
aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj

@ -26,12 +26,11 @@
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.Dashboard" Version="3.0.4" />
<PackageReference Include="DotNetCore.CAP.MySql" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.MySql" Version="3.0.4" />
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="3.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.5">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.4" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.5" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.4" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" /> <PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" />
@ -40,6 +39,7 @@
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" /> <PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" />
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="3.0.0" /> <PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="3.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="3.0.0" /> <PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="3.0.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" /> <PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" />
@ -60,6 +60,7 @@
<ProjectReference Include="..\..\..\modules\account\LINGYUN.Abp.Account.Application\LINGYUN.Abp.Account.Application.csproj" /> <ProjectReference Include="..\..\..\modules\account\LINGYUN.Abp.Account.Application\LINGYUN.Abp.Account.Application.csproj" />
<ProjectReference Include="..\..\..\modules\account\LINGYUN.Abp.Account.HttpApi\LINGYUN.Abp.Account.HttpApi.csproj" /> <ProjectReference Include="..\..\..\modules\account\LINGYUN.Abp.Account.HttpApi\LINGYUN.Abp.Account.HttpApi.csproj" />
<ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.Application.Contracts\LINGYUN.ApiGateway.Application.Contracts.csproj" /> <ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.Application.Contracts\LINGYUN.ApiGateway.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Domain.Entities.Events\LINGYUN.Abp.Domain.Entities.Events.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" />
<ProjectReference Include="..\..\..\modules\file-management\LINGYUN.Abp.FileManagement.Application.Contracts\LINGYUN.Abp.FileManagement.Application.Contracts.csproj" /> <ProjectReference Include="..\..\..\modules\file-management\LINGYUN.Abp.FileManagement.Application.Contracts\LINGYUN.Abp.FileManagement.Application.Contracts.csproj" />
@ -75,6 +76,7 @@
<ProjectReference Include="..\..\..\modules\platform\LINGYUN.Platform.Application.Contracts\LINGYUN.Platform.Application.Contracts.csproj" /> <ProjectReference Include="..\..\..\modules\platform\LINGYUN.Platform.Application.Contracts\LINGYUN.Platform.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\modules\settings\LINGYUN.Abp.SettingManagement.Application\LINGYUN.Abp.SettingManagement.Application.csproj" /> <ProjectReference Include="..\..\..\modules\settings\LINGYUN.Abp.SettingManagement.Application\LINGYUN.Abp.SettingManagement.Application.csproj" />
<ProjectReference Include="..\..\..\modules\settings\LINGYUN.Abp.SettingManagement.HttpApi\LINGYUN.Abp.SettingManagement.HttpApi.csproj" /> <ProjectReference Include="..\..\..\modules\settings\LINGYUN.Abp.SettingManagement.HttpApi\LINGYUN.Abp.SettingManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.TenantManagement.Application\LINGYUN.Abp.TenantManagement.Application.csproj" /> <ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.TenantManagement.Application\LINGYUN.Abp.TenantManagement.Application.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.TenantManagement.HttpApi\LINGYUN.Abp.TenantManagement.HttpApi.csproj" /> <ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.TenantManagement.HttpApi\LINGYUN.Abp.TenantManagement.HttpApi.csproj" />
</ItemGroup> </ItemGroup>

38
aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs

@ -1,12 +1,15 @@
using DotNetCore.CAP; using DotNetCore.CAP;
using DotNetCore.CAP.Messages; using DotNetCore.CAP.Messages;
using IdentityModel; using IdentityModel;
using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.ApiGateway.EntityFrameworkCore; using LINGYUN.ApiGateway.EntityFrameworkCore;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -18,6 +21,8 @@ using System.Text;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.AutoMapper; using Volo.Abp.AutoMapper;
using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL; using Volo.Abp.EntityFrameworkCore.MySQL;
@ -42,6 +47,9 @@ namespace LINGYUN.ApiGateway
typeof(AbpSettingManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpCAPEventBusModule), typeof(AbpCAPEventBusModule),
typeof(AbpDbFinderMultiTenancyModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpAutofacModule) typeof(AbpAutofacModule)
)] )]
public class ApiGatewayHttpApiHostModule : AbpModule public class ApiGatewayHttpApiHostModule : AbpModule
@ -79,6 +87,29 @@ namespace LINGYUN.ApiGateway
options.DefaultSalt = Encoding.ASCII.GetBytes("sf&5)s3#"); options.DefaultSalt = Encoding.ASCII.GetBytes("sf&5)s3#");
}); });
Configure<AbpDistributedCacheOptions>(options =>
{
// 最好统一命名,不然某个缓存变动其他应用服务有例外发生
options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(60);
});
Configure<RedisCacheOptions>(options =>
{
var redisConfig = ConfigurationOptions.Parse(options.Configuration);
// 单独一个缓存数据库
var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
if (databaseConfig.Exists())
{
redisConfig.DefaultDatabase = databaseConfig.Get<int>();
}
options.ConfigurationOptions = redisConfig;
options.InstanceName = configuration["Redis:InstanceName"];
});
// 多租户 // 多租户
Configure<AbpMultiTenancyOptions>(options => Configure<AbpMultiTenancyOptions>(options =>
{ {
@ -119,13 +150,6 @@ namespace LINGYUN.ApiGateway
AbpClaimTypes.Email = JwtClaimTypes.Email; AbpClaimTypes.Email = JwtClaimTypes.Email;
}); });
context.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["RedisCache:ConnectString"];
var instanceName = configuration["RedisCache:RedisPrefix"];
options.InstanceName = instanceName.IsNullOrEmpty() ? "ApiGateway_Cache" : instanceName;
});
if (!hostingEnvironment.IsDevelopment()) if (!hostingEnvironment.IsDevelopment())
{ {
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]); var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);

14
aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj

@ -11,15 +11,14 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="3.0.3" /> <PackageReference Include="DotNetCore.CAP.Dashboard" Version="3.0.4" />
<PackageReference Include="DotNetCore.CAP.MySql" Version="3.0.3" /> <PackageReference Include="DotNetCore.CAP.MySql" Version="3.0.4" />
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="3.0.3" /> <PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="3.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.5">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.3" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.5" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.3" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" /> <PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" />
@ -28,6 +27,7 @@
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" /> <PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" />
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" /> <PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="3.0.0" /> <PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="3.0.0" />
<PackageReference Include="Volo.Abp.TenantManagement.EntityFrameworkCore" Version="3.0.0" /> <PackageReference Include="Volo.Abp.TenantManagement.EntityFrameworkCore" Version="3.0.0" />
@ -39,7 +39,9 @@
<ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.Application\LINGYUN.ApiGateway.Application.csproj" /> <ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.Application\LINGYUN.ApiGateway.Application.csproj" />
<ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.EntityFrameworkCore\LINGYUN.ApiGateway.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.EntityFrameworkCore\LINGYUN.ApiGateway.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.HttpApi\LINGYUN.ApiGateway.HttpApi.csproj" /> <ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.HttpApi\LINGYUN.ApiGateway.HttpApi.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Domain.Entities.Events\LINGYUN.Abp.Domain.Entities.Events.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

15
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs

@ -39,6 +39,10 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
/// </summary> /// </summary>
protected INotificationStore NotificationStore { get; } protected INotificationStore NotificationStore { get; }
/// <summary> /// <summary>
/// Reference to <see cref="INotificationSubscriptionManager"/>.
/// </summary>
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationPublishProviderManager"/>. /// Reference to <see cref="INotificationPublishProviderManager"/>.
/// </summary> /// </summary>
protected INotificationPublishProviderManager NotificationPublishProviderManager { get; } protected INotificationPublishProviderManager NotificationPublishProviderManager { get; }
@ -50,11 +54,13 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
IBackgroundJobManager backgroundJobManager, IBackgroundJobManager backgroundJobManager,
IOptions<AbpNotificationOptions> options, IOptions<AbpNotificationOptions> options,
INotificationStore notificationStore, INotificationStore notificationStore,
INotificationSubscriptionManager notificationSubscriptionManager,
INotificationPublishProviderManager notificationPublishProviderManager) INotificationPublishProviderManager notificationPublishProviderManager)
{ {
BackgroundJobManager = backgroundJobManager; BackgroundJobManager = backgroundJobManager;
Options = options.Value; Options = options.Value;
NotificationStore = notificationStore; NotificationStore = notificationStore;
NotificationSubscriptionManager = notificationSubscriptionManager;
NotificationPublishProviderManager = notificationPublishProviderManager; NotificationPublishProviderManager = notificationPublishProviderManager;
Logger = NullLogger<NotificationEventHandler>.Instance; Logger = NullLogger<NotificationEventHandler>.Instance;
@ -85,9 +91,16 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
// 持久化通知 // 持久化通知
await NotificationStore.InsertNotificationAsync(notificationInfo); await NotificationStore.InsertNotificationAsync(notificationInfo);
// TODO: 某些情况下,不能直接在服务内订阅消息,目前只能通过将订阅内容放进消息内部,需要重构通知系统设计了
if (notificationInfo.Data.HasUserNotification(out Guid userId, out string userName))
{
await NotificationSubscriptionManager.SubscribeAsync(notificationInfo.TenantId,
new UserIdentifier(userId, userName), notificationInfo.Name);
}
Logger.LogDebug($"Gets a list of user subscriptions {notificationInfo.Name}"); Logger.LogDebug($"Gets a list of user subscriptions {notificationInfo.Name}");
// 获取用户订阅列表 // 获取用户订阅列表
var userSubscriptions = await NotificationStore.GetSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name); var userSubscriptions = await NotificationSubscriptionManager.GetSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name);
Logger.LogDebug($"Persistent user notifications {notificationInfo.Name}"); Logger.LogDebug($"Persistent user notifications {notificationInfo.Name}");
// 持久化用户通知 // 持久化用户通知

2
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantCreateEventHandler.cs

@ -55,7 +55,7 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
// 管理用户订阅租户创建通知 // 管理用户订阅租户创建通知
await NotificationSubscriptionManager.SubscribeAsync(eventData.Id, tenantAdminUserIdentifier, noticeNormalizerName.Name); await NotificationSubscriptionManager.SubscribeAsync(eventData.Id, tenantAdminUserIdentifier, noticeNormalizerName.Name);
var notificationData = new NotificationData(); var notificationData = NotificationData.CreateTenantNotificationData(eventData.Id);
notificationData.WriteStandardData( notificationData.WriteStandardData(
L("NewTenantRegisteredNotificationTitle"), L("NewTenantRegisteredNotificationTitle"),
L("NewTenantRegisteredNotificationMessage", eventData.Name), L("NewTenantRegisteredNotificationMessage", eventData.Name),

8
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj

@ -19,12 +19,11 @@
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.Dashboard" Version="3.0.4" />
<PackageReference Include="DotNetCore.CAP.MySql" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.MySql" Version="3.0.4" />
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="3.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.5">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.4" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.5" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.4" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" /> <PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" />
@ -33,6 +32,7 @@
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" /> <PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" />
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="3.0.0" /> <PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="3.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="3.0.0" /> <PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="3.0.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" /> <PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" />
@ -43,6 +43,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Domain.Entities.Events\LINGYUN.Abp.Domain.Entities.Events.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Notifications\LINGYUN.Abp.ExceptionHandling.Notifications.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Notifications\LINGYUN.Abp.ExceptionHandling.Notifications.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Hangfire.MySqlStorage\LINGYUN.Abp.Hangfire.Storage.MySql.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Hangfire.MySqlStorage\LINGYUN.Abp.Hangfire.Storage.MySql.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.BackgroundJobs.Hangfire\LINGYUN.Abp.BackgroundJobs.Hangfire.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.BackgroundJobs.Hangfire\LINGYUN.Abp.BackgroundJobs.Hangfire.csproj" />
@ -53,6 +54,7 @@
<ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.Application\LINGYUN.Abp.MessageService.Application.csproj" /> <ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.Application\LINGYUN.Abp.MessageService.Application.csproj" />
<ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.EntityFrameworkCore\LINGYUN.Abp.MessageService.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.EntityFrameworkCore\LINGYUN.Abp.MessageService.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.HttpApi\LINGYUN.Abp.MessageService.HttpApi.csproj" /> <ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.HttpApi\LINGYUN.Abp.MessageService.HttpApi.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj" /> <ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj" />
</ItemGroup> </ItemGroup>

37
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs

@ -2,6 +2,7 @@
using Hangfire; using Hangfire;
using IdentityModel; using IdentityModel;
using LINGYUN.Abp.BackgroundJobs.Hangfire; using LINGYUN.Abp.BackgroundJobs.Hangfire;
using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Notifications; using LINGYUN.Abp.ExceptionHandling.Notifications;
@ -10,11 +11,13 @@ using LINGYUN.Abp.IM.SignalR;
using LINGYUN.Abp.MessageService.EntityFrameworkCore; using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using LINGYUN.Abp.MessageService.Localization; using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MessageService.MultiTenancy; using LINGYUN.Abp.MessageService.MultiTenancy;
using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.Abp.Notifications.SignalR; using LINGYUN.Abp.Notifications.SignalR;
using LINGYUN.Abp.Notifications.WeChat.WeApp; using LINGYUN.Abp.Notifications.WeChat.WeApp;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -27,6 +30,7 @@ using Volo.Abp.AspNetCore.Authentication.JwtBearer;
using Volo.Abp.AspNetCore.MultiTenancy; using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -56,6 +60,9 @@ namespace LINGYUN.Abp.MessageService
typeof(AbpCAPEventBusModule), typeof(AbpCAPEventBusModule),
typeof(AbpBackgroundJobsHangfireModule), typeof(AbpBackgroundJobsHangfireModule),
typeof(AbpHangfireMySqlStorageModule), typeof(AbpHangfireMySqlStorageModule),
typeof(AbpDbFinderMultiTenancyModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpAutofacModule) typeof(AbpAutofacModule)
)] )]
public class AbpMessageServiceHttpApiHostModule : AbpModule public class AbpMessageServiceHttpApiHostModule : AbpModule
@ -124,6 +131,29 @@ namespace LINGYUN.Abp.MessageService
options.TenantResolvers.Insert(0, new AuthorizationTenantResolveContributor()); options.TenantResolvers.Insert(0, new AuthorizationTenantResolveContributor());
}); });
Configure<AbpDistributedCacheOptions>(options =>
{
// 最好统一命名,不然某个缓存变动其他应用服务有例外发生
options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
});
Configure<RedisCacheOptions>(options =>
{
var redisConfig = ConfigurationOptions.Parse(options.Configuration);
// 单独一个缓存数据库
var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
if (databaseConfig.Exists())
{
redisConfig.DefaultDatabase = databaseConfig.Get<int>();
}
options.ConfigurationOptions = redisConfig;
options.InstanceName = configuration["Redis:InstanceName"];
});
// Swagger // Swagger
context.Services.AddSwaggerGen( context.Services.AddSwaggerGen(
options => options =>
@ -156,13 +186,6 @@ namespace LINGYUN.Abp.MessageService
AbpClaimTypes.Email = JwtClaimTypes.Email; AbpClaimTypes.Email = JwtClaimTypes.Email;
}); });
context.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["RedisCache:ConnectString"];
var instanceName = configuration["RedisCache:RedisPrefix"];
options.InstanceName = instanceName.IsNullOrEmpty() ? "MessageService_Cache" : instanceName;
});
if (!hostingEnvironment.IsDevelopment()) if (!hostingEnvironment.IsDevelopment())
{ {
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]); var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);

29
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs

@ -1,9 +1,11 @@
using DotNetCore.CAP; using DotNetCore.CAP;
using IdentityModel; using IdentityModel;
using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing; using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.FileManagement; using LINGYUN.Abp.FileManagement;
using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.Abp.Notifications; using LINGYUN.Abp.Notifications;
using LINGYUN.Platform.EntityFrameworkCore; using LINGYUN.Platform.EntityFrameworkCore;
using LINGYUN.Platform.HttpApi; using LINGYUN.Platform.HttpApi;
@ -12,6 +14,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -27,6 +30,7 @@ using Volo.Abp.Autofac;
using Volo.Abp.BlobStoring; using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem; using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -55,6 +59,9 @@ namespace LINGYUN.Platform
typeof(AbpEmailingExceptionHandlingModule), typeof(AbpEmailingExceptionHandlingModule),
typeof(AbpCAPEventBusModule), typeof(AbpCAPEventBusModule),
typeof(AbpBlobStoringFileSystemModule), typeof(AbpBlobStoringFileSystemModule),
typeof(AbpDbFinderMultiTenancyModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpAutofacModule) typeof(AbpAutofacModule)
)] )]
public class AppPlatformHttpApiHostModule : AbpModule public class AppPlatformHttpApiHostModule : AbpModule
@ -129,12 +136,27 @@ namespace LINGYUN.Platform
Configure<AbpDistributedCacheOptions>(options => Configure<AbpDistributedCacheOptions>(options =>
{ {
// 最好统一命名,不然某个缓存变动其他应用服务有例外发生
options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天 // 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30); options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天 // 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
}); });
Configure<RedisCacheOptions>(options =>
{
var redisConfig = ConfigurationOptions.Parse(options.Configuration);
// 单独一个缓存数据库
var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
if (databaseConfig.Exists())
{
redisConfig.DefaultDatabase = databaseConfig.Get<int>();
}
options.ConfigurationOptions = redisConfig;
options.InstanceName = configuration["Redis:InstanceName"];
});
Configure<AbpVirtualFileSystemOptions>(options => Configure<AbpVirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<AppPlatformHttpApiHostModule>("LINGYUN.Platform"); options.FileSets.AddEmbedded<AppPlatformHttpApiHostModule>("LINGYUN.Platform");
@ -190,13 +212,6 @@ namespace LINGYUN.Platform
AbpClaimTypes.Email = JwtClaimTypes.Email; AbpClaimTypes.Email = JwtClaimTypes.Email;
}); });
context.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["RedisCache:ConnectString"];
var instanceName = configuration["RedisCache:RedisPrefix"];
options.InstanceName = instanceName.IsNullOrEmpty() ? "Platform_Cache" : instanceName;
});
if (!hostingEnvironment.IsDevelopment()) if (!hostingEnvironment.IsDevelopment())
{ {
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]); var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);

8
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj

@ -21,12 +21,11 @@
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.Dashboard" Version="3.0.4" />
<PackageReference Include="DotNetCore.CAP.MySql" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.MySql" Version="3.0.4" />
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="3.0.4" /> <PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="3.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.5">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.4" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.5" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.4" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" /> <PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" /> <PackageReference Include="Serilog.Enrichers.Assembly" Version="2.0.0" />
@ -35,6 +34,7 @@
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" /> <PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" />
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="3.0.0" /> <PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="3.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="3.0.0" /> <PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="3.0.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" /> <PackageReference Include="Volo.Abp.Autofac" Version="3.0.0" />
@ -46,6 +46,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Domain.Entities.Events\LINGYUN.Abp.Domain.Entities.Events.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />
@ -54,6 +55,7 @@
<ProjectReference Include="..\..\..\modules\platform\LINGYUN.Platform.Application\LINGYUN.Platform.Application.csproj" /> <ProjectReference Include="..\..\..\modules\platform\LINGYUN.Platform.Application\LINGYUN.Platform.Application.csproj" />
<ProjectReference Include="..\..\..\modules\platform\LINGYUN.Platform.EntityFrameworkCore\LINGYUN.Platform.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\..\modules\platform\LINGYUN.Platform.EntityFrameworkCore\LINGYUN.Platform.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\modules\platform\LINGYUN.Platform.HttpApi\LINGYUN.Platform.HttpApi.csproj" /> <ProjectReference Include="..\..\..\modules\platform\LINGYUN.Platform.HttpApi\LINGYUN.Platform.HttpApi.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

Loading…
Cancel
Save