diff --git a/aspnet-core/Directory.Build.Volo.targets b/aspnet-core/Directory.Build.Volo.targets index c51f5abe..6aa7628c 100644 --- a/aspnet-core/Directory.Build.Volo.targets +++ b/aspnet-core/Directory.Build.Volo.targets @@ -85,8 +85,7 @@ - - + \ No newline at end of file diff --git a/aspnet-core/Lion.AbpPro.sln b/aspnet-core/Lion.AbpPro.sln index 42663cba..c777b7c3 100644 --- a/aspnet-core/Lion.AbpPro.sln +++ b/aspnet-core/Lion.AbpPro.sln @@ -48,10 +48,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{F8A8 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "frameworks", "frameworks", "{CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{9F5676A3-00DC-48B7-93D1-341C39E19BB9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C4AC9352-C9F5-4096-8D73-13638232CFB9}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NotificationManagement", "NotificationManagement", "{EB2B8705-18E7-49E1-A565-93A6DE5570D5}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E28AECBD-2904-477C-9817-C67312330A41}" @@ -114,10 +110,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryM EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{8C1B8C6C-C518-4290-B070-622CCA6004DA}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CAP", "CAP", "{2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.HttpApi.Host", "services\host\Lion.AbpPro.HttpApi.Host\Lion.AbpPro.HttpApi.Host.csproj", "{FB20372D-6C96-4733-9AAC-12522F15CAA6}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{6434E3F2-B352-4B30-839A-88C2BA166D96}" @@ -130,10 +122,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gateways", "gateways", "{5C EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.WebGateway", "gateways\Lion.AbpPro.WebGateway\Lion.AbpPro.WebGateway.csproj", "{D9108313-8D05-4F5F-9AA0-B443EC3374B6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Extension", "frameworks\Extensions\src\Lion.AbpPro.Extension\Lion.AbpPro.Extension.csproj", "{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.CAP", "frameworks\CAP\src\Lion.AbpPro.CAP\Lion.AbpPro.CAP.csproj", "{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileManagement", "FileManagement", "{F604F9BE-CAAB-4D94-8989-22DE4D966C7A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{C188A1F4-9601-42E5-9A0A-B282E13EAC41}" @@ -208,6 +196,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.BasicManagement EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.BasicManagement.HttpApi.Host", "modules\BasicManagement\host\Lion.AbpPro.BasicManagement.HttpApi.Host\Lion.AbpPro.BasicManagement.HttpApi.Host.csproj", "{26765303-B9D8-457B-915C-ED869CEEB210}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.Core", "frameworks\src\Lion.AbpPro.Core\Lion.AbpPro.Core.csproj", "{F22611C1-0DAE-408D-B034-7005906536F6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.Localization", "frameworks\src\Lion.AbpPro.Localization\Lion.AbpPro.Localization.csproj", "{EF7D01D6-9F90-4E24-B134-BA13E9965D78}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.CAP", "frameworks\src\Lion.AbpPro.CAP\Lion.AbpPro.CAP.csproj", "{D1A86DB0-DABB-47B6-BC71-C49318AF5534}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7BE85EBC-99AD-4CDE-957E-4BDD087FC4E3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{EFC415F8-872F-4C7E-8645-31A51481BCFC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.Localization.Tests", "frameworks\test\Lion.AbpPro.Localization.Tests\Lion.AbpPro.Localization.Tests.csproj", "{800A02FA-EA70-4492-9A93-13C820692F1D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lion.AbpPro.Core.Tests", "frameworks\test\Lion.AbpPro.Core.Tests\Lion.AbpPro.Core.Tests.csproj", "{A7206D58-8107-4BB9-8962-30C845ACB6DC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -374,14 +376,6 @@ Global {D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Release|Any CPU.Build.0 = Release|Any CPU - {4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Release|Any CPU.Build.0 = Release|Any CPU - {3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Release|Any CPU.Build.0 = Release|Any CPU {866B0894-2B50-484E-BE7E-F221956557F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {866B0894-2B50-484E-BE7E-F221956557F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {866B0894-2B50-484E-BE7E-F221956557F3}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -494,6 +488,26 @@ Global {26765303-B9D8-457B-915C-ED869CEEB210}.Debug|Any CPU.Build.0 = Debug|Any CPU {26765303-B9D8-457B-915C-ED869CEEB210}.Release|Any CPU.ActiveCfg = Release|Any CPU {26765303-B9D8-457B-915C-ED869CEEB210}.Release|Any CPU.Build.0 = Release|Any CPU + {F22611C1-0DAE-408D-B034-7005906536F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F22611C1-0DAE-408D-B034-7005906536F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F22611C1-0DAE-408D-B034-7005906536F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F22611C1-0DAE-408D-B034-7005906536F6}.Release|Any CPU.Build.0 = Release|Any CPU + {EF7D01D6-9F90-4E24-B134-BA13E9965D78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF7D01D6-9F90-4E24-B134-BA13E9965D78}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF7D01D6-9F90-4E24-B134-BA13E9965D78}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF7D01D6-9F90-4E24-B134-BA13E9965D78}.Release|Any CPU.Build.0 = Release|Any CPU + {D1A86DB0-DABB-47B6-BC71-C49318AF5534}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1A86DB0-DABB-47B6-BC71-C49318AF5534}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1A86DB0-DABB-47B6-BC71-C49318AF5534}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1A86DB0-DABB-47B6-BC71-C49318AF5534}.Release|Any CPU.Build.0 = Release|Any CPU + {800A02FA-EA70-4492-9A93-13C820692F1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {800A02FA-EA70-4492-9A93-13C820692F1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {800A02FA-EA70-4492-9A93-13C820692F1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {800A02FA-EA70-4492-9A93-13C820692F1D}.Release|Any CPU.Build.0 = Release|Any CPU + {A7206D58-8107-4BB9-8962-30C845ACB6DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7206D58-8107-4BB9-8962-30C845ACB6DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7206D58-8107-4BB9-8962-30C845ACB6DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7206D58-8107-4BB9-8962-30C845ACB6DC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -514,8 +528,6 @@ Global {E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} {EF480016-9127-4916-8735-D2466BDBC582} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} {AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} - {9F5676A3-00DC-48B7-93D1-341C39E19BB9} = {CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5} - {C4AC9352-C9F5-4096-8D73-13638232CFB9} = {9F5676A3-00DC-48B7-93D1-341C39E19BB9} {EB2B8705-18E7-49E1-A565-93A6DE5570D5} = {F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3} {E28AECBD-2904-477C-9817-C67312330A41} = {EB2B8705-18E7-49E1-A565-93A6DE5570D5} {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} = {EB2B8705-18E7-49E1-A565-93A6DE5570D5} @@ -547,14 +559,10 @@ Global {5AACD0EE-F2B2-49F6-868F-8FE08D7243C0} = {9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} {8D196E3D-6F95-4793-B948-79669AF09017} = {5AACD0EE-F2B2-49F6-868F-8FE08D7243C0} {8C1B8C6C-C518-4290-B070-622CCA6004DA} = {2C861ADD-76E9-4B3B-8A3C-638EBB67D683} - {2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8} = {CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5} - {11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6} = {2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8} {FB20372D-6C96-4733-9AAC-12522F15CAA6} = {8C1B8C6C-C518-4290-B070-622CCA6004DA} {A091AE9B-3A1E-49AC-9AD5-D29310512A3D} = {6434E3F2-B352-4B30-839A-88C2BA166D96} {C018EFF9-579E-43B3-9181-543BE95E2E03} = {6434E3F2-B352-4B30-839A-88C2BA166D96} {D9108313-8D05-4F5F-9AA0-B443EC3374B6} = {5C304CBC-F30D-413C-A0AF-8B6814A2D4A3} - {4C65690E-2C17-46A1-BB35-A51BAB2EA3B7} = {C4AC9352-C9F5-4096-8D73-13638232CFB9} - {3C3FF821-E43D-4D58-8B3C-1E97F4518EF7} = {11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6} {F604F9BE-CAAB-4D94-8989-22DE4D966C7A} = {F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3} {C188A1F4-9601-42E5-9A0A-B282E13EAC41} = {F604F9BE-CAAB-4D94-8989-22DE4D966C7A} {2CC8E555-AA80-4D7A-B606-0821E6754187} = {F604F9BE-CAAB-4D94-8989-22DE4D966C7A} @@ -592,6 +600,13 @@ Global {2BACB63E-2830-4371-AEBB-E8089E3EB316} = {6464122A-1DC2-45E8-B599-4B5C32FBC85B} {19A28EF9-A5AE-4EC5-851C-D2547E5FE29C} = {6464122A-1DC2-45E8-B599-4B5C32FBC85B} {26765303-B9D8-457B-915C-ED869CEEB210} = {4E6D558B-CA6D-4133-8701-FDC6F245DA37} + {7BE85EBC-99AD-4CDE-957E-4BDD087FC4E3} = {CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5} + {D1A86DB0-DABB-47B6-BC71-C49318AF5534} = {7BE85EBC-99AD-4CDE-957E-4BDD087FC4E3} + {F22611C1-0DAE-408D-B034-7005906536F6} = {7BE85EBC-99AD-4CDE-957E-4BDD087FC4E3} + {EF7D01D6-9F90-4E24-B134-BA13E9965D78} = {7BE85EBC-99AD-4CDE-957E-4BDD087FC4E3} + {EFC415F8-872F-4C7E-8645-31A51481BCFC} = {CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5} + {800A02FA-EA70-4492-9A93-13C820692F1D} = {EFC415F8-872F-4C7E-8645-31A51481BCFC} + {A7206D58-8107-4BB9-8962-30C845ACB6DC} = {EFC415F8-872F-4C7E-8645-31A51481BCFC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapConsumerServiceSelector.cs b/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapConsumerServiceSelector.cs deleted file mode 100644 index 55b6f51b..00000000 --- a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapConsumerServiceSelector.cs +++ /dev/null @@ -1,117 +0,0 @@ -namespace Lion.AbpPro.CAP -{ - [Dependency(ServiceLifetime.Singleton, ReplaceServices = true)] - [ExposeServices(typeof(IConsumerServiceSelector))] - public sealed class AbpProAbpCapConsumerServiceSelector : ConsumerServiceSelector - { - private AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; } - private IServiceProvider ServiceProvider { get; } - - /// - /// Creates a new . - /// - public AbpProAbpCapConsumerServiceSelector( - IServiceProvider serviceProvider, - IOptions distributedEventBusOptions) - : base(serviceProvider) - { - ServiceProvider = serviceProvider; - AbpDistributedEventBusOptions = distributedEventBusOptions.Value; - } - - protected override IEnumerable FindConsumersFromInterfaceTypes(IServiceProvider provider) - { - var executorDescriptorList = base.FindConsumersFromInterfaceTypes(provider).ToList(); - - //handlers - var handlers = AbpDistributedEventBusOptions.Handlers; - - foreach (var handler in handlers) - { - var interfaces = handler.GetInterfaces(); - foreach (var @interface in interfaces) - { - if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) - { - continue; - } - var genericArgs = @interface.GetGenericArguments(); - - if (genericArgs.Length != 1) - { - continue; - } - - var descriptors = GetHandlerDescription(genericArgs[0], handler); - - foreach (var descriptor in descriptors) - { - var count = executorDescriptorList.Count(x => - x.Attribute.Name == descriptor.Attribute.Name); - - descriptor.Attribute.Group = descriptor.Attribute.Group.Insert( - descriptor.Attribute.Group.LastIndexOf(".", StringComparison.Ordinal), $".{count}"); - - executorDescriptorList.Add(descriptor); - } - - //Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); - } - } - return executorDescriptorList; - } - - private IEnumerable GetHandlerDescription(Type eventType,Type typeInfo) - { - var serviceTypeInfo = typeof(IDistributedEventHandler<>) - .MakeGenericType(eventType); - var method = typeInfo - .GetMethod( - nameof(IDistributedEventHandler.HandleEventAsync), - new[] { eventType } - ); - var eventName = EventNameAttribute.GetNameOrDefault(eventType); - var topicAttr = method.GetCustomAttributes(true); - var topicAttributes = topicAttr.ToList(); - - if (topicAttributes.Count == 0) - { - topicAttributes.Add(new CapSubscribeAttribute(eventName)); - } - - foreach (var attr in topicAttributes) - { - SetSubscribeAttribute(attr); - - var parameters = method.GetParameters() - .Select(parameter => new ParameterDescriptor - { - Name = parameter.Name, - ParameterType = parameter.ParameterType, - IsFromCap = parameter.GetCustomAttributes(typeof(FromCapAttribute)).Any() - }).ToList(); - - yield return InitDescriptor(attr, method, typeInfo.GetTypeInfo(), serviceTypeInfo.GetTypeInfo(), parameters); - } - } - - private static ConsumerExecutorDescriptor InitDescriptor( - TopicAttribute attr, - MethodInfo methodInfo, - TypeInfo implType, - TypeInfo serviceTypeInfo, - IList parameters) - { - var descriptor = new ConsumerExecutorDescriptor - { - Attribute = attr, - MethodInfo = methodInfo, - ImplTypeInfo = implType, - ServiceTypeInfo = serviceTypeInfo, - Parameters = parameters - }; - - return descriptor; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapDistributedEventBus.cs b/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapDistributedEventBus.cs deleted file mode 100644 index e4511732..00000000 --- a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapDistributedEventBus.cs +++ /dev/null @@ -1,161 +0,0 @@ -namespace Lion.AbpPro.CAP -{ - public class AbpProAbpCapDistributedEventBus : - EventBusBase, - IDistributedEventBus, - ISingletonDependency - { - private AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; } - private ConcurrentDictionary> HandlerFactories { get; } - private ConcurrentDictionary EventTypes { get; } - - private readonly ICapPublisher CapPublisher; - - - public AbpProAbpCapDistributedEventBus(IServiceScopeFactory serviceScopeFactory, - IOptions distributedEventBusOptions, - ICapPublisher capPublisher, - ICurrentTenant currentTenant, - UnitOfWorkManager unitOfWorkManager, - IEventHandlerInvoker eventHandlerInvoker) - : base(serviceScopeFactory, currentTenant,unitOfWorkManager,eventHandlerInvoker) - { - CapPublisher = capPublisher; - AbpDistributedEventBusOptions = distributedEventBusOptions.Value; - HandlerFactories = new ConcurrentDictionary>(); - EventTypes = new ConcurrentDictionary(); - } - - public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) - { - //This is handled by CAP ConsumerServiceSelector - throw new NotImplementedException(); - } - - public override void Unsubscribe(Func action) - { - Check.NotNull(action, nameof(action)); - - GetOrCreateHandlerFactories(typeof(TEvent)) - .Locking(factories => - { - factories.RemoveAll( - factory => - { - var singleInstanceFactory = factory as SingleInstanceHandlerFactory; - if (singleInstanceFactory == null) - { - return false; - } - - var actionHandler = singleInstanceFactory.HandlerInstance as ActionEventHandler; - if (actionHandler == null) - { - return false; - } - - return actionHandler.Action == action; - }); - }); - } - - public override void Unsubscribe(Type eventType, IEventHandler handler) - { - GetOrCreateHandlerFactories(eventType) - .Locking(factories => - { - factories.RemoveAll( - factory => - factory is SingleInstanceHandlerFactory && - (factory as SingleInstanceHandlerFactory).HandlerInstance == handler - ); - }); - } - - public override void Unsubscribe(Type eventType, IEventHandlerFactory factory) - { - GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory)); - } - - public override void UnsubscribeAll(Type eventType) - { - GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear()); - } - - protected override Task PublishToEventBusAsync(Type eventType, object eventData) - { - throw new NotImplementedException(); - } - - protected override void AddToUnitOfWork(IUnitOfWork unitOfWork, UnitOfWorkEventRecord eventRecord) - { - throw new NotImplementedException(); - } - - public IDisposable Subscribe(IDistributedEventHandler handler) where TEvent : class - { - return Subscribe(typeof(TEvent), handler); - } - - public async Task PublishAsync(TEvent eventData, bool onUnitOfWorkComplete = true, - bool useOutbox = true) where TEvent : class - { - var eventName = EventNameAttribute.GetNameOrDefault(typeof(TEvent)); - await CapPublisher.PublishAsync(eventName, eventData); - - } - - public async Task PublishAsync(Type eventType, object eventData, bool onUnitOfWorkComplete = true, - bool useOutbox = true) - { - var eventName = EventNameAttribute.GetNameOrDefault(eventType); - await CapPublisher.PublishAsync(eventName, eventData); - } - - - protected override IEnumerable GetHandlerFactories(Type eventType) - { - var handlerFactoryList = new List(); - - foreach (var handlerFactory in - HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key))) - { - handlerFactoryList.Add( - new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value)); - } - - return handlerFactoryList.ToArray(); - } - - private List GetOrCreateHandlerFactories(Type eventType) - { - return HandlerFactories.GetOrAdd( - eventType, - type => - { - var eventName = EventNameAttribute.GetNameOrDefault(type); - EventTypes[eventName] = type; - return new List(); - } - ); - } - - private static bool ShouldTriggerEventForHandler(Type targetEventType, Type handlerEventType) - { - //Should trigger same type - if (handlerEventType == targetEventType) - { - return true; - } - - //TODO: Support inheritance? But it does not support on subscription to RabbitMq! - //Should trigger for inherited types - if (handlerEventType.IsAssignableFrom(targetEventType)) - { - return true; - } - - return false; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapModule.cs b/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapModule.cs deleted file mode 100644 index a6984b88..00000000 --- a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapModule.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Lion.AbpPro.CAP -{ - [DependsOn(typeof(AbpEventBusModule))] - public class AbpProAbpCapModule : AbpModule - { - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapServiceCollectionExtensions.cs b/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapServiceCollectionExtensions.cs deleted file mode 100644 index aee610d0..00000000 --- a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/AbpProAbpCapServiceCollectionExtensions.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Lion.AbpPro.CAP -{ - public static class AbpProAbpCapServiceCollectionExtensions - { - public static ServiceConfigurationContext AddAbpCap( - this ServiceConfigurationContext context, - Action capAction) - { - context.Services.AddCap(capAction); - context.Services.AddSingleton(); - context.Services.AddSingleton(); - return context; - } - } -} diff --git a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/Lion.AbpPro.CAP.csproj b/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/Lion.AbpPro.CAP.csproj deleted file mode 100644 index e5655f73..00000000 --- a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/Lion.AbpPro.CAP.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - netstandard2.1 - - - - - - - - diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/CustomeListResultDto.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/CustomeListResultDto.cs deleted file mode 100644 index dc571d88..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/CustomeListResultDto.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs.Dtos -{ - [Serializable] - public class CustomeListResultDto - { - public IReadOnlyList Items - { - get { return _items ??= new List(); } - set => _items = value; - } - - private IReadOnlyList _items; - - public CustomeListResultDto() - { - } - - public CustomeListResultDto(IReadOnlyList items) - { - Items = items; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/CustomePagedResultDto.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/CustomePagedResultDto.cs deleted file mode 100644 index 7b547981..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/CustomePagedResultDto.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs.Dtos -{ - [Serializable] - public class CustomePagedResultDto : CustomeListResultDto - { - public long TotalCount { get; set; } - - public CustomePagedResultDto() - { - } - - public CustomePagedResultDto(long totalCount, IReadOnlyList items) - : base(items) - { - TotalCount = totalCount; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/FromSelector.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/FromSelector.cs deleted file mode 100644 index 9d2020e9..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/FromSelector.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs.Dtos -{ - - - public abstract class FromSelectorBase - { - protected FromSelectorBase(int value, string label) - { - Value = value; - Label = label; - } - public int Value { get; protected set; } - public string Label { get; protected set; } - } - - public abstract class FromSelectorBase - { - protected FromSelectorBase(TValue value, TLabel label) - { - Value = value; - Label = label; - } - - public TValue Value { get; protected set; } - public TLabel Label { get; protected set; } - } - - public class FromSelector : FromSelectorBase - { - public FromSelector(int value, string label) : base(value, label) - { - } - } - - public class FromSelector : FromSelectorBase - { - public FromSelector(TValue value, TLabel label) : base(value, label) - { - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/IdInput.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/IdInput.cs deleted file mode 100644 index a41b440c..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/IdInput.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs.Dtos -{ - public class IdInput - { - public Guid Id { get; set; } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/PagingBase.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/PagingBase.cs deleted file mode 100644 index b63dab03..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/PagingBase.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs.Dtos -{ - - - /// - /// 分页查询时使用的Dto类型 - /// - public class PagingBase : IValidatableObject - { - public const int MaxPageSize = 100000; - - /// - /// 当前页面.默认从1开始 - /// - public int PageIndex { get; set; } = 1; - - /// - /// 每页多少条.每页显示多少记录 - /// - public int PageSize { get; set; } = 10; - - /// - /// 跳过多少条 - /// - public int SkipCount => (PageIndex - 1) * PageSize; - - protected PagingBase() - { - } - - public PagingBase(int pageIndex = 1, int pageSize = 10) - { - PageIndex = pageIndex; - PageSize = pageSize; - } - - public virtual IEnumerable Validate(ValidationContext validationContext) - { - if (PageIndex < 1) - { - yield return new ValidationResult( - "起始页必须大于等于1", - new[] { "PageIndex"} - ); - } - - if (PageSize > MaxPageSize) - { - yield return new ValidationResult( - $"每页最大记录数不能超过'{MaxPageSize}'", - new[] { "PageSize"} - ); - } - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs deleted file mode 100644 index 522995b1..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResult.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs.Dtos -{ - public class WrapResult - { - public bool Success { get; private set; } - - public string Message { get; private set; } - - public T Data { get; private set; } - - public int Code { get; private set; } - - public WrapResult() - { - Success = true; - Message = "Success"; - Data = default; - Code = 200; - } - - public void SetSuccess(T data, string message = "Success", int code = 200) - { - Success = true; - Data = data; - Code = code; - } - - public void SetFail(string message = "Fail", int code = 500) - { - Success = false; - Message = message; - Code = code; - } - - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResultAttribute.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResultAttribute.cs deleted file mode 100644 index 2cbd5027..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Dtos/WrapResultAttribute.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs.Dtos -{ - public class WrapResultAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Guard.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Guard.cs deleted file mode 100644 index 6f856f30..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Guard.cs +++ /dev/null @@ -1,265 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs -{ - /// - /// 参数合法性检查类 - /// - [DebuggerStepThrough] - public static class Guard - { - /// - /// 检查参数不能为空引用, - /// - /// - /// 参数名称 - public static T NotNull(T value, string valueName) - { - if (null == value) - { - throw new ArgumentNullException(valueName); - } - - return value; - } - - /// - /// 检查字符串不能为空引用或空字符串, - /// - /// - /// 参数名称。 - /// 字符串允许的最大长度。 - /// 字符串允许的最小长度。0表示不限制最小长度 - public static string NotNullOrEmpty(string value, string valueName, int maxLength = int.MaxValue, - int minLength = 0) - { - if (string.IsNullOrEmpty(value)) - { - throw new ArgumentNullException(valueName); - } - - if (value.Length > maxLength) - { - throw new ArgumentOutOfRangeException(valueName); - } - - if (minLength > 0 && value.Length < minLength) - { - throw new ArgumentOutOfRangeException(valueName); - } - - return value; - } - - /// - /// 检查字符串不能为空引用或全部为空白, - /// - /// 需检查的字符串 - /// 参数名称。 - /// 字符串允许的最大长度。 - /// 字符串允许的最小长度。0表示不限制最小长度 - public static string NotNullOrWhiteSpace( - string value, - string valueName, - int maxLength = int.MaxValue, - int minLength = 0) - { - if (string.IsNullOrWhiteSpace(value)) - { - throw new ArgumentNullException(valueName); - } - - if (value.Length > maxLength) - { - throw new ArgumentOutOfRangeException(valueName); - } - - if (minLength > 0 && value.Length < minLength) - { - throw new ArgumentOutOfRangeException(valueName); - } - - return value; - } - - /// - /// 检查字符串长度是否超过最大长度,或低于最小长度, - /// - /// 需检查的字符串。 - /// 参数名称。 - /// 字符串允许的最大长度。 - /// 字符串要求的最小长度。0表示不限制最小长度 - public static string Length(string value, string valueName, int maxLength = int.MaxValue, - int minLength = 0) - { - if (string.IsNullOrEmpty(value)) - { - return value; - } - - if (value.Length > maxLength) - { - throw new ArgumentOutOfRangeException(valueName); - } - - if (minLength > 0 && value.Length < minLength) - { - throw new ArgumentOutOfRangeException(valueName); - } - - return value; - } - - /// - /// 检查Guid值不能为Guid.Empty - /// - /// - /// 参数名称。 - public static Guid NotEmpty( - Guid value, - string valueName) - { - if (value == Guid.Empty) - { - throw new ArgumentNullException(valueName); - } - - return value; - } - - /// - /// 检查集合不能为空引用或空集合, - /// - /// 集合项的类型。 - /// - /// 参数名称。 - public static void NotNullOrEmpty( - IReadOnlyList list, - string valueName) - { - if (null == list || !list.Any()) - { - throw new ArgumentNullException(valueName); - } - } - - /// - /// 检查参数必须小于[或可等于,参数]指定值, - /// - /// 参数类型。 - /// - /// 参数名称。 - /// 要比较的值。 - /// 是否可等于。 - public static void LessThan( - T value, - string valueName, - T target, - bool canEqual = false) - where T : IComparable - { - var flag = canEqual ? value.CompareTo(target) <= 0 : value.CompareTo(target) < 0; - if (!flag) - { - throw new ArgumentOutOfRangeException(valueName); - } - } - - /// - /// 检查参数必须大于[或可等于,参数]指定值, - /// - /// 参数类型。 - /// 需检查的参数。 - /// 参数名称。 - /// 要比较的值。 - /// 是否可等于。 - public static void GreaterThan( - T value, - string valueName, - T target, - bool canEqual = false) - where T : IComparable - { - var flag = canEqual ? value.CompareTo(target) >= 0 : value.CompareTo(target) > 0; - if (!flag) - { - throw new ArgumentOutOfRangeException(valueName); - } - } - - /// - /// 检查参数必须在指定范围之间 - /// - /// 参数类型。 - /// 需检查的参数。 - /// 参数名称。 - /// 比较范围的起始值。 - /// 比较范围的结束值。 - /// 是否可等于起始值 - /// 是否可等于结束值 - public static void Between( - T value, - string valueName, - T start, - T end, - bool startEqual = false, - bool endEqual = false) - where T : IComparable - { - var flag = startEqual ? value.CompareTo(start) >= 0 : value.CompareTo(start) > 0; - if (!flag) - { - throw new ArgumentOutOfRangeException(valueName); - } - - flag = endEqual ? value.CompareTo(end) <= 0 : value.CompareTo(end) < 0; - if (!flag) - { - throw new ArgumentOutOfRangeException(valueName); - } - } - - /// - /// 检查指定路径的文件夹必须存在, - /// - /// 需检查的路径。 - /// 参数名称。 - public static string DirectoryExists( - string directory, - string parameterName) - { - if (string.IsNullOrWhiteSpace(directory)) - { - throw new DirectoryNotFoundException(parameterName); - } - - if (!Directory.Exists(directory)) - { - throw new DirectoryNotFoundException(directory); - } - - return directory; - } - - /// - /// 检查指定路径的文件必须存在,否则抛出 - /// - /// - /// 参数名称。 - - public static string FileExists( - string filename, - string valueName) - { - if (string.IsNullOrWhiteSpace(filename)) - { - throw new ArgumentNullException(valueName); - } - - if (!File.Exists(filename)) - { - throw new FileNotFoundException(filename); - } - - return filename; - } - } -} diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Http/HttpClientHelper.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Http/HttpClientHelper.cs deleted file mode 100644 index fb5ba700..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Customs/Http/HttpClientHelper.cs +++ /dev/null @@ -1,156 +0,0 @@ -namespace Lion.AbpPro.Extension.Customs.Http -{ - /// - /// 基于IHttpClientFactory二次封装httpclient - /// - public static class HttpClientHelper - { - - public static async Task GetAsync(this IHttpClientFactory _httpClientFactory, string clientName, string url, Dictionary headers = null) where TResult : class - { - try - { - var client = _httpClientFactory.CreateClient(clientName); - if (headers != null && headers.Count > 0) - { - foreach (var item in headers) - { - client.DefaultRequestHeaders.Add(item.Key, item.Value); - } - - } - - client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); - - //执行请求 - var response = await client.GetAsync(url); - var result = await response.Content.ReadAsStringAsync(); - if (response.IsSuccessStatusCode) - { - if (result != null && !string.IsNullOrEmpty(result)) - return JsonConvert.DeserializeObject(result); - else - return default(TResult); - } - else - { - if (string.IsNullOrEmpty(result)) - result = response.ReasonPhrase; - throw new Exception(result); - } - } - catch (Exception e) - { - throw new Exception(e.Message); - } - } - - public static async Task PostAsync(this IHttpClientFactory _httpClientFactory, string clientName, string url, T obj, Dictionary headers = null) where T : class where TResult : class - { - var data = typeof(T).Name.ToLower() == "string" ? obj.ToString() : JsonConvert.SerializeObject(obj); - var client = _httpClientFactory.CreateClient(clientName); - if (headers != null && headers.Count > 0) - { - foreach (var item in headers) - { - client.DefaultRequestHeaders.Add(item.Key, item.Value); - } - } - - client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); - //post 参数 - var content = new StringContent(data, Encoding.UTF8, "application/json"); - //执行请求 - var response = await client.PostAsync(url, content); - - var result = await response.Content.ReadAsStringAsync(); - if (response.IsSuccessStatusCode) - { - if (result != null && !string.IsNullOrEmpty(result)) - return JsonConvert.DeserializeObject(result); - else - return default(TResult); - } - else - { - if (string.IsNullOrEmpty(result)) - result = response.ReasonPhrase; - - throw new Exception(result); - } - } - - public static async Task PutAsync(this IHttpClientFactory _httpClientFactory, string clientName, string url, T obj, Dictionary headers = null) where T : class where TResult : class - { - var data = typeof(T).Name.ToLower() == "string" ? obj.ToString() : JsonConvert.SerializeObject(obj); - var client = _httpClientFactory.CreateClient(clientName); - if (headers != null && headers.Count > 0) - { - foreach (var item in headers) - { - client.DefaultRequestHeaders.Add(item.Key, item.Value); - } - } - - client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); - //post 参数 - var content = new StringContent(data, Encoding.UTF8, "application/json"); - //执行请求 - var response = await client.PutAsync(url, content); - - var result = await response.Content.ReadAsStringAsync(); - if (response.IsSuccessStatusCode) - { - if (result != null && !string.IsNullOrEmpty(result)) - return JsonConvert.DeserializeObject(result); - else - return default(TResult); - } - else - { - if (string.IsNullOrEmpty(result)) - result = response.ReasonPhrase; - - throw new Exception(result); - } - } - - public static async Task DeleteAsync(this IHttpClientFactory _httpClientFactory, string clientName, string url, Dictionary headers = null) where TResult : class - { - try - { - var client = _httpClientFactory.CreateClient(clientName); - if (headers != null && headers.Count > 0) - { - foreach (var item in headers) - { - client.DefaultRequestHeaders.Add(item.Key, item.Value); - } - } - - client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); - - //执行请求 - var response = await client.DeleteAsync(url); - var result = await response.Content.ReadAsStringAsync(); - if (response.IsSuccessStatusCode) - { - if (result != null && !string.IsNullOrEmpty(result)) - return JsonConvert.DeserializeObject(result); - else - return default(TResult); - } - else - { - if (string.IsNullOrEmpty(result)) - result = response.ReasonPhrase; - throw new Exception(result); - } - } - catch (Exception e) - { - throw new Exception(e.Message); - } - } - } -} diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/GlobalUsings.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/GlobalUsings.cs deleted file mode 100644 index 2d291cdd..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/GlobalUsings.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Global using directives - -global using System; -global using System.Collections.Generic; -global using System.Collections.Specialized; -global using System.ComponentModel; -global using System.ComponentModel.DataAnnotations; -global using System.Diagnostics; -global using System.Globalization; -global using System.IO; -global using System.Linq; -global using System.Linq.Expressions; -global using System.Net.Http; -global using System.Net.Http.Headers; -global using System.Reflection; -global using System.Runtime.ExceptionServices; -global using System.Text; -global using System.Text.RegularExpressions; -global using System.Threading.Tasks; -global using System.Web; -global using Lion.AbpPro.Extension.Customs; -global using Lion.AbpPro.Extension.System.Collections.Generic; -global using Lion.AbpPro.Extension.System.Reflection; -global using Newtonsoft.Json; \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Lion.AbpPro.Extension.csproj b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Lion.AbpPro.Extension.csproj deleted file mode 100644 index ab7c6771..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/Lion.AbpPro.Extension.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - netstandard2.1 - - - - - - - - - - - - - - - diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/BooleanExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/BooleanExtensions.cs deleted file mode 100644 index bccb8ce2..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/BooleanExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Lion.AbpPro.Extension.System -{ - /// - /// 布尔值类型的扩展辅助操作类 - /// - public static class BooleanExtensions - { - /// - /// 把布尔值转换为小写字符串 - /// - public static string ToLower(this bool value) - { - return value.ToString().ToLower(); - } - - /// - /// 如果条件成立,则抛出异常 - /// - public static void TrueThrow(this bool flag, Exception exception) - { - if (flag) - { - throw exception; - } - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Collections/Generic/CollectionExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Collections/Generic/CollectionExtensions.cs deleted file mode 100644 index 4c509934..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Collections/Generic/CollectionExtensions.cs +++ /dev/null @@ -1,74 +0,0 @@ -namespace Lion.AbpPro.Extension.System.Collections.Generic -{ - /// - /// 集合扩展方法 - /// - public static class CollectionExtensions - { - /// - /// 如果条件成立,添加项 - /// - public static void AddIf(this ICollection collection, T value, bool flag) - { - Guard.NotNull(collection, nameof(collection)); - if (flag) - { - collection.Add(value); - } - } - - /// - /// 如果条件成立,添加项 - /// - public static void AddIf(this ICollection collection, T value, Func func) - { - Guard.NotNull(collection, nameof(collection)); - if (func()) - { - collection.Add(value); - } - } - - /// - /// 获取对象,不存在对使用委托添加对象 - /// - public static T GetOrAdd(this ICollection collection, Func selector, Func factory) - { - Guard.NotNull(collection, nameof(collection)); - T item = collection.FirstOrDefault(selector); - if (item == null) - { - item = factory(); - collection.Add(item); - } - - return item; - } - - /// - /// 判断集合是否为null或空集合 - /// - public static bool IsNullOrEmpty(this ICollection collection) - { - return collection == null || collection.Count == 0; - } - - /// - /// 交换两项的位置 - /// - public static void Swap(this List list, int index1, int index2) - { - Guard.Between(index1, nameof(index1), 0, list.Count, true); - Guard.Between(index2, nameof(index2), 0, list.Count, true); - - if (index1 == index2) - { - return; - } - - T tmp = list[index1]; - list[index1] = list[index2]; - list[index2] = tmp; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Collections/Generic/EnumerableExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Collections/Generic/EnumerableExtensions.cs deleted file mode 100644 index 7905b576..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Collections/Generic/EnumerableExtensions.cs +++ /dev/null @@ -1,196 +0,0 @@ -namespace Lion.AbpPro.Extension.System.Collections.Generic -{ - /// - /// Enumerable集合扩展方法 - /// - public static class EnumerableExtensions - { - /// 断言集合中的元素符合指定表达式,否则抛出异常。 - /// 集合项类型 - /// 源集合 - /// 元素判断表达式 - /// 异常选择器 - /// 筛选过的集合 - public static IEnumerable Assert(this IEnumerable source, Func predicate, - Func errorSelector = null) - { - foreach (var item in source) - { - var success = predicate(item); - if (!success) - { - throw errorSelector?.Invoke(item) ?? - new InvalidOperationException("集合中包含无效的元素。"); - } - - yield return item; - } - } - - /// - /// 打乱一个集合的项顺序,将一个集合洗牌 - /// - public static IEnumerable Shuffle(this IEnumerable source) - { - // ReSharper disable PossibleMultipleEnumeration - - Guard.NotNull(source, nameof(source)); - return source.OrderBy(m => Guid.NewGuid()); - - // ReSharper restore PossibleMultipleEnumeration - } - - /// - /// 将集合展开并分别转换成字符串,再以指定的分隔符衔接,拼成一个字符串返回。默认分隔符为逗号。 - /// - /// 要处理的集合 - /// 分隔符,默认为逗号 - /// 拼接后的字符串 - public static string ExpandAndToString(this IEnumerable collection, string separator = ",") - { - return collection.ExpandAndToString(item => item?.ToString() ?? string.Empty, separator); - } - - /// - /// 循环集合的每一项,调用委托生成字符串,返回合并后的字符串。默认分隔符为逗号 - /// - /// 待处理的集合 - /// 单个集合项的转换委托 - /// 分隔符,默认为逗号 - /// 泛型类型 - /// - public static string ExpandAndToString( - this IEnumerable collection, - Func itemFormatFunc, - string separator = ",") - { - collection = collection as IList ?? collection.ToList(); - Guard.NotNull(itemFormatFunc, nameof(itemFormatFunc)); - - if (!collection.Any()) - { - return string.Empty; - } - - var sb = new StringBuilder(); - var i = 0; - var count = collection.Count(); - foreach (var item in collection) - { - if (i == count - 1) - { - sb.Append(itemFormatFunc(item)); - } - else - { - sb.Append(itemFormatFunc(item) + separator); - } - - i++; - } - - return sb.ToString(); - } - - /// - /// 集合是否为空 - /// - /// 要处理的集合 - /// 动态类型 - /// 为空返回True,不为空返回False - public static bool IsEmpty(this IEnumerable collection) - { - collection = collection as IList ?? collection.ToList(); - return !collection.Any(); - } - - /// - /// 根据第三方条件是否为真来决定是否执行指定条件的查询 - /// - /// 要查询的源 - /// 查询条件 - /// 第三方条件 - /// 动态类型 - /// 查询的结果 - public static IEnumerable WhereIf(this IEnumerable source, Func predicate, bool condition) - { - Guard.NotNull(predicate, nameof(predicate)); - source = source as IList ?? source.ToList(); - - return condition ? source.Where(predicate) : source; - } - - /// - /// 将字符串集合按指定前缀排序 - /// - public static IEnumerable OrderByPrefixes(this IEnumerable source, Func keySelector, - params string[] prefixes) - { - var all = source.OrderBy(keySelector).ToList(); - var result = new List(); - foreach (var prefix in prefixes) - { - var tmpList = all.Where(m => keySelector(m).StartsWith(prefix)).OrderBy(keySelector).ToList(); - all = all.Except(tmpList).ToList(); - result.AddRange(tmpList); - } - - result.AddRange(all); - return result; - } - - /// - /// 根据指定条件返回集合中不重复的元素 - /// - /// 动态类型 - /// 动态筛选条件类型 - /// 要操作的源 - /// 重复数据筛选条件 - /// 不重复元素的集合 - public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) - { - Guard.NotNull(keySelector, nameof(keySelector)); - source = source as IList ?? source.ToList(); - - return source.GroupBy(keySelector).Select(group => group.First()); - } - - #region Internal - - internal static int? TryGetCollectionCount(this IEnumerable source) - { - switch (source) - { - case null: - throw new ArgumentNullException(nameof(source)); - case ICollection collection: - return collection.Count; - case IReadOnlyCollection collection: - return collection.Count; - default: - return null; - } - } - - static int CountUpTo(this IEnumerable source, int max) - { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (max < 0) - throw new ArgumentOutOfRangeException(nameof(max), "最大计数参数不能为负。"); - - var count = 0; - - using (var e = source.GetEnumerator()) - { - while (count < max && e.MoveNext()) - { - count++; - } - } - - return count; - } - - #endregion - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/DateTimeExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/DateTimeExtensions.cs deleted file mode 100644 index 9d583b9b..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/DateTimeExtensions.cs +++ /dev/null @@ -1,100 +0,0 @@ -namespace Lion.AbpPro.Extension.System -{ - /// - /// 时间扩展操作类 - /// - public static class DateTimeExtensions - { - /// - /// 当前时间是否周末 - /// - /// 时间点 - /// - public static bool IsWeekend(this DateTime dateTime) - { - DayOfWeek[] weeks = { DayOfWeek.Saturday, DayOfWeek.Sunday }; - return weeks.Contains(dateTime.DayOfWeek); - } - - /// - /// 当前时间是否工作日 - /// - /// 时间点 - /// - public static bool IsWeekday(this DateTime dateTime) - { - DayOfWeek[] weeks = { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday }; - return weeks.Contains(dateTime.DayOfWeek); - } - - /// - /// 获取时间相对唯一字符串 - /// - /// - /// 是否使用毫秒 - /// - public static string ToUniqueString(this DateTime dateTime, bool millisecond = false) - { - var seconds = dateTime.Hour * 3600 + dateTime.Minute * 60 + dateTime.Second; - var value = $"{dateTime:yyyy}{dateTime.DayOfYear}{seconds}"; - if (millisecond) - { - return value + dateTime.ToString("fff"); - } - - return value; - } - - /// - /// 将时间转换为JS时间格式(Date.getTime()) - /// - /// - /// 是否使用毫秒 - public static string ToJsGetTime(this DateTime dateTime, bool millisecond = true) - { - var utc = dateTime.ToUniversalTime(); - var span = utc.Subtract(new DateTime(1970, 1, 1)); - return Math.Round(millisecond ? span.TotalMilliseconds : span.TotalSeconds).ToString(CultureInfo.InvariantCulture); - } - - /// - /// 将JS时间格式的数值转换为时间 - /// - public static DateTime FromJsGetTime(this long jsTime) - { - var length = jsTime.ToString().Length; - if (!(length == 10 || length == 13)) - { - throw new ArgumentOutOfRangeException(null, "JS时间数值的长度不正确,必须为10位或13位"); - } - var start = new DateTime(1970, 1, 1); - var result = length == 10 ? start.AddSeconds(jsTime) : start.AddMilliseconds(jsTime); - return result.ToUniversalTime(); - } - - /// - /// 获取指定日期 当天的最大时间 - /// 例如 2021-09-10 11:22:33.123456 转换后 2021-09-10 23:59:59.9999999 - /// - public static DateTime? ToCurrentDateMaxDateTime(this DateTime? dateTime) - { - return dateTime?.Date.AddDays(1).AddTicks(-1); - } - - /// - /// 获取指定时间的下一秒 - /// 例如 2021-09-10 11:11:11.1234567 转换后 2021-09-10 11:11:12.0000000 - /// - public static DateTime? ToNextSecondDateTime(this DateTime? dateTime) - { - if (!dateTime.HasValue) - { - return null; - } - - return new DateTime(dateTime.Value.Year, dateTime.Value.Month, dateTime.Value.Day, dateTime.Value.Hour, - dateTime.Value.Minute, dateTime.Value.Second) - .AddSeconds(1); - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/EnumExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/EnumExtensions.cs deleted file mode 100644 index 8322395d..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/EnumExtensions.cs +++ /dev/null @@ -1,192 +0,0 @@ -namespace Lion.AbpPro.Extension.System -{ - /// - /// 枚举的扩展辅助操作方法 - /// - public static class EnumExtensions - { - /// - /// 获取枚举项上的特性的文字描述 - /// - /// - /// - public static string ToDescription(this Enum value) - { - var type = value.GetType(); - var member = type.GetMember(value.ToString()).FirstOrDefault(); - - return member != null ? member.GetDescription() : value.ToString(); - } - - /// - /// 枚举遍历,返回枚举的名称、值、特性 - /// - /// 枚举类型 - /// 回调函数 - private static void Each(this Type enumType, Action action) - { - if (enumType.BaseType != typeof(Enum)) - { - return; - } - var arr = Enum.GetValues(enumType); - foreach (var name in arr) - { - var currentEnum = Enum.Parse(enumType, name.ToString()); - var value = Convert.ToInt32(Enum.Parse(enumType, name.ToString())); - var fieldInfo = enumType.GetField(name.ToString()); - var description = ""; - if (fieldInfo != null) - { - var attr = Attribute.GetCustomAttribute(fieldInfo, - typeof(DescriptionAttribute), false) as DescriptionAttribute; - if (attr != null) - { - description = attr.Description; - } - } - action(name.ToString(), value.ToString(), description, currentEnum); - } - } - - /// - /// 根据枚举类型值返回枚举定义Description属性 - /// - /// - /// - /// - public static string ToEnumDescriptionString(this short value, Type enumType) - { - var nvc = new NameValueCollection(); - var typeDescription = typeof(DescriptionAttribute); - var fields = enumType.GetFields(); - foreach (var field in fields) - { - if (field.FieldType.IsEnum) - { - var strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString(); - var arr = field.GetCustomAttributes(typeDescription, true); - string strText; - if (arr.Length > 0) - { - var aa = (DescriptionAttribute)arr[0]; - strText = aa.Description; - } - else - { - strText = ""; - } - nvc.Add(strValue, strText); - } - } - return nvc[value.ToString()]; - } - - /// - /// 将指定枚举转换为字典. - /// 枚举的Description为字典的Key,枚举的Value为字典的Value - /// - /// 指定枚举 - private static List> GetEnumTypeValueList() - { - var items = new List>(); - typeof(T).Each((name, value, description, enumObj) => - items.Add(new KeyValuePair(description, value))); - return items; - } - - /// - /// 将指定枚举转换为字典. - /// 枚举的Description为字典的Key,枚举为字典的Value - /// - /// 指定枚举 - private static List> GetEnumTypeList() - { - var items = new List>(); - typeof(T).Each((name, value, description, enumObj) => - items.Add(new KeyValuePair(description, (T)enumObj))); - return items; - } - - /// - /// 将指定枚举转换为字典. - /// 枚举的Description为字典的Key,枚举的Name为字典的Value - /// - /// 指定枚举 - public static List> GetEnumTypeDescriptionNameList() - { - var items = new List>(); - typeof(T).Each((name, value, description, enumObj) => items.Add(new KeyValuePair(description, name))); - return items; - } - - /// - /// 将指定枚举转换为字典. - /// 枚举的Name为字典的Key,枚举的Description为字典的Value - /// - /// 指定枚举 - public static List> GetEnumTypeValueNameList() - { - var items = new List>(); - typeof(T).Each((name, value, description, enumObj) => items.Add(new KeyValuePair(name, description))); - return items; - } - - /// - /// 将指定枚举转换为字典. - /// 枚举的Name为字典的Key,枚举的Description为字典的Value - /// - /// 指定枚举 - public static List> GetStringKeyValueList() where TModel : Enum - { - var keyValuePairList = new List>(); - var values = Enum.GetValues(typeof(TModel)); - var modelArray = new TModel[values.Length]; - values.CopyTo(modelArray, 0); - foreach (TModel model in modelArray) - keyValuePairList.Add(new KeyValuePair(model.ToString(), model.ToString())); - return keyValuePairList; - } - - /// - /// 将指定枚举转换为字典. - /// 枚举的Description为字典的Key,枚举为字典的Value - /// - /// 指定枚举 - public static List> GetEnumKeyValueList() where TModel : Enum - { - var enumTypeList = GetEnumTypeList(); - var keyValuePairList = new List>(); - foreach (KeyValuePair keyValuePair in enumTypeList) - keyValuePairList.Add(new KeyValuePair(keyValuePair.Key, keyValuePair.Value)); - return keyValuePairList; - } - - public static List> GetEntityDoubleStringKeyValueList() - { - var enumTypeList = GetEnumTypeValueList(); - var keyValuePairList = new List>(); - foreach (KeyValuePair keyValuePair in enumTypeList) - keyValuePairList.Add(new KeyValuePair(keyValuePair.Key, keyValuePair.Value)); - return keyValuePairList; - } - - public static List> GetEntityStringIntKeyValueList() - { - List> enumTypeList = GetEnumTypeValueList(); - List> keyValuePairList = new List>(); - foreach (KeyValuePair keyValuePair in enumTypeList) - keyValuePairList.Add(new KeyValuePair(keyValuePair.Key, Convert.ToInt32(keyValuePair.Value))); - return keyValuePairList; - } - - public static List> GetEntityDoubleIntKeyValueList() - { - List> enumTypeList = GetEnumTypeValueList(); - List> keyValuePairList = new List>(); - foreach (KeyValuePair keyValuePair in enumTypeList) - keyValuePairList.Add(new KeyValuePair(Convert.ToInt32(keyValuePair.Key), Convert.ToInt32(keyValuePair.Value))); - return keyValuePairList; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/ExceptionExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/ExceptionExtensions.cs deleted file mode 100644 index dd41d61a..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/ExceptionExtensions.cs +++ /dev/null @@ -1,73 +0,0 @@ -namespace Lion.AbpPro.Extension.System -{ - /// - /// 异常操作扩展 - /// - public static class ExceptionExtensions - { - /// - /// 格式化异常消息 - /// - /// 异常对象 - /// 是否隐藏异常规模信息 - /// 格式化后的异常信息字符串 - public static string FormatMessage(this Exception e, bool isHideStackTrace = false) - { - var sb = new StringBuilder(); - var count = 0; - var appString = string.Empty; - while (e != null) - { - if (count > 0) - { - appString += " "; - } - sb.AppendLine($"{appString}异常消息:{e.Message}"); - sb.AppendLine($"{appString}异常类型:{e.GetType().FullName}"); - sb.AppendLine($"{appString}异常方法:{(e.TargetSite == null ? null : e.TargetSite.Name)}"); - sb.AppendLine($"{appString}异常源:{e.Source}"); - if (!isHideStackTrace && e.StackTrace != null) - { - sb.AppendLine($"{appString}异常堆栈:{e.StackTrace}"); - } - if (e.InnerException != null) - { - sb.AppendLine($"{appString}内部异常:"); - count++; - e = e.InnerException; - } - } - return sb.ToString(); - } - - /// - /// 将异常重新抛出 - /// - public static void ReThrow(this Exception exception) - { - ExceptionDispatchInfo.Capture(exception).Throw(); - } - - /// - /// 如果条件成立,则抛出异常 - /// - public static void ThrowIf(this Exception exception, bool isThrow) - { - if (isThrow) - { - throw exception; - } - } - - /// - /// 如果条件成立,则抛出异常 - /// - public static void ThrowIf(this Exception exception, Func isThrowFunc) - { - if (isThrowFunc()) - { - throw exception; - } - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Linq/QueryableExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Linq/QueryableExtensions.cs deleted file mode 100644 index 47456684..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Linq/QueryableExtensions.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Lion.AbpPro.Extension.System.Linq -{ - /// - /// IQueryable集合扩展方法 - /// - public static class QueryableExtensions - { - /// - /// 根据第三方条件是否为真来决定是否执行指定条件的查询 - /// - /// 要查询的源 - /// 查询条件 - /// 第三方条件 - /// 动态类型 - /// 查询的结果 - public static IQueryable WhereIf(this IQueryable source, Expression> predicate, - bool condition) - { - Guard.NotNull(source, nameof(source)); - Guard.NotNull(predicate, nameof(predicate)); - - return condition ? source.Where(predicate) : source; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/AssemblyExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/AssemblyExtensions.cs deleted file mode 100644 index 19720c63..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/AssemblyExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Lion.AbpPro.Extension.System.Reflection -{ - /// - /// 程序集扩展操作类 - /// - public static class AssemblyExtensions - { - /// - /// 获取程序集的产品版本 - /// - public static string GetProductVersion(this Assembly assembly) - { - Guard.NotNull(assembly, nameof(assembly)); - var info = FileVersionInfo.GetVersionInfo(assembly.Location); - var version = info.ProductVersion; - if (version.Contains("+")) - { - version = version.ReplaceRegex(@"\+(\w+)?", ""); - } - return version; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/MemberInfoExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/MemberInfoExtensions.cs deleted file mode 100644 index 2d886126..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/MemberInfoExtensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace Lion.AbpPro.Extension.System.Reflection -{ - /// - /// 成员的扩展辅助操作方法 - /// - public static class MemberInfoExtensions - { - /// - /// 获取成员元数据的Description特性描述信息。 - /// - /// 成员元数据对象。 - /// 是否搜索成员的继承链以查找描述特性。 - /// 返回Description特性描述信息,如不存在则返回成员的名称。 - public static string GetDescription(this MemberInfo member, bool inherit = true) - { - var desc = member.GetAttribute(inherit); - if (desc != null) - { - return desc.Description; - } - - var displayName = member.GetAttribute(inherit); - if (displayName != null) - { - return displayName.DisplayName; - } - - var display = member.GetAttribute(inherit); - return display != null ? display.Name : member.Name; - } - - /// - /// 检查指定指定类型成员中是否存在指定的Attribute特性。 - /// - /// 要检查的Attribute特性类型。 - /// 要检查的类型成员 - /// 是否从继承中查找 - /// 是否存在 - public static bool HasAttribute(this MemberInfo memberInfo, bool inherit = true) where T : Attribute - { - return memberInfo.IsDefined(typeof(T), inherit); - } - - /// - /// 从类型成员获取指定Attribute特性 - /// - /// Attribute特性类型 - /// 类型类型成员 - /// 是否从继承中查找 - /// 存在返回第一个,不存在返回null - public static T GetAttribute(this MemberInfo memberInfo, bool inherit = true) where T : Attribute - { - var attributes = memberInfo.GetCustomAttributes(typeof(T), inherit); - return attributes.FirstOrDefault() as T; - } - - /// - /// 从类型成员获取指定Attribute特性。 - /// - /// Attribute特性类型。 - /// 类型类型成员。 - /// 是否从继承中查找。 - /// 返回所有指定Attribute特性的数组。 - public static T[] GetAttributes(this MemberInfo memberInfo, bool inherit = true) where T : Attribute - { - return memberInfo.GetCustomAttributes(typeof(T), inherit).Cast().ToArray(); - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/MethodInfoExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/MethodInfoExtensions.cs deleted file mode 100644 index ea3aca43..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/MethodInfoExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Lion.AbpPro.Extension.System.Reflection -{ - /// - /// 方法的扩展辅助操作方法 - /// - public static class MethodInfoExtensions - { - /// - /// 方法是否是异步 - /// - public static bool IsAsync(this MethodInfo method) - { - return (method.ReturnType == typeof(Task<>) - || method.ReturnType.IsGenericType - && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)) - || method.ReturnType == typeof(Task); - } - - /// - /// 返回当前方法信息是否是重写方法 - /// - /// 要判断的方法信息 - /// 是否是重写方法 - public static bool IsOverridden(this MethodInfo method) - { - return method.GetBaseDefinition().DeclaringType != method.DeclaringType; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/PropertyInfoExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/PropertyInfoExtensions.cs deleted file mode 100644 index 70c3e9ee..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/Reflection/PropertyInfoExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Lion.AbpPro.Extension.System.Reflection -{ - /// - /// 属性的扩展辅助操作方法 - /// - public static class PropertyInfoExtensions - { - /// - /// 返回当前属性信息是否为virtual - /// - public static bool IsVirtual(this PropertyInfo property) - { - var accessor = property.GetAccessors().FirstOrDefault(); - if (accessor == null) - { - return false; - } - - return accessor.IsVirtual && !accessor.IsFinal; - } - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/StringExtensions.cs b/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/StringExtensions.cs deleted file mode 100644 index 071ce647..00000000 --- a/aspnet-core/frameworks/Extensions/src/Lion.AbpPro.Extension/System/StringExtensions.cs +++ /dev/null @@ -1,971 +0,0 @@ -namespace Lion.AbpPro.Extension.System -{ - /// - /// 字符串类型的扩展辅助操作类 - /// - [DebuggerStepThrough] - public static class StringExtensions - { - #region 正则表达式 - - /// - /// 指示所指定的正则表达式在指定的输入字符串中是否找到了匹配项 - /// - /// 要搜索匹配项的字符串 - /// 要匹配的正则表达式模式 - /// 是否包含,否则全匹配 - /// 如果正则表达式找到匹配项,则为 true;否则,为 false - public static bool IsMatch(this string value, string pattern, bool isContains = true) - { - if (value == null) - { - return false; - } - - return isContains - ? Regex.IsMatch(value, pattern) - : Regex.Match(value, pattern).Success; - } - - /// - /// 在指定的输入字符串中搜索指定的正则表达式的第一个匹配项 - /// - /// 要搜索匹配项的字符串 - /// 要匹配的正则表达式模式 - /// 一个对象,包含有关匹配项的信息 - public static string Match(this string value, string pattern) - { - if (value == null) - { - return null; - } - - return Regex.Match(value, pattern).Value; - } - - /// - /// 在指定的输入字符串中匹配并替换符合指定正则表达式的子串 - /// - public static string ReplaceRegex(this string value, string pattern, string replacement) - { - if (value == null) - { - return null; - } - - return Regex.Replace(value, pattern, replacement); - } - - /// - /// 在指定的输入字符串中搜索指定的正则表达式的所有匹配项的字符串集合 - /// - /// 要搜索匹配项的字符串 - /// 要匹配的正则表达式模式 - /// 一个集合,包含有关匹配项的字符串值 - public static IEnumerable Matches(this string value, string pattern) - { - if (value == null) - { - return new string[] { }; - } - - var matches = Regex.Matches(value, pattern); - return from Match match in matches select match.Value; - } - - /// - /// 在指定的输入字符串中匹配第一个数字字符串 - /// - public static string MatchFirstNumber(this string value) - { - var matches = Regex.Matches(value, @"\d+"); - if (matches.Count == 0) - { - return string.Empty; - } - - return matches[0].Value; - } - - /// - /// 在指定字符串中匹配最后一个数字字符串 - /// - public static string MatchLastNumber(this string value) - { - var matches = Regex.Matches(value, @"\d+"); - if (matches.Count == 0) - { - return string.Empty; - } - - return matches[matches.Count - 1].Value; - } - - /// - /// 在指定字符串中匹配所有数字字符串 - /// - public static IEnumerable MatchNumbers(this string value) - { - return Matches(value, @"\d+"); - } - - /// - /// 检测指定字符串中是否包含数字 - /// - public static bool IsMatchNumber(this string value) - { - return IsMatch(value, @"\d"); - } - - /// - /// 检测指定字符串是否全部为数字并且长度等于指定长度 - /// - public static bool IsMatchNumber(this string value, int length) - { - var regex = new Regex(@"^\d{" + length + "}$"); - return regex.IsMatch(value); - } - - /// - /// 截取指定字符串之间的字符串 - /// - /// - /// 起始字符串 - /// 结束字符串,可多个 - /// 返回的中间字符串 - public static string Substring(this string source, string startString, params string[] endStrings) - { - if (source.IsMissing()) - { - return string.Empty; - } - - var startIndex = 0; - if (!string.IsNullOrEmpty(startString)) - { - startIndex = source.IndexOf(startString, StringComparison.OrdinalIgnoreCase); - if (startIndex < 0) - { - throw new InvalidOperationException($"在源字符串中无法找到“{startString}”的子串位置"); - } - - startIndex += startString.Length; - } - - var endIndex = source.Length; - endStrings = endStrings.OrderByDescending(m => m.Length).ToArray(); - foreach (var endString in endStrings) - { - if (string.IsNullOrEmpty(endString)) - { - endIndex = source.Length; - break; - } - - endIndex = source.IndexOf(endString, startIndex, StringComparison.OrdinalIgnoreCase); - if (endIndex < 0 || endIndex < startIndex) - { - continue; - } - - break; - } - - if (endIndex < 0 || endIndex < startIndex) - { - throw new InvalidOperationException($"在源字符串中无法找到“{endStrings.ExpandAndToString()}”的子串位置"); - } - - var length = endIndex - startIndex; - - return source.Substring(startIndex, length); - } - - /// - /// 用正则表达式截取字符串 - /// - public static string Substring2(this string source, string startString, string endString) - { - return source.Substring2(startString, endString, false); - } - - /// - /// 用正则表达式截取字符串 - /// - public static string Substring2(this string source, string startString, string endString, bool containsEmpty) - { - if (source.IsMissing()) - { - return string.Empty; - } - - var inner = containsEmpty ? "\\s\\S" : "\\S"; - var result = source.Match($"(?<={startString})([{inner}]+?)(?={endString})"); - return result.IsMissing() ? null : result; - } - - /// - /// 是否电子邮件 - /// - public static bool IsEmail(this string value) - { - const string pattern = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"; - return value.IsMatch(pattern); - } - - /// - /// 是否是IP地址 - /// - public static bool IsIpAddress(this string value) - { - const string pattern = - @"^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))$"; - return value.IsMatch(pattern); - } - - /// - /// 是否是整数 - /// - public static bool IsNumeric(this string value) - { - const string pattern = @"^\-?[0-9]+$"; - return value.IsMatch(pattern); - } - - /// - /// 是否是Unicode字符串 - /// - public static bool IsUnicode(this string value) - { - const string pattern = @"^[\u4E00-\u9FA5\uE815-\uFA29]+$"; - return value.IsMatch(pattern); - } - - /// - /// 是否Url字符串 - /// - public static bool IsUrl(this string value) - { - try - { - if (string.IsNullOrEmpty(value) || value.Contains(' ')) - { - return false; - } - - var uri = new Uri(value); - return true; - } - catch (Exception) - { - return false; - } - } - - /// - /// 是否身份证号,验证如下3种情况: - /// 1.身份证号码为15位数字; - /// 2.身份证号码为18位数字; - /// 3.身份证号码为17位数字+1个字母 - /// - public static bool IsIdentityCardId(this string value) - { - if (value.Length != 15 && value.Length != 18) - { - return false; - } - - Regex regex; - string[] array; - if (value.Length == 15) - { - regex = new Regex(@"^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})_"); - if (!regex.Match(value).Success) - { - return false; - } - - array = regex.Split(value); - return DateTime.TryParse(string.Format("{0}-{1}-{2}", "19" + array[2], array[3], array[4]), out _); - } - - regex = new Regex(@"^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9Xx])$"); - if (!regex.Match(value).Success) - { - return false; - } - - array = regex.Split(value); - if (!DateTime.TryParse(string.Format("{0}-{1}-{2}", array[2], array[3], array[4]), out _)) - { - return false; - } - - //校验最后一位 - var chars = value.ToCharArray().Select(m => m.ToString()).ToArray(); - int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; - var sum = 0; - for (var i = 0; i < 17; i++) - { - var num = int.Parse(chars[i]); - sum += num * weights[i]; - } - - var mod = sum % 11; - var vCode = "10X98765432"; // 检验码字符串 - var last = vCode.ToCharArray().ElementAt(mod).ToString(); - return chars.Last().ToUpper() == last; - } - - /// - /// 是否手机号码 - /// - /// - /// 是否按严格格式验证 - public static bool IsMobileNumber(this string value, bool isRestrict = false) - { - var pattern = isRestrict ? @"^[1][3-8]\d{9}$" : @"^[1]\d{10}$"; - return value.IsMatch(pattern); - } - - #endregion - - #region 其他操作 - - /// - /// 判断指定的字符串不是 null、空。 - /// - public static bool IsNotNullOrEmpty(this string str) - { - return !string.IsNullOrEmpty(str); - } - - /// - /// 判断指定的字符串不是 null、空或者仅由空白字符组成 - /// - public static bool IsNotNullOrWhiteSpace(this string str) - { - return !string.IsNullOrWhiteSpace(str); - } - - /// - /// 指示指定的字符串是 null、空或者仅由空白字符组成 - /// - public static bool IsMissing(this string value) - { - return string.IsNullOrWhiteSpace(value); - } - - /// - /// 为指定格式的字符串填充相应对象来生成字符串 - /// - /// 字符串格式,占位符以{n}表示 - /// 用于填充占位符的参数 - /// 格式化后的字符串 - public static string FormatWith(this string format, params object[] args) - { - Guard.NotNull(format, nameof(format)); - return string.Format(CultureInfo.CurrentCulture, format, args); - } - - /// - /// 将字符串反转 - /// - /// 要反转的字符串 - public static string ReverseString(this string value) - { - Guard.NotNull(value, nameof(value)); - return new string(value.Reverse().ToArray()); - } - - /// - /// 单词复数变成单数形式 - /// - /// - /// - public static string ToSingular(this string word) - { - var plural1 = new Regex("(?[^aeiou])ies$"); - var plural2 = new Regex("(?[aeiou]y)s$"); - var plural3 = new Regex("(?[sxzh])es$"); - var plural4 = new Regex("(?[^sxzhyu])s$"); - - if (plural1.IsMatch(word)) - { - return plural1.Replace(word, "${keep}y"); - } - - if (plural2.IsMatch(word)) - { - return plural2.Replace(word, "${keep}"); - } - - if (plural3.IsMatch(word)) - { - return plural3.Replace(word, "${keep}"); - } - - if (plural4.IsMatch(word)) - { - return plural4.Replace(word, "${keep}"); - } - - return word; - } - - /// - /// 单词单数变成复数形式 - /// - /// - /// - public static string ToPlural(this string word) - { - var plural1 = new Regex("(?[^aeiou])y$"); - var plural2 = new Regex("(?[aeiou]y)$"); - var plural3 = new Regex("(?[sxzh])$"); - var plural4 = new Regex("(?[^sxzhy])$"); - - if (plural1.IsMatch(word)) - { - return plural1.Replace(word, "${keep}ies"); - } - - if (plural2.IsMatch(word)) - { - return plural2.Replace(word, "${keep}s"); - } - - if (plural3.IsMatch(word)) - { - return plural3.Replace(word, "${keep}es"); - } - - if (plural4.IsMatch(word)) - { - return plural4.Replace(word, "${keep}s"); - } - - return word; - } - - /// - /// 以指定字符串作为分隔符将指定字符串分隔成数组 - /// - /// 要分割的字符串 - /// 字符串类型的分隔符 - /// 是否移除数据中元素为空字符串的项 - /// 分割后的数据 - public static string[] Split(this string value, string strSplit, bool removeEmptyEntries = false) - { - return value.Split(new[] {strSplit}, - removeEmptyEntries ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None); - } - - /// - /// 支持汉字的字符串长度,汉字长度计为2 - /// - /// 参数字符串 - /// 当前字符串的长度,汉字长度为2 - public static int TextLength(this string value) - { - var ascii = new ASCIIEncoding(); - var tempLen = 0; - var bytes = ascii.GetBytes(value); - foreach (var b in bytes) - { - if (b == 63) - { - tempLen += 2; - } - else - { - tempLen += 1; - } - } - - return tempLen; - } - - /// - /// 将JSON字符串还原为对象 - /// - /// 要转换的目标类型 - /// JSON字符串 - /// - public static T FromJsonString(this string json) - { - Guard.NotNull(json, nameof(json)); - return JsonConvert.DeserializeObject(json); - } - - /// - /// 将JSON字符串还原为对象 - /// - /// JSON字符串 - /// 数据类型 - public static object FromJsonString(this string json, Type type) - { - return JsonConvert.DeserializeObject(json, type); - } - - /// - /// 给URL添加查询参数 - /// - /// URL字符串 - /// 要添加的参数,形如:"id=1,cid=2" - /// - public static string AddUrlQuery(this string url, params string[] queries) - { - foreach (var query in queries) - { - if (!url.Contains("?")) - { - url += "?"; - } - else if (!url.EndsWith("&")) - { - url += "&"; - } - - url += query; - } - - return url; - } - - /// - /// 获取URL中指定参数的值,不存在返回空字符串 - /// - public static string GetUrlQuery(this string url, string key) - { - var uri = new Uri(url); - var query = uri.Query; - if (string.IsNullOrEmpty(query)) - { - return string.Empty; - } - - query = query.TrimStart('?'); - var dict = (from m in query.Split("&", true) - let strs = m.Split("=") - select new KeyValuePair(strs[0], strs[1])) - .ToDictionary(m => m.Key, m => m.Value); - if (dict.ContainsKey(key)) - { - return dict[key]; - } - - return string.Empty; - } - - /// - /// 给URL添加 # 参数 - /// - /// URL字符串 - /// 要添加的参数 - /// - public static string AddHashFragment(this string url, string query) - { - Guard.NotNull(url, nameof(url)); - Guard.NotNull(query, nameof(query)); - - if (!url.Contains("#")) - { - url += "#"; - } - - return url + query; - } - - - - /// - /// 将[]数组转换为Base64字符串 - /// - public static string ToBase64String(this byte[] bytes) - { - Guard.NotNull(bytes, nameof(bytes)); - - return Convert.ToBase64String(bytes); - } - - /// - /// 将字符串转换为Base64字符串,默认编码为 - /// - /// 正常的字符串 - /// 编码 - /// Base64字符串 - public static string ToBase64String(this string source, Encoding encoding = null) - { - Guard.NotNull(source, nameof(source)); - - if (encoding == null) encoding = Encoding.UTF8; - - return Convert.ToBase64String(encoding.GetBytes(source)); - } - - /// - /// 将Base64字符串转换为正常字符串,默认编码为 - /// - /// Base64字符串 - /// 编码 - /// 正常字符串 - public static string FromBase64String(this string base64String, Encoding encoding = null) - { - Guard.NotNull(base64String, nameof(base64String)); - - if (encoding == null) encoding = Encoding.UTF8; - - var bytes = Convert.FromBase64String(base64String); - return encoding.GetString(bytes); - } - - /// - /// 将字符串进行UrlDecode解码 - /// - /// 待UrlDecode解码的字符串 - /// UrlDecode解码后的字符串 - public static string ToUrlDecode(this string source) - { - Guard.NotNull(source, nameof(source)); - - return HttpUtility.UrlDecode(source); - } - - /// - /// 将字符串进行UrlEncode编码 - /// - /// 待UrlEncode编码的字符串 - /// UrlEncode编码后的字符串 - public static string ToUrlEncode(this string source) - { - Guard.NotNull(source, nameof(source)); - - return HttpUtility.UrlEncode(source); - } - - /// - /// 将字符串进行HtmlDecode解码 - /// - /// 待HtmlDecode解码的字符串 - /// HtmlDecode解码后的字符串 - public static string ToHtmlDecode(this string source) - { - Guard.NotNull(source, nameof(source)); - - return HttpUtility.HtmlDecode(source); - } - - /// - /// 将字符串进行HtmlEncode编码 - /// - /// 待HtmlEncode编码的字符串 - /// HtmlEncode编码后的字符串 - public static string ToHtmlEncode(this string source) - { - Guard.NotNull(source, nameof(source)); - - return HttpUtility.HtmlEncode(source); - } - - /// - /// 将字符串转换为十六进制字符串,默认编码为 - /// - public static string ToHexString(this string source, Encoding encoding = null) - { - Guard.NotNull(source, nameof(source)); - - if (encoding == null) encoding = Encoding.UTF8; - - byte[] bytes = encoding.GetBytes(source); - return bytes.ToHexString(); - } - - /// - /// 将十六进制字符串转换为常规字符串,默认编码为 - /// - public static string FromHexString(this string hexString, Encoding encoding = null) - { - Guard.NotNull(hexString, nameof(hexString)); - - if (encoding == null) encoding = Encoding.UTF8; - - var bytes = hexString.ToHexBytes(); - return encoding.GetString(bytes); - } - - /// - /// 将byte[]编码为十六进制字符串 - /// - /// byte[]数组 - /// 十六进制字符串 - public static string ToHexString(this byte[] bytes) - { - Guard.NotNull(bytes, nameof(bytes)); - - return bytes.Aggregate(string.Empty, (current, t) => current + t.ToString("X2")); - } - - /// - /// 将十六进制字符串转换为byte[] - /// - /// 十六进制字符串 - /// byte[]数组 - public static byte[] ToHexBytes(this string hexString) - { - hexString = hexString ?? ""; - hexString = hexString.Replace(" ", ""); - byte[] bytes = new byte[hexString.Length / 2]; - for (int i = 0; i < bytes.Length; i++) - { - bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); - } - - return bytes; - } - - /// - /// 将字符串进行Unicode编码,变成形如“\u7f16\u7801”的形式 - /// - /// 要进行编号的字符串 - public static string ToUnicodeString(this string source) - { - Guard.NotNull(source, nameof(source)); - - var regex = new Regex(@"[^\u0000-\u00ff]"); - return regex.Replace(source, m => string.Format(@"\u{0:x4}", (short) m.Value[0])); - } - - /// - /// 将形如“\u7f16\u7801”的Unicode字符串解码 - /// - public static string FromUnicodeString(this string source) - { - var regex = new Regex(@"\\u([0-9a-fA-F]{4})", RegexOptions.Compiled); - return regex.Replace(source, - m => - { - short s; - if (short.TryParse(m.Groups[1].Value, NumberStyles.HexNumber, CultureInfo.InstalledUICulture, - out s)) - { - return "" + (char) s; - } - - return m.Value; - }); - } - - /// - /// 将驼峰字符串按单词拆分并转换成小写,再以特定字符串分隔 - /// - /// 待转换的字符串 - /// 分隔符字符 - /// - public static string UpperToLowerAndSplit(this string str, string splitStr = "-") - { - if (string.IsNullOrEmpty(str)) - { - return str; - } - - List words = new List(); - while (str.Length > 0) - { - char c = str.FirstOrDefault(char.IsUpper); - if (c == default(char)) - { - words.Add(str); - break; - } - - int upperIndex = str.IndexOf(c); - if (upperIndex < 0) //admin - { - return str; - } - - if (upperIndex > 0) //adminAdmin - { - string first = str.Substring(0, upperIndex); - words.Add(first); - str = str.Substring(upperIndex, str.Length - upperIndex); - continue; - } - - str = char.ToLower(str[0]) + str.Substring(1, str.Length - 1); - } - - return words.ExpandAndToString(splitStr); - } - - /// - /// 将驼峰字符串的第一个字符小写 - /// - public static string LowerFirstChar(this string str) - { - if (string.IsNullOrEmpty(str) || !char.IsUpper(str[0])) - { - return str; - } - - if (str.Length == 1) - { - return char.ToLower(str[0]).ToString(); - } - - return char.ToLower(str[0]) + str.Substring(1, str.Length - 1); - } - - /// - /// 将小驼峰字符串的第一个字符大写 - /// - public static string UpperFirstChar(this string str) - { - if (string.IsNullOrEmpty(str) || !char.IsLower(str[0])) - { - return str; - } - - if (str.Length == 1) - { - return char.ToUpper(str[0]).ToString(); - } - - return char.ToUpper(str[0]) + str.Substring(1, str.Length - 1); - } - - /// - /// 计算当前字符串与指定字符串的编辑距离(相似度) - /// - /// 源字符串 - /// 目标字符串 - /// 输出相似度 - /// 是否忽略大小写 - /// 编辑距离 - public static int LevenshteinDistance(this string source, string target, out double similarity, - bool ignoreCase = false) - { - if (string.IsNullOrEmpty(source)) - { - if (string.IsNullOrEmpty(target)) - { - similarity = 1; - return 0; - } - - similarity = 0; - return target.Length; - } - - if (string.IsNullOrEmpty(target)) - { - similarity = 0; - return source.Length; - } - - string from, to; - if (ignoreCase) - { - from = source; - to = target; - } - else - { - from = source.ToLower(); - to = source.ToLower(); - } - - int m = from.Length, n = to.Length; - int[,] mn = new int[m + 1, n + 1]; - for (int i = 0; i <= m; i++) - { - mn[i, 0] = i; - } - - for (int j = 1; j <= n; j++) - { - mn[0, j] = j; - } - - for (int i = 1; i <= m; i++) - { - char c = from[i - 1]; - for (int j = 1; j <= n; j++) - { - if (c == to[j - 1]) - { - mn[i, j] = mn[i - 1, j - 1]; - } - else - { - mn[i, j] = Math.Min(mn[i - 1, j - 1], Math.Min(mn[i - 1, j], mn[i, j - 1])) + 1; - } - } - } - - int maxLength = Math.Max(m, n); - similarity = (double) (maxLength - mn[m, n]) / maxLength; - return mn[m, n]; - } - - /// - /// 计算两个字符串的相似度,应用公式:相似度=kq*q/(kq*q+kr*r+ks*s)(kq>0,kr>=0,ka>=0) - /// 其中,q是字符串1和字符串2中都存在的单词的总数,s是字符串1中存在,字符串2中不存在的单词总数,r是字符串2中存在,字符串1中不存在的单词总数. kq,kr和ka分别是q,r,s的权重,根据实际的计算情况,我们设kq=2,kr=ks=1. - /// - /// 源字符串 - /// 目标字符串 - /// 是否忽略大小写 - /// 字符串相似度 - public static double GetSimilarityWith(this string source, string target, bool ignoreCase = false) - { - if (string.IsNullOrEmpty(source) && string.IsNullOrEmpty(target)) - { - return 1; - } - - if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(target)) - { - return 0; - } - - const double kq = 2, kr = 1, ks = 1; - char[] sourceChars = source.ToCharArray(), targetChars = target.ToCharArray(); - - //获取交集数量 - int q = sourceChars.Intersect(targetChars).Count(), s = sourceChars.Length - q, r = targetChars.Length - q; - return kq * q / (kq * q + kr * r + ks * s); - } - - /// - /// 标准化Path字符串,将 \\ 转换为 / - /// - /// Path字符串 - public static string NormalizePath(this string path) - { - return path.Replace('\\', '/'); - } - - /// - /// (Pascal) 命名法 的字符串 改为 短横线分隔式命名 - /// 例如UserName => user-name - /// - public static string PascalToKebabCase(this string value) - { - if (string.IsNullOrEmpty(value)) - { - return value; - } - - return Regex.Replace( - value, - "(? - /// StringBuilder 扩展方法类 - /// - public static class StringBuilderExtensions - { - /// - /// 去除开头的空格 - /// - /// - /// 返回修改后的StringBuilder,主要用于链式操作 - public static StringBuilder TrimStart(this StringBuilder stringBuilder) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - - return stringBuilder.TrimStart(' '); - } - - /// - /// 去除开头的指定 - /// - /// - /// 要去掉的 - /// - public static StringBuilder TrimStart(this StringBuilder stringBuilder, char c) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - - if (stringBuilder.Length == 0) - return stringBuilder; - while (c.Equals(stringBuilder[0])) - { - stringBuilder.Remove(0, 1); - } - - return stringBuilder; - } - - /// - /// 去除开头的指定字符数组 - /// - /// - /// 要去掉的字符数组 - /// - public static StringBuilder TrimStart(this StringBuilder stringBuilder, char[] chars) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - Guard.NotNull(chars, nameof(chars)); - - return stringBuilder.TrimStart(new string(chars)); - } - - /// - /// 去除开头的指定的 - /// - /// - /// 要去掉的 - /// - public static StringBuilder TrimStart(this StringBuilder stringBuilder, string str) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - - if (string.IsNullOrEmpty(str) - || stringBuilder.Length == 0 - || str.Length > stringBuilder.Length) - { - return stringBuilder; - } - - while (stringBuilder.SubString(0, str.Length).Equals(str)) - { - stringBuilder.Remove(0, str.Length); - if (str.Length > stringBuilder.Length) - { - break; - } - } - - return stringBuilder; - } - - /// - /// 去除StringBuilder结尾的空格 - /// - /// StringBuilder - /// 返回修改后的StringBuilder,主要用于链式操作 - public static StringBuilder TrimEnd(this StringBuilder stringBuilder) - { - return stringBuilder.TrimEnd(' '); - } - - /// - /// 去除结尾指定字符 - /// - /// - /// 要去掉的字符 - /// - public static StringBuilder TrimEnd(this StringBuilder stringBuilder, char c) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - if (stringBuilder.Length == 0) - { - return stringBuilder; - } - - while (c.Equals(stringBuilder[stringBuilder.Length - 1])) - { - stringBuilder.Remove(stringBuilder.Length - 1, 1); - } - - return stringBuilder; - } - - /// - /// 去除结尾指定字符数组 - /// - /// - /// 要去除的字符数组 - /// - public static StringBuilder TrimEnd(this StringBuilder stringBuilder, char[] chars) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - Guard.NotNull(chars, nameof(chars)); - - return stringBuilder.TrimEnd(new string(chars)); - } - - /// - /// 去除结尾指定字符串 - /// - /// - /// 要去除的字符串 - /// - public static StringBuilder TrimEnd(this StringBuilder stringBuilder, string str) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - if (string.IsNullOrEmpty(str) - || stringBuilder.Length == 0 - || str.Length > stringBuilder.Length) - { - return stringBuilder; - } - while (stringBuilder.SubString(stringBuilder.Length - str.Length, str.Length).Equals(str)) - { - stringBuilder.Remove(stringBuilder.Length - str.Length, str.Length); - if (stringBuilder.Length < str.Length) - { - break; - } - } - - return stringBuilder; - } - - /// - /// 去除StringBuilder两端的空格 - /// - /// StringBuilder - /// 返回修改后的StringBuilder,主要用于链式操作 - public static StringBuilder Trim(this StringBuilder stringBuilder) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - - if (stringBuilder.Length == 0) - return stringBuilder; - return stringBuilder.TrimEnd().TrimStart(); - } - - /// - /// 返回从起始位置指定长度的字符串 - /// - /// - /// 起始位置 - /// 长度 - /// 字符串 - /// 超出字符串索引长度异常 - public static string SubString(this StringBuilder stringBuilder, int start, int length) - { - Guard.NotNull(stringBuilder, nameof(stringBuilder)); - - if (start + length > stringBuilder.Length) - { - throw new IndexOutOfRangeException("超出字符串索引长度"); - } - - var cs = new char[length]; - for (var i = 0; i < length; i++) - { - cs[i] = stringBuilder[start + i]; - } - - return new string(cs); - } - - public static StringBuilder AppendLineWithControlChar(this StringBuilder stringBuilder, StringBuilder sb, string newLine) - { - stringBuilder = AppendWithControlChar(stringBuilder, sb.ToString()); - return stringBuilder.Append(newLine); - } - - public static StringBuilder AppendLineWithControlChar(this StringBuilder stringBuilder, string str, string newLine) - { - stringBuilder = AppendWithControlChar(stringBuilder, str); - return stringBuilder.Append(newLine); - } - - public static StringBuilder AppendWithControlChar(this StringBuilder stringBuilder, StringBuilder sb) - { - return AppendWithControlChar(stringBuilder, sb.ToString()); - } - - public static StringBuilder AppendWithControlChar(this StringBuilder stringBuilder, string str) - { - if (str.Contains('\b')) - { - foreach (var c in str) - { - if (c == '\b') - { - stringBuilder.Length--; - } - else - { - stringBuilder.Append(c); - } - } - } - else - { - stringBuilder.Append(str); - } - - return stringBuilder; - } - - } -} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion.AbpPro.CAP.csproj b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion.AbpPro.CAP.csproj new file mode 100644 index 00000000..ca4481a7 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion.AbpPro.CAP.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.1 + + Lion.AbpPro.CAP + + + + + + + + diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapConsumerServiceSelector.cs b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapConsumerServiceSelector.cs new file mode 100644 index 00000000..d169aac0 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapConsumerServiceSelector.cs @@ -0,0 +1,116 @@ +namespace Lion.AbpPro.CAP; + +[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)] +[ExposeServices(typeof(IConsumerServiceSelector))] +public sealed class AbpProAbpCapConsumerServiceSelector : ConsumerServiceSelector +{ + private AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; } + private IServiceProvider ServiceProvider { get; } + + /// + /// Creates a new . + /// + public AbpProAbpCapConsumerServiceSelector( + IServiceProvider serviceProvider, + IOptions distributedEventBusOptions) + : base(serviceProvider) + { + ServiceProvider = serviceProvider; + AbpDistributedEventBusOptions = distributedEventBusOptions.Value; + } + + protected override IEnumerable FindConsumersFromInterfaceTypes(IServiceProvider provider) + { + var executorDescriptorList = base.FindConsumersFromInterfaceTypes(provider).ToList(); + + //handlers + var handlers = AbpDistributedEventBusOptions.Handlers; + + foreach (var handler in handlers) + { + var interfaces = handler.GetInterfaces(); + foreach (var @interface in interfaces) + { + if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) + { + continue; + } + var genericArgs = @interface.GetGenericArguments(); + + if (genericArgs.Length != 1) + { + continue; + } + + var descriptors = GetHandlerDescription(genericArgs[0], handler); + + foreach (var descriptor in descriptors) + { + var count = executorDescriptorList.Count(x => + x.Attribute.Name == descriptor.Attribute.Name); + + descriptor.Attribute.Group = descriptor.Attribute.Group.Insert( + descriptor.Attribute.Group.LastIndexOf(".", StringComparison.Ordinal), $".{count}"); + + executorDescriptorList.Add(descriptor); + } + + //Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); + } + } + return executorDescriptorList; + } + + private IEnumerable GetHandlerDescription(Type eventType,Type typeInfo) + { + var serviceTypeInfo = typeof(IDistributedEventHandler<>) + .MakeGenericType(eventType); + var method = typeInfo + .GetMethod( + nameof(IDistributedEventHandler.HandleEventAsync), + new[] { eventType } + ); + var eventName = EventNameAttribute.GetNameOrDefault(eventType); + var topicAttr = method.GetCustomAttributes(true); + var topicAttributes = topicAttr.ToList(); + + if (topicAttributes.Count == 0) + { + topicAttributes.Add(new CapSubscribeAttribute(eventName)); + } + + foreach (var attr in topicAttributes) + { + SetSubscribeAttribute(attr); + + var parameters = method.GetParameters() + .Select(parameter => new ParameterDescriptor + { + Name = parameter.Name, + ParameterType = parameter.ParameterType, + IsFromCap = parameter.GetCustomAttributes(typeof(FromCapAttribute)).Any() + }).ToList(); + + yield return InitDescriptor(attr, method, typeInfo.GetTypeInfo(), serviceTypeInfo.GetTypeInfo(), parameters); + } + } + + private static ConsumerExecutorDescriptor InitDescriptor( + TopicAttribute attr, + MethodInfo methodInfo, + TypeInfo implType, + TypeInfo serviceTypeInfo, + IList parameters) + { + var descriptor = new ConsumerExecutorDescriptor + { + Attribute = attr, + MethodInfo = methodInfo, + ImplTypeInfo = implType, + ServiceTypeInfo = serviceTypeInfo, + Parameters = parameters + }; + + return descriptor; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapDistributedEventBus.cs b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapDistributedEventBus.cs new file mode 100644 index 00000000..e9fd7003 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapDistributedEventBus.cs @@ -0,0 +1,160 @@ +namespace Lion.AbpPro.CAP; + +public class AbpProAbpCapDistributedEventBus : + EventBusBase, + IDistributedEventBus, + ISingletonDependency +{ + private AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; } + private ConcurrentDictionary> HandlerFactories { get; } + private ConcurrentDictionary EventTypes { get; } + + private readonly ICapPublisher CapPublisher; + + + public AbpProAbpCapDistributedEventBus(IServiceScopeFactory serviceScopeFactory, + IOptions distributedEventBusOptions, + ICapPublisher capPublisher, + ICurrentTenant currentTenant, + UnitOfWorkManager unitOfWorkManager, + IEventHandlerInvoker eventHandlerInvoker) + : base(serviceScopeFactory, currentTenant,unitOfWorkManager,eventHandlerInvoker) + { + CapPublisher = capPublisher; + AbpDistributedEventBusOptions = distributedEventBusOptions.Value; + HandlerFactories = new ConcurrentDictionary>(); + EventTypes = new ConcurrentDictionary(); + } + + public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) + { + //This is handled by CAP ConsumerServiceSelector + throw new NotImplementedException(); + } + + public override void Unsubscribe(Func action) + { + Check.NotNull(action, nameof(action)); + + GetOrCreateHandlerFactories(typeof(TEvent)) + .Locking(factories => + { + factories.RemoveAll( + factory => + { + var singleInstanceFactory = factory as SingleInstanceHandlerFactory; + if (singleInstanceFactory == null) + { + return false; + } + + var actionHandler = singleInstanceFactory.HandlerInstance as ActionEventHandler; + if (actionHandler == null) + { + return false; + } + + return actionHandler.Action == action; + }); + }); + } + + public override void Unsubscribe(Type eventType, IEventHandler handler) + { + GetOrCreateHandlerFactories(eventType) + .Locking(factories => + { + factories.RemoveAll( + factory => + factory is SingleInstanceHandlerFactory && + (factory as SingleInstanceHandlerFactory).HandlerInstance == handler + ); + }); + } + + public override void Unsubscribe(Type eventType, IEventHandlerFactory factory) + { + GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory)); + } + + public override void UnsubscribeAll(Type eventType) + { + GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear()); + } + + protected override Task PublishToEventBusAsync(Type eventType, object eventData) + { + throw new NotImplementedException(); + } + + protected override void AddToUnitOfWork(IUnitOfWork unitOfWork, UnitOfWorkEventRecord eventRecord) + { + throw new NotImplementedException(); + } + + public IDisposable Subscribe(IDistributedEventHandler handler) where TEvent : class + { + return Subscribe(typeof(TEvent), handler); + } + + public async Task PublishAsync(TEvent eventData, bool onUnitOfWorkComplete = true, + bool useOutbox = true) where TEvent : class + { + var eventName = EventNameAttribute.GetNameOrDefault(typeof(TEvent)); + await CapPublisher.PublishAsync(eventName, eventData); + + } + + public async Task PublishAsync(Type eventType, object eventData, bool onUnitOfWorkComplete = true, + bool useOutbox = true) + { + var eventName = EventNameAttribute.GetNameOrDefault(eventType); + await CapPublisher.PublishAsync(eventName, eventData); + } + + + protected override IEnumerable GetHandlerFactories(Type eventType) + { + var handlerFactoryList = new List(); + + foreach (var handlerFactory in + HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key))) + { + handlerFactoryList.Add( + new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value)); + } + + return handlerFactoryList.ToArray(); + } + + private List GetOrCreateHandlerFactories(Type eventType) + { + return HandlerFactories.GetOrAdd( + eventType, + type => + { + var eventName = EventNameAttribute.GetNameOrDefault(type); + EventTypes[eventName] = type; + return new List(); + } + ); + } + + private static bool ShouldTriggerEventForHandler(Type targetEventType, Type handlerEventType) + { + //Should trigger same type + if (handlerEventType == targetEventType) + { + return true; + } + + //TODO: Support inheritance? But it does not support on subscription to RabbitMq! + //Should trigger for inherited types + if (handlerEventType.IsAssignableFrom(targetEventType)) + { + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapModule.cs b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapModule.cs new file mode 100644 index 00000000..55c1303a --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapModule.cs @@ -0,0 +1,6 @@ +namespace Lion.AbpPro.CAP; + +[DependsOn(typeof(AbpEventBusModule))] +public class AbpProAbpCapModule : AbpModule +{ +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapServiceCollectionExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapServiceCollectionExtensions.cs new file mode 100644 index 00000000..7d4bf53f --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/AbpProAbpCapServiceCollectionExtensions.cs @@ -0,0 +1,14 @@ +namespace Lion.AbpPro.CAP; + +public static class AbpProAbpCapServiceCollectionExtensions +{ + public static ServiceConfigurationContext AddAbpCap( + this ServiceConfigurationContext context, + Action capAction) + { + context.Services.AddCap(capAction); + context.Services.AddSingleton(); + context.Services.AddSingleton(); + return context; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/GlobalUsings.cs b/aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/GlobalUsings.cs similarity index 100% rename from aspnet-core/frameworks/CAP/src/Lion.AbpPro.CAP/GlobalUsings.cs rename to aspnet-core/frameworks/src/Lion.AbpPro.CAP/Lion/AbpPro/CAP/GlobalUsings.cs diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/GlobalUsings.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/GlobalUsings.cs new file mode 100644 index 00000000..db552e04 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/GlobalUsings.cs @@ -0,0 +1,9 @@ +// Global using directives + +global using System.ComponentModel.DataAnnotations; +global using System.Diagnostics; +global using System.Globalization; +global using System.Text; +global using System.Text.RegularExpressions; +global using System.Web; +global using Lion.AbpPro.Core; \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion.AbpPro.Core.csproj b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion.AbpPro.Core.csproj new file mode 100644 index 00000000..9a4b8e00 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion.AbpPro.Core.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.1 + Lion.AbpPro.Core + + + + + + + + + + + diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/CustomListResultDto.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/CustomListResultDto.cs new file mode 100644 index 00000000..8e5e455d --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/CustomListResultDto.cs @@ -0,0 +1,22 @@ +namespace Lion.AbpPro.Core; + +[Serializable] +public class CustomListResultDto +{ + public IReadOnlyList Items + { + get { return _items ??= new List(); } + set => _items = value; + } + + private IReadOnlyList _items; + + public CustomListResultDto() + { + } + + public CustomListResultDto(IReadOnlyList items) + { + Items = items; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/CustomPagedResultDto.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/CustomPagedResultDto.cs new file mode 100644 index 00000000..9c167a1c --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/CustomPagedResultDto.cs @@ -0,0 +1,17 @@ +namespace Lion.AbpPro.Core; + +[Serializable] +public class CustomPagedResultDto : CustomListResultDto +{ + public long TotalCount { get; set; } + + public CustomPagedResultDto() + { + } + + public CustomPagedResultDto(long totalCount, IReadOnlyList items) + : base(items) + { + TotalCount = totalCount; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/FromSelector.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/FromSelector.cs new file mode 100644 index 00000000..9a920f72 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/FromSelector.cs @@ -0,0 +1,39 @@ +namespace Lion.AbpPro.Core; + +public abstract class FromSelectorBase +{ + protected FromSelectorBase(int value, string label) + { + Value = value; + Label = label; + } + + public int Value { get; protected set; } + public string Label { get; protected set; } +} + +public abstract class FromSelectorBase +{ + protected FromSelectorBase(TValue value, TLabel label) + { + Value = value; + Label = label; + } + + public TValue Value { get; protected set; } + public TLabel Label { get; protected set; } +} + +public class FromSelector : FromSelectorBase +{ + public FromSelector(int value, string label) : base(value, label) + { + } +} + +public class FromSelector : FromSelectorBase +{ + public FromSelector(TValue value, TLabel label) : base(value, label) + { + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/Guard.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/Guard.cs new file mode 100644 index 00000000..8b9bd719 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/Guard.cs @@ -0,0 +1,262 @@ +namespace Lion.AbpPro.Core; + +/// +/// 参数合法性检查类 +/// +public static class Guard +{ + /// + /// 检查参数不能为空引用, + /// + /// + /// 参数名称 + public static T NotNull(T value, string valueName) + { + if (null == value) + { + throw new ArgumentNullException(valueName); + } + + return value; + } + + /// + /// 检查字符串不能为空引用或空字符串, + /// + /// + /// 参数名称。 + /// 字符串允许的最大长度。 + /// 字符串允许的最小长度。0表示不限制最小长度 + public static string NotNullOrEmpty(string value, string valueName, int maxLength = int.MaxValue, + int minLength = 0) + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentNullException(valueName); + } + + if (value.Length > maxLength) + { + throw new ArgumentOutOfRangeException(valueName); + } + + if (minLength > 0 && value.Length < minLength) + { + throw new ArgumentOutOfRangeException(valueName); + } + + return value; + } + + /// + /// 检查字符串不能为空引用或全部为空白, + /// + /// 需检查的字符串 + /// 参数名称。 + /// 字符串允许的最大长度。 + /// 字符串允许的最小长度。0表示不限制最小长度 + public static string NotNullOrWhiteSpace( + string value, + string valueName, + int maxLength = int.MaxValue, + int minLength = 0) + { + if (string.IsNullOrWhiteSpace(value)) + { + throw new ArgumentNullException(valueName); + } + + if (value.Length > maxLength) + { + throw new ArgumentOutOfRangeException(valueName); + } + + if (minLength > 0 && value.Length < minLength) + { + throw new ArgumentOutOfRangeException(valueName); + } + + return value; + } + + /// + /// 检查字符串长度是否超过最大长度,或低于最小长度, + /// + /// 需检查的字符串。 + /// 参数名称。 + /// 字符串允许的最大长度。 + /// 字符串要求的最小长度。0表示不限制最小长度 + public static string Length(string value, string valueName, int maxLength = int.MaxValue, + int minLength = 0) + { + if (string.IsNullOrEmpty(value)) + { + return value; + } + + if (value.Length > maxLength) + { + throw new ArgumentOutOfRangeException(valueName); + } + + if (minLength > 0 && value.Length < minLength) + { + throw new ArgumentOutOfRangeException(valueName); + } + + return value; + } + + /// + /// 检查Guid值不能为Guid.Empty + /// + /// + /// 参数名称。 + public static Guid NotEmpty( + Guid value, + string valueName) + { + if (value == Guid.Empty) + { + throw new ArgumentNullException(valueName); + } + + return value; + } + + /// + /// 检查集合不能为空引用或空集合, + /// + /// 集合项的类型。 + /// + /// 参数名称。 + public static void NotNullOrEmpty( + IReadOnlyList list, + string valueName) + { + if (null == list || !list.Any()) + { + throw new ArgumentNullException(valueName); + } + } + + /// + /// 检查参数必须小于[或可等于,参数]指定值, + /// + /// 参数类型。 + /// + /// 参数名称。 + /// 要比较的值。 + /// 是否可等于。 + public static void LessThan( + T value, + string valueName, + T target, + bool canEqual = false) + where T : IComparable + { + var flag = canEqual ? value.CompareTo(target) <= 0 : value.CompareTo(target) < 0; + if (!flag) + { + throw new ArgumentOutOfRangeException(valueName); + } + } + + /// + /// 检查参数必须大于[或可等于,参数]指定值, + /// + /// 参数类型。 + /// 需检查的参数。 + /// 参数名称。 + /// 要比较的值。 + /// 是否可等于。 + public static void GreaterThan( + T value, + string valueName, + T target, + bool canEqual = false) + where T : IComparable + { + var flag = canEqual ? value.CompareTo(target) >= 0 : value.CompareTo(target) > 0; + if (!flag) + { + throw new ArgumentOutOfRangeException(valueName); + } + } + + /// + /// 检查参数必须在指定范围之间 + /// + /// 参数类型。 + /// 需检查的参数。 + /// 参数名称。 + /// 比较范围的起始值。 + /// 比较范围的结束值。 + /// 是否可等于起始值 + /// 是否可等于结束值 + public static void Between( + T value, + string valueName, + T start, + T end, + bool startEqual = false, + bool endEqual = false) + where T : IComparable + { + var flag = startEqual ? value.CompareTo(start) >= 0 : value.CompareTo(start) > 0; + if (!flag) + { + throw new ArgumentOutOfRangeException(valueName); + } + + flag = endEqual ? value.CompareTo(end) <= 0 : value.CompareTo(end) < 0; + if (!flag) + { + throw new ArgumentOutOfRangeException(valueName); + } + } + + /// + /// 检查指定路径的文件夹必须存在, + /// + /// 需检查的路径。 + /// 参数名称。 + public static string DirectoryExists( + string directory, + string parameterName) + { + if (string.IsNullOrWhiteSpace(directory)) + { + throw new DirectoryNotFoundException(parameterName); + } + + if (!Directory.Exists(directory)) + { + throw new DirectoryNotFoundException(directory); + } + + return directory; + } + + /// + /// 检查指定路径的文件必须存在,否则抛出 + /// + /// + /// 参数名称。 + public static string FileExists( + string filename, + string valueName) + { + if (string.IsNullOrWhiteSpace(filename)) + { + throw new ArgumentNullException(valueName); + } + + if (!File.Exists(filename)) + { + throw new FileNotFoundException(filename); + } + + return filename; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/IdInput.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/IdInput.cs new file mode 100644 index 00000000..4456fcde --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/IdInput.cs @@ -0,0 +1,6 @@ +namespace Lion.AbpPro.Core; + +public class IdInput +{ + public Guid Id { get; set; } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/LionAbpProCoreModule.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/LionAbpProCoreModule.cs new file mode 100644 index 00000000..ece7f5dc --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/LionAbpProCoreModule.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Modularity; + +namespace Lion.AbpPro.Core; + +[DependsOn(typeof(LionAbpProLocalizationModule))] +public class LionAbpProCoreModule : AbpModule +{ +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/PagingBase.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/PagingBase.cs new file mode 100644 index 00000000..33bbd28f --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/PagingBase.cs @@ -0,0 +1,53 @@ +namespace Lion.AbpPro.Core; + +/// +/// 分页查询时使用的Dto类型 +/// +public class PagingBase : IValidatableObject +{ + public const int MaxPageSize = 100000; + + /// + /// 当前页面.默认从1开始 + /// + public int PageIndex { get; set; } = 1; + + /// + /// 每页多少条.每页显示多少记录 + /// + public int PageSize { get; set; } = 10; + + /// + /// 跳过多少条 + /// + public int SkipCount => (PageIndex - 1) * PageSize; + + protected PagingBase() + { + } + + public PagingBase(int pageIndex = 1, int pageSize = 10) + { + PageIndex = pageIndex; + PageSize = pageSize; + } + + public virtual IEnumerable Validate(ValidationContext validationContext) + { + if (PageIndex < 1) + { + yield return new ValidationResult( + "起始页必须大于等于1", + new[] { "PageIndex"} + ); + } + + if (PageSize > MaxPageSize) + { + yield return new ValidationResult( + $"每页最大记录数不能超过'{MaxPageSize}'", + new[] { "PageSize"} + ); + } + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/WrapResult.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/WrapResult.cs new file mode 100644 index 00000000..292522bc --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/WrapResult.cs @@ -0,0 +1,35 @@ +namespace Lion.AbpPro.Core; + +public class WrapResult +{ + public bool Success { get; private set; } + + public string Message { get; private set; } + + public T Data { get; private set; } + + public int Code { get; private set; } + + public WrapResult() + { + Success = true; + Message = "Success"; + Data = default; + Code = 200; + } + + public void SetSuccess(T data, string message = "Success", int code = 200) + { + Success = true; + Data = data; + Code = code; + } + + public void SetFail(string message = "Fail", int code = 500) + { + Success = false; + Message = message; + Code = code; + } + +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/WrapResultAttribute.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/WrapResultAttribute.cs new file mode 100644 index 00000000..efbd4946 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/Lion/AbpPro/Core/WrapResultAttribute.cs @@ -0,0 +1,5 @@ +namespace Lion.AbpPro.Core; + +public class WrapResultAttribute : Attribute +{ +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/BooleanExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/BooleanExtensions.cs new file mode 100644 index 00000000..05e3e2ec --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/BooleanExtensions.cs @@ -0,0 +1,26 @@ +namespace System; + +/// +/// 布尔值类型的扩展辅助操作类 +/// +public static class BooleanExtensions +{ + /// + /// 把布尔值转换为小写字符串 + /// + public static string ToLower(this bool value) + { + return value.ToString().ToLower(); + } + + /// + /// 如果条件成立,则抛出异常 + /// + public static void TrueThrow(this bool flag, Exception exception) + { + if (flag) + { + throw exception; + } + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Collections/Generic/CollectionExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Collections/Generic/CollectionExtensions.cs new file mode 100644 index 00000000..c0714cab --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Collections/Generic/CollectionExtensions.cs @@ -0,0 +1,100 @@ +namespace System.Collections.Generic; + +/// +/// 集合扩展方法 +/// +public static class CollectionExtensions +{ + /// + /// 如果条件成立,添加项 + /// + public static void AddIf(this ICollection collection, T value, bool flag) + { + if (collection is null) throw new ArgumentNullException(); + if (flag) + { + collection.Add(value); + } + } + + /// + /// 如果条件成立,添加项 + /// + public static void AddIf(this ICollection collection, T value, Func func) + { + if (collection is null) throw new ArgumentNullException(); + if (func()) + { + collection.Add(value); + } + } + + /// + /// 如果不存在,添加项 + /// + public static void AddIfNotExist(this ICollection collection, T value, Func existFunc = null) + { + if (collection is null) throw new ArgumentNullException(); + var exists = existFunc == null ? collection!.Contains(value) : collection!.Any(existFunc); + if (!exists) + { + collection!.Add(value); + } + } + + /// + /// 如果不为空,添加项 + /// + public static void AddIfNotNull(this ICollection collection, T value) where T : class + { + if (collection is null) throw new ArgumentNullException(); + if (value != null) + { + collection!.Add(value); + } + } + + /// + /// 获取对象,不存在对使用委托添加对象 + /// + public static T GetOrAdd(this ICollection collection, Func selector, Func factory) + { + if (collection is null) throw new ArgumentNullException(); + T item = collection.FirstOrDefault(selector); + if (item == null) + { + item = factory(); + collection.Add(item); + } + + return item; + } + + + /// + /// 判断数字集合是否是连续的 + /// + /// 如果参数集合为null或空集合,则返回false + public static bool IsContinuous(this List numList) + { + if (numList == null || numList.Count == 0) + { + return false; + } + + numList.Sort((x, y) => -x.CompareTo(y)); //降序 + bool result = false; + var totalCount = numList.Count(); + for (int i = 0; i < totalCount - 1; i++) + { + result = numList[i] - numList[i + 1] == 1; + + if (!result) + { + break; + } + } + + return result; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/DateTimeExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/DateTimeExtensions.cs new file mode 100644 index 00000000..825f70ed --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/DateTimeExtensions.cs @@ -0,0 +1,237 @@ +namespace System; + +/// +/// 时间扩展操作类 +/// +public static class DateTimeExtensions +{ + /// + /// 当前时间是否周末 + /// + /// 时间点 + /// + public static bool IsWeekend(this DateTime dateTime) + { + DayOfWeek[] weeks = + { + DayOfWeek.Saturday, + DayOfWeek.Sunday + }; + return weeks.Contains(dateTime.DayOfWeek); + } + + /// + /// 当前时间是否工作日 + /// + /// 时间点 + /// + public static bool IsWeekday(this DateTime dateTime) + { + DayOfWeek[] weeks = + { + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday + }; + return weeks.Contains(dateTime.DayOfWeek); + } + + /// + /// 获取时间相对唯一字符串 + /// + /// + /// 是否使用毫秒 + /// + public static string ToUniqueString(this DateTime dateTime, bool millisecond = false) + { + var seconds = dateTime.Hour * 3600 + dateTime.Minute * 60 + dateTime.Second; + var value = $"{dateTime:yyyy}{dateTime.DayOfYear}{seconds}"; + if (millisecond) + { + return value + dateTime.ToString("fff"); + } + + return value; + } + + /// + /// 将时间转换为JS时间格式(Date.getTime()) + /// + /// + /// 是否使用毫秒 + public static string ToJsGetTime(this DateTime dateTime, bool millisecond = true) + { + var utc = dateTime.ToUniversalTime(); + var span = utc.Subtract(new DateTime(1970, 1, 1)); + return Math.Round(millisecond ? span.TotalMilliseconds : span.TotalSeconds).ToString(CultureInfo.InvariantCulture); + } + + + /// + /// 将时间类型转成int类型. 例如 2021-09-01 => 20210901 + /// + public static int ToYyyyMmDd(this DateTime dateTime) + { + // 2021-09-01 => 2021*10000 + 09*100 + 1 + return dateTime.Year * 10000 + dateTime.Month * 100 + dateTime.Day; + } + + /// + /// 将时间类型转成int类型. 例如 2021-09-01 => 202109 + /// + public static int ToYyyyMm(this DateTime dateTime) + { + // 2021-09-06 => 2021*100+09 + return dateTime.Year * 100 + dateTime.Month; + } + + /// + /// 获取指定日期 当天的最大时间 + /// 例如 2021-09-10 11:22:33.123456 转换后 2021-09-10 23:59:59.9999999 + /// + public static DateTime? ToCurrentDateMaxDateTime(this DateTime? dateTime) + { + return dateTime?.Date.AddDays(1).AddTicks(-1); + } + + /// + /// 获取指定日期 当天的最大时间 + /// 例如 2021-09-10 11:22:33.123456 转换后 2021-09-10 23:59:59.9999999 + /// + public static DateTime ToCurrentDateMaxDateTime(this DateTime dateTime) + { + return dateTime.Date.AddDays(1).AddTicks(-1); + } + + /// + /// 获取指定日期 当天的最小时间 + /// + public static DateTime? ToCurrentDateMinDateTime(this DateTime? dateTime) + { + return dateTime?.Date.AddTicks(1); + } + + /// + /// 获取指定日期 当天的最小时间 + /// + public static DateTime ToCurrentDateMinDateTime(this DateTime dateTime) + { + return dateTime.Date.AddTicks(1); + } + + /// + /// 获取指定时间的下一秒 + /// 例如 2021-09-10 11:11:11.1234567 转换后 2021-09-10 11:11:12.0000000 + /// + public static DateTime? ToNextSecondDateTime(this DateTime? dateTime) + { + if (!dateTime.HasValue) + { + return null; + } + + return new DateTime(dateTime.Value.Year, dateTime.Value.Month, dateTime.Value.Day, dateTime.Value.Hour, dateTime.Value.Minute, dateTime.Value.Second).AddSeconds(1); + } + + /// + /// 转为秒级时间戳 + /// 默认 TimeZoneInfo.Utc + /// + public static long ToSecondTimeStamp(this DateTime dateTime, TimeZoneInfo timeZoneInfo = null) + { + timeZoneInfo ??= TimeZoneInfo.Utc; + var dtStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0), timeZoneInfo); + long timeStamp = Convert.ToInt32((dateTime - dtStart).TotalSeconds); + return timeStamp; + } + + /// + /// 转为秒级时间戳 + /// 默认 TimeZoneInfo.Utc + /// + public static long? ToSecondTimeStamp(this DateTime? dateTime, TimeZoneInfo timeZoneInfo = null) + { + if (!dateTime.HasValue) return null; + timeZoneInfo ??= TimeZoneInfo.Utc; + var dtStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0), timeZoneInfo); + long timeStamp = Convert.ToInt32((dateTime.Value - dtStart).TotalSeconds); + return timeStamp; + } + + /// + /// 转为毫秒级时间戳 + /// 默认 TimeZoneInfo.Utc + /// + public static long ToMilliSecondTimeStamp(this DateTime dateTime, TimeZoneInfo timeZoneInfo = null) + { + timeZoneInfo ??= TimeZoneInfo.Utc; + var dtStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0), timeZoneInfo); + var timeStamp = Convert.ToInt64((dateTime - dtStart).TotalMilliseconds); + return timeStamp; + } + + /// + /// 转为毫秒级时间戳 + /// 默认 TimeZoneInfo.Utc + /// + public static long? ToMilliSecondTimeStamp(this DateTime? dateTime, TimeZoneInfo timeZoneInfo = null) + { + if (!dateTime.HasValue) return null; + timeZoneInfo ??= TimeZoneInfo.Utc; + var dtStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0), timeZoneInfo); + var timeStamp = Convert.ToInt64((dateTime.Value - dtStart).TotalMilliseconds); + return timeStamp; + } + + /// + /// 秒级时间戳转为时间 + /// 默认 TimeZoneInfo.Utc + /// + public static DateTime ToDateTimeBySecondTimeStamp(this long timestamp, TimeZoneInfo timeZoneInfo = null) + { + timeZoneInfo ??= TimeZoneInfo.Utc; + var dtStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0), timeZoneInfo); + var time = dtStart.AddSeconds(timestamp); + return time; + } + + /// + /// 秒级时间戳转为时间 + /// 默认 TimeZoneInfo.Utc + /// + public static DateTime? ToDateTimeBySecondTimeStamp(this long? timestamp, TimeZoneInfo timeZoneInfo = null) + { + if (!timestamp.HasValue) return null; + timeZoneInfo ??= TimeZoneInfo.Utc; + var dtStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0), timeZoneInfo); + var time = dtStart.AddSeconds(timestamp.Value); + return time; + } + + /// + /// 毫秒级时间戳转为时间 + /// 默认 TimeZoneInfo.Utc + /// + public static DateTime ToDateTimeByMilliSecondTimeStamp(this long timestamp, TimeZoneInfo timeZoneInfo = null) + { + timeZoneInfo ??= TimeZoneInfo.Utc; + var dtStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0), timeZoneInfo); + var time = dtStart.AddMilliseconds(timestamp); + return time; + } + + /// + /// 毫秒级时间戳转为时间 + /// 默认 TimeZoneInfo.Utc + /// + public static DateTime? ToDateTimeByMilliSecondTimeStamp(this long? timestamp, TimeZoneInfo timeZoneInfo = null) + { + if (!timestamp.HasValue) return null; + timeZoneInfo ??= TimeZoneInfo.Utc; + var dtStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0), timeZoneInfo); + var time = dtStart.AddMilliseconds(timestamp.Value); + return time; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/DecimalExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/DecimalExtensions.cs new file mode 100644 index 00000000..aeb6fc99 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/DecimalExtensions.cs @@ -0,0 +1,34 @@ +namespace System; + +/// +/// Decimal扩展操作类 +/// +public static class DecimalExtensions +{ + /// + /// 移除小数点后面的零 + /// + public static decimal TrimEndZero(this decimal number) + { + var str = number.ToString(CultureInfo.InvariantCulture); + if (str.Contains('.')) + { + return Convert.ToDecimal(str.TrimEnd('0').TrimEnd('.')); + } + + return Convert.ToDecimal(str); + } + + /// + /// 移除小数点后面的零 + /// + public static decimal? TrimEndZero(this decimal? number) + { + if (number.HasValue) + { + return TrimEndZero(number.Value); + } + + return null; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/EnumExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/EnumExtensions.cs new file mode 100644 index 00000000..2f96211c --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/EnumExtensions.cs @@ -0,0 +1,195 @@ +using System.Collections.Specialized; +using System.ComponentModel; +using System.Reflection; + +namespace System; + +/// +/// 枚举的扩展辅助操作方法 +/// +public static class EnumExtensions +{ + /// + /// 获取枚举项上的特性的文字描述 + /// + /// + /// + public static string ToDescription(this Enum value) + { + var type = value.GetType(); + var member = type.GetMember(value.ToString()).FirstOrDefault(); + + return member != null ? member.GetDescription() : value.ToString(); + } + + /// + /// 枚举遍历,返回枚举的名称、值、特性 + /// + /// 枚举类型 + /// 回调函数 + private static void Each(this Type enumType, Action action) + { + if (enumType.BaseType != typeof(Enum)) + { + return; + } + var arr = Enum.GetValues(enumType); + foreach (var name in arr) + { + var currentEnum = Enum.Parse(enumType, name.ToString()); + var value = Convert.ToInt32(Enum.Parse(enumType, name.ToString())); + var fieldInfo = enumType.GetField(name.ToString()); + var description = ""; + if (fieldInfo != null) + { + var attr = Attribute.GetCustomAttribute(fieldInfo, + typeof(DescriptionAttribute), false) as DescriptionAttribute; + if (attr != null) + { + description = attr.Description; + } + } + action(name.ToString(), value.ToString(), description, currentEnum); + } + } + + /// + /// 根据枚举类型值返回枚举定义Description属性 + /// + /// + /// + /// + public static string ToEnumDescriptionString(this short value, Type enumType) + { + var nvc = new NameValueCollection(); + var typeDescription = typeof(DescriptionAttribute); + var fields = enumType.GetFields(); + foreach (var field in fields) + { + if (field.FieldType.IsEnum) + { + var strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString(); + var arr = field.GetCustomAttributes(typeDescription, true); + string strText; + if (arr.Length > 0) + { + var aa = (DescriptionAttribute)arr[0]; + strText = aa.Description; + } + else + { + strText = ""; + } + nvc.Add(strValue, strText); + } + } + return nvc[value.ToString()]; + } + + /// + /// 将指定枚举转换为字典. + /// 枚举的Description为字典的Key,枚举的Value为字典的Value + /// + /// 指定枚举 + private static List> GetEnumTypeValueList() + { + var items = new List>(); + typeof(T).Each((name, value, description, enumObj) => + items.Add(new KeyValuePair(description, value))); + return items; + } + + /// + /// 将指定枚举转换为字典. + /// 枚举的Description为字典的Key,枚举为字典的Value + /// + /// 指定枚举 + private static List> GetEnumTypeList() + { + var items = new List>(); + typeof(T).Each((name, value, description, enumObj) => + items.Add(new KeyValuePair(description, (T)enumObj))); + return items; + } + + /// + /// 将指定枚举转换为字典. + /// 枚举的Description为字典的Key,枚举的Name为字典的Value + /// + /// 指定枚举 + public static List> GetEnumTypeDescriptionNameList() + { + var items = new List>(); + typeof(T).Each((name, value, description, enumObj) => items.Add(new KeyValuePair(description, name))); + return items; + } + + /// + /// 将指定枚举转换为字典. + /// 枚举的Name为字典的Key,枚举的Description为字典的Value + /// + /// 指定枚举 + public static List> GetEnumTypeValueNameList() + { + var items = new List>(); + typeof(T).Each((name, value, description, enumObj) => items.Add(new KeyValuePair(name, description))); + return items; + } + + /// + /// 将指定枚举转换为字典. + /// 枚举的Name为字典的Key,枚举的Description为字典的Value + /// + /// 指定枚举 + public static List> GetStringKeyValueList() where TModel : Enum + { + var keyValuePairList = new List>(); + var values = Enum.GetValues(typeof(TModel)); + var modelArray = new TModel[values.Length]; + values.CopyTo(modelArray, 0); + foreach (TModel model in modelArray) + keyValuePairList.Add(new KeyValuePair(model.ToString(), model.ToString())); + return keyValuePairList; + } + + /// + /// 将指定枚举转换为字典. + /// 枚举的Description为字典的Key,枚举为字典的Value + /// + /// 指定枚举 + public static List> GetEnumKeyValueList() where TModel : Enum + { + var enumTypeList = GetEnumTypeList(); + var keyValuePairList = new List>(); + foreach (KeyValuePair keyValuePair in enumTypeList) + keyValuePairList.Add(new KeyValuePair(keyValuePair.Key, keyValuePair.Value)); + return keyValuePairList; + } + + public static List> GetEntityDoubleStringKeyValueList() + { + var enumTypeList = GetEnumTypeValueList(); + var keyValuePairList = new List>(); + foreach (KeyValuePair keyValuePair in enumTypeList) + keyValuePairList.Add(new KeyValuePair(keyValuePair.Key, keyValuePair.Value)); + return keyValuePairList; + } + + public static List> GetEntityStringIntKeyValueList() + { + List> enumTypeList = GetEnumTypeValueList(); + List> keyValuePairList = new List>(); + foreach (KeyValuePair keyValuePair in enumTypeList) + keyValuePairList.Add(new KeyValuePair(keyValuePair.Key, Convert.ToInt32(keyValuePair.Value))); + return keyValuePairList; + } + + public static List> GetEntityDoubleIntKeyValueList() + { + List> enumTypeList = GetEnumTypeValueList(); + List> keyValuePairList = new List>(); + foreach (KeyValuePair keyValuePair in enumTypeList) + keyValuePairList.Add(new KeyValuePair(Convert.ToInt32(keyValuePair.Key), Convert.ToInt32(keyValuePair.Value))); + return keyValuePairList; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/ExceptionExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/ExceptionExtensions.cs new file mode 100644 index 00000000..3b945f9b --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/ExceptionExtensions.cs @@ -0,0 +1,74 @@ +using System.Runtime.ExceptionServices; + +namespace System; + +/// +/// 异常操作扩展 +/// +public static class ExceptionExtensions +{ + /// + /// 格式化异常消息 + /// + /// 异常对象 + /// 是否隐藏异常规模信息 + /// 格式化后的异常信息字符串 + public static string FormatMessage(this Exception e, bool isHideStackTrace = false) + { + var sb = new StringBuilder(); + var count = 0; + var appString = string.Empty; + while (e != null) + { + if (count > 0) + { + appString += " "; + } + sb.AppendLine($"{appString}异常消息:{e.Message}"); + sb.AppendLine($"{appString}异常类型:{e.GetType().FullName}"); + sb.AppendLine($"{appString}异常方法:{(e.TargetSite == null ? null : e.TargetSite.Name)}"); + sb.AppendLine($"{appString}异常源:{e.Source}"); + if (!isHideStackTrace && e.StackTrace != null) + { + sb.AppendLine($"{appString}异常堆栈:{e.StackTrace}"); + } + if (e.InnerException != null) + { + sb.AppendLine($"{appString}内部异常:"); + count++; + e = e.InnerException; + } + } + return sb.ToString(); + } + + /// + /// 将异常重新抛出 + /// + public static void ReThrow(this Exception exception) + { + ExceptionDispatchInfo.Capture(exception).Throw(); + } + + /// + /// 如果条件成立,则抛出异常 + /// + public static void ThrowIf(this Exception exception, bool isThrow) + { + if (isThrow) + { + throw exception; + } + } + + /// + /// 如果条件成立,则抛出异常 + /// + public static void ThrowIf(this Exception exception, Func isThrowFunc) + { + if (isThrowFunc()) + { + throw exception; + } + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/GuidExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/GuidExtensions.cs new file mode 100644 index 00000000..1d794235 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/GuidExtensions.cs @@ -0,0 +1,14 @@ +namespace System; + +public static class GuidExtensions +{ + public static bool IsNullOrEmpty(this Guid? value) + { + return value == null || value.Value == Guid.Empty; + } + + public static bool IsNullOrEmpty(this Guid value) + { + return value == Guid.Empty; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Int32Extensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Int32Extensions.cs new file mode 100644 index 00000000..025ec02f --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Int32Extensions.cs @@ -0,0 +1,23 @@ +namespace System; + +/// +/// int 扩展方法 +/// +public static class Int32Extensions +{ + /// + /// 将 反转换. + /// 例如 20210826 => 2021-08-26 + /// + public static DateTime YyyyMmDdToTime(this int value) + { + var canParse = DateTime.TryParseExact(value.ToString(), "yyyyMMdd", null, DateTimeStyles.None, + out var result); + if (!canParse) + { + throw new Exception("not can parse"); + } + + return result; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/MemberInfoExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/MemberInfoExtensions.cs new file mode 100644 index 00000000..f34de4b2 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/MemberInfoExtensions.cs @@ -0,0 +1,71 @@ +using System.ComponentModel; + +namespace System.Reflection; + +/// +/// 成员的扩展辅助操作方法 +/// +public static class MemberInfoExtensions +{ + + /// + /// 获取成员元数据的Description特性描述信息。 + /// + /// 成员元数据对象。 + /// 是否搜索成员的继承链以查找描述特性。 + /// 返回Description特性描述信息,如不存在则返回成员的名称。 + public static string GetDescription(this MemberInfo member, bool inherit = true) + { + var desc = member.GetAttribute(inherit); + if (desc != null) + { + return desc.Description; + } + + var displayName = member.GetAttribute(inherit); + if (displayName != null) + { + return displayName.DisplayName; + } + + var display = member.GetAttribute(inherit); + return display != null ? display.Name : member.Name; + } + + /// + /// 检查指定指定类型成员中是否存在指定的Attribute特性。 + /// + /// 要检查的Attribute特性类型。 + /// 要检查的类型成员 + /// 是否从继承中查找 + /// 是否存在 + public static bool HasAttribute(this MemberInfo memberInfo, bool inherit = true) where T : Attribute + { + return memberInfo.IsDefined(typeof(T), inherit); + } + + /// + /// 从类型成员获取指定Attribute特性 + /// + /// Attribute特性类型 + /// 类型类型成员 + /// 是否从继承中查找 + /// 存在返回第一个,不存在返回null + public static T GetAttribute(this MemberInfo memberInfo, bool inherit = true) where T : Attribute + { + var attributes = memberInfo.GetCustomAttributes(typeof(T), inherit); + return attributes.FirstOrDefault() as T; + } + + /// + /// 从类型成员获取指定Attribute特性。 + /// + /// Attribute特性类型。 + /// 类型类型成员。 + /// 是否从继承中查找。 + /// 返回所有指定Attribute特性的数组。 + public static T[] GetAttributes(this MemberInfo memberInfo, bool inherit = true) where T : Attribute + { + return memberInfo.GetCustomAttributes(typeof(T), inherit).Cast().ToArray(); + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/MethodInfoExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/MethodInfoExtensions.cs new file mode 100644 index 00000000..78c496c7 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/MethodInfoExtensions.cs @@ -0,0 +1,28 @@ +namespace System.Reflection; + +/// +/// 方法的扩展辅助操作方法 +/// +public static class MethodInfoExtensions +{ + /// + /// 方法是否是异步 + /// + public static bool IsAsync(this MethodInfo method) + { + return (method.ReturnType == typeof(Task<>) + || method.ReturnType.IsGenericType + && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)) + || method.ReturnType == typeof(Task); + } + + /// + /// 返回当前方法信息是否是重写方法 + /// + /// 要判断的方法信息 + /// 是否是重写方法 + public static bool IsOverridden(this MethodInfo method) + { + return method.GetBaseDefinition().DeclaringType != method.DeclaringType; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/PropertyInfoExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/PropertyInfoExtensions.cs new file mode 100644 index 00000000..001e4565 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/Reflection/PropertyInfoExtensions.cs @@ -0,0 +1,21 @@ +namespace System.Reflection; + +/// +/// 属性的扩展辅助操作方法 +/// +public static class PropertyInfoExtensions +{ + /// + /// 返回当前属性信息是否为virtual + /// + public static bool IsVirtual(this PropertyInfo property) + { + var accessor = property.GetAccessors().FirstOrDefault(); + if (accessor == null) + { + return false; + } + + return accessor.IsVirtual && !accessor.IsFinal; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/StringExtensions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/StringExtensions.cs new file mode 100644 index 00000000..dd71588d --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Core/System/StringExtensions.cs @@ -0,0 +1,850 @@ +namespace System; + +/// +/// 字符串类型的扩展辅助操作类 +/// +[DebuggerStepThrough] +public static class StringExtensions +{ + #region 正则表达式 + + /// + /// 指示所指定的正则表达式在指定的输入字符串中是否找到了匹配项 + /// + /// 要搜索匹配项的字符串 + /// 要匹配的正则表达式模式 + /// 是否包含,否则全匹配 + /// 如果正则表达式找到匹配项,则为 true;否则,为 false + public static bool IsMatch(this string value, string pattern, bool isContains = true) + { + if (value == null) + { + return false; + } + + return isContains + ? Regex.IsMatch(value, pattern) + : Regex.Match(value, pattern).Success; + } + + /// + /// 在指定的输入字符串中搜索指定的正则表达式的第一个匹配项 + /// + /// 要搜索匹配项的字符串 + /// 要匹配的正则表达式模式 + /// 一个对象,包含有关匹配项的信息 + public static string Match(this string value, string pattern) + { + if (value == null) + { + return null; + } + + return Regex.Match(value, pattern).Value; + } + + /// + /// 在指定的输入字符串中匹配并替换符合指定正则表达式的子串 + /// + public static string ReplaceRegex(this string value, string pattern, string replacement) + { + if (value == null) + { + return null; + } + + return Regex.Replace(value, pattern, replacement); + } + + /// + /// 在指定的输入字符串中搜索指定的正则表达式的所有匹配项的字符串集合 + /// + /// 要搜索匹配项的字符串 + /// 要匹配的正则表达式模式 + /// 一个集合,包含有关匹配项的字符串值 + public static IEnumerable Matches(this string value, string pattern) + { + if (value == null) + { + return new string[] { }; + } + + var matches = Regex.Matches(value, pattern); + return from Match match in matches select match.Value; + } + + /// + /// 在指定的输入字符串中匹配第一个数字字符串 + /// + public static string MatchFirstNumber(this string value) + { + var matches = Regex.Matches(value, @"\d+"); + if (matches.Count == 0) + { + return string.Empty; + } + + return matches[0].Value; + } + + /// + /// 在指定字符串中匹配最后一个数字字符串 + /// + public static string MatchLastNumber(this string value) + { + var matches = Regex.Matches(value, @"\d+"); + if (matches.Count == 0) + { + return string.Empty; + } + + return matches[matches.Count - 1].Value; + } + + /// + /// 在指定字符串中匹配所有数字字符串 + /// + public static IEnumerable MatchNumbers(this string value) + { + return Matches(value, @"\d+"); + } + + /// + /// 检测指定字符串中是否包含数字 + /// + public static bool IsMatchNumber(this string value) + { + return IsMatch(value, @"\d"); + } + + /// + /// 检测指定字符串是否全部为数字并且长度等于指定长度 + /// + public static bool IsMatchNumber(this string value, int length) + { + var regex = new Regex(@"^\d{" + length + "}$"); + return regex.IsMatch(value); + } + + /// + /// 用正则表达式截取字符串 + /// + public static string Substring2(this string source, string startString, string endString) + { + return source.Substring2(startString, endString, false); + } + + /// + /// 用正则表达式截取字符串 + /// + public static string Substring2(this string source, string startString, string endString, bool containsEmpty) + { + if (source.IsMissing()) + { + return string.Empty; + } + + var inner = containsEmpty ? "\\s\\S" : "\\S"; + var result = source.Match($"(?<={startString})([{inner}]+?)(?={endString})"); + return result.IsMissing() ? null : result; + } + + /// + /// 是否电子邮件 + /// + public static bool IsEmail(this string value) + { + const string pattern = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"; + return value.IsMatch(pattern); + } + + /// + /// 是否是IP地址 + /// + public static bool IsIpAddress(this string value) + { + const string pattern = + @"^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))$"; + return value.IsMatch(pattern); + } + + /// + /// 是否是整数 + /// + public static bool IsNumeric(this string value) + { + const string pattern = @"^\-?[0-9]+$"; + return value.IsMatch(pattern); + } + + /// + /// 是否是Unicode字符串 + /// + public static bool IsUnicode(this string value) + { + const string pattern = @"^[\u4E00-\u9FA5\uE815-\uFA29]+$"; + return value.IsMatch(pattern); + } + + /// + /// 是否Url字符串 + /// + public static bool IsUrl(this string value) + { + try + { + if (string.IsNullOrEmpty(value) || value.Contains(' ')) + { + return false; + } + + var uri = new Uri(value); + return true; + } + catch (Exception) + { + return false; + } + } + + /// + /// 是否身份证号,验证如下3种情况: + /// 1.身份证号码为15位数字; + /// 2.身份证号码为18位数字; + /// 3.身份证号码为17位数字+1个字母 + /// + public static bool IsIdentityCardId(this string value) + { + if (value.Length != 15 && value.Length != 18) + { + return false; + } + + Regex regex; + string[] array; + if (value.Length == 15) + { + regex = new Regex(@"^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})_"); + if (!regex.Match(value).Success) + { + return false; + } + + array = regex.Split(value); + return DateTime.TryParse(string.Format("{0}-{1}-{2}", "19" + array[2], array[3], array[4]), out _); + } + + regex = new Regex(@"^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9Xx])$"); + if (!regex.Match(value).Success) + { + return false; + } + + array = regex.Split(value); + if (!DateTime.TryParse(string.Format("{0}-{1}-{2}", array[2], array[3], array[4]), out _)) + { + return false; + } + + //校验最后一位 + var chars = value.ToCharArray().Select(m => m.ToString()).ToArray(); + int[] weights = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }; + var sum = 0; + for (var i = 0; i < 17; i++) + { + var num = int.Parse(chars[i]); + sum += num * weights[i]; + } + + var mod = sum % 11; + var vCode = "10X98765432"; // 检验码字符串 + var last = vCode.ToCharArray().ElementAt(mod).ToString(); + return chars.Last().ToUpper() == last; + } + + /// + /// 是否手机号码 + /// + /// + /// 是否按严格格式验证 + public static bool IsMobileNumber(this string value, bool isRestrict = false) + { + var pattern = isRestrict ? @"^[1][3-8]\d{9}$" : @"^[1]\d{10}$"; + return value.IsMatch(pattern); + } + + #endregion + + #region 其他操作 + + /// + /// 判断指定的字符串不是 null、空。 + /// + public static bool IsNotNullOrEmpty(this string str) + { + return !string.IsNullOrEmpty(str); + } + + /// + /// 判断指定的字符串不是 null、空或者仅由空白字符组成 + /// + public static bool IsNotNullOrWhiteSpace(this string str) + { + return !string.IsNullOrWhiteSpace(str); + } + + /// + /// 指示指定的字符串是 null、空或者仅由空白字符组成 + /// + public static bool IsMissing(this string value) + { + return string.IsNullOrWhiteSpace(value); + } + + /// + /// 为指定格式的字符串填充相应对象来生成字符串 + /// + /// 字符串格式,占位符以{n}表示 + /// 用于填充占位符的参数 + /// 格式化后的字符串 + public static string FormatWith(this string format, params object[] args) + { + Guard.NotNull(format, nameof(format)); + return string.Format(CultureInfo.CurrentCulture, format, args); + } + + /// + /// 将字符串反转 + /// + /// 要反转的字符串 + public static string ReverseString(this string value) + { + Guard.NotNull(value, nameof(value)); + return new string(value.Reverse().ToArray()); + } + + /// + /// 单词复数变成单数形式 + /// + /// + /// + public static string ToSingular(this string word) + { + var plural1 = new Regex("(?[^aeiou])ies$"); + var plural2 = new Regex("(?[aeiou]y)s$"); + var plural3 = new Regex("(?[sxzh])es$"); + var plural4 = new Regex("(?[^sxzhyu])s$"); + + if (plural1.IsMatch(word)) + { + return plural1.Replace(word, "${keep}y"); + } + + if (plural2.IsMatch(word)) + { + return plural2.Replace(word, "${keep}"); + } + + if (plural3.IsMatch(word)) + { + return plural3.Replace(word, "${keep}"); + } + + if (plural4.IsMatch(word)) + { + return plural4.Replace(word, "${keep}"); + } + + return word; + } + + /// + /// 单词单数变成复数形式 + /// + /// + /// + public static string ToPlural(this string word) + { + var plural1 = new Regex("(?[^aeiou])y$"); + var plural2 = new Regex("(?[aeiou]y)$"); + var plural3 = new Regex("(?[sxzh])$"); + var plural4 = new Regex("(?[^sxzhy])$"); + + if (plural1.IsMatch(word)) + { + return plural1.Replace(word, "${keep}ies"); + } + + if (plural2.IsMatch(word)) + { + return plural2.Replace(word, "${keep}s"); + } + + if (plural3.IsMatch(word)) + { + return plural3.Replace(word, "${keep}es"); + } + + if (plural4.IsMatch(word)) + { + return plural4.Replace(word, "${keep}s"); + } + + return word; + } + + /// + /// 以指定字符串作为分隔符将指定字符串分隔成数组 + /// + /// 要分割的字符串 + /// 字符串类型的分隔符 + /// 是否移除数据中元素为空字符串的项 + /// 分割后的数据 + public static string[] Split(this string value, string strSplit, bool removeEmptyEntries = false) + { + return value.Split(new[] { strSplit }, + removeEmptyEntries ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None); + } + + /// + /// 支持汉字的字符串长度,汉字长度计为2 + /// + /// 参数字符串 + /// 当前字符串的长度,汉字长度为2 + public static int TextLength(this string value) + { + var ascii = new ASCIIEncoding(); + var tempLen = 0; + var bytes = ascii.GetBytes(value); + foreach (var b in bytes) + { + if (b == 63) + { + tempLen += 2; + } + else + { + tempLen += 1; + } + } + + return tempLen; + } + + + /// + /// 给URL添加查询参数 + /// + /// URL字符串 + /// 要添加的参数,形如:"id=1,cid=2" + /// + public static string AddUrlQuery(this string url, params string[] queries) + { + foreach (var query in queries) + { + if (!url.Contains("?")) + { + url += "?"; + } + else if (!url.EndsWith("&")) + { + url += "&"; + } + + url += query; + } + + return url; + } + + /// + /// 获取URL中指定参数的值,不存在返回空字符串 + /// + public static string GetUrlQuery(this string url, string key) + { + var uri = new Uri(url); + var query = uri.Query; + if (string.IsNullOrEmpty(query)) + { + return string.Empty; + } + + query = query.TrimStart('?'); + var dict = (from m in query.Split("&", true) + let strs = m.Split("=") + select new KeyValuePair(strs[0], strs[1])) + .ToDictionary(m => m.Key, m => m.Value); + if (dict.ContainsKey(key)) + { + return dict[key]; + } + + return string.Empty; + } + + /// + /// 给URL添加 # 参数 + /// + /// URL字符串 + /// 要添加的参数 + /// + public static string AddHashFragment(this string url, string query) + { + Guard.NotNull(url, nameof(url)); + Guard.NotNull(query, nameof(query)); + + if (!url.Contains("#")) + { + url += "#"; + } + + return url + query; + } + + + /// + /// 将[]数组转换为Base64字符串 + /// + public static string ToBase64String(this byte[] bytes) + { + Guard.NotNull(bytes, nameof(bytes)); + + return Convert.ToBase64String(bytes); + } + + /// + /// 将字符串转换为Base64字符串,默认编码为 + /// + /// 正常的字符串 + /// 编码 + /// Base64字符串 + public static string ToBase64String(this string source, Encoding encoding = null) + { + Guard.NotNull(source, nameof(source)); + + if (encoding == null) encoding = Encoding.UTF8; + + return Convert.ToBase64String(encoding.GetBytes(source)); + } + + /// + /// 将Base64字符串转换为正常字符串,默认编码为 + /// + /// Base64字符串 + /// 编码 + /// 正常字符串 + public static string FromBase64String(this string base64String, Encoding encoding = null) + { + Guard.NotNull(base64String, nameof(base64String)); + + if (encoding == null) encoding = Encoding.UTF8; + + var bytes = Convert.FromBase64String(base64String); + return encoding.GetString(bytes); + } + + /// + /// 将字符串进行UrlDecode解码 + /// + /// 待UrlDecode解码的字符串 + /// UrlDecode解码后的字符串 + public static string ToUrlDecode(this string source) + { + Guard.NotNull(source, nameof(source)); + + return HttpUtility.UrlDecode(source); + } + + /// + /// 将字符串进行UrlEncode编码 + /// + /// 待UrlEncode编码的字符串 + /// UrlEncode编码后的字符串 + public static string ToUrlEncode(this string source) + { + Guard.NotNull(source, nameof(source)); + + return HttpUtility.UrlEncode(source); + } + + /// + /// 将字符串进行HtmlDecode解码 + /// + /// 待HtmlDecode解码的字符串 + /// HtmlDecode解码后的字符串 + public static string ToHtmlDecode(this string source) + { + Guard.NotNull(source, nameof(source)); + + return HttpUtility.HtmlDecode(source); + } + + /// + /// 将字符串进行HtmlEncode编码 + /// + /// 待HtmlEncode编码的字符串 + /// HtmlEncode编码后的字符串 + public static string ToHtmlEncode(this string source) + { + Guard.NotNull(source, nameof(source)); + + return HttpUtility.HtmlEncode(source); + } + + /// + /// 将字符串转换为十六进制字符串,默认编码为 + /// + public static string ToHexString(this string source, Encoding encoding = null) + { + Guard.NotNull(source, nameof(source)); + + if (encoding == null) encoding = Encoding.UTF8; + + byte[] bytes = encoding.GetBytes(source); + return bytes.ToHexString(); + } + + /// + /// 将十六进制字符串转换为常规字符串,默认编码为 + /// + public static string FromHexString(this string hexString, Encoding encoding = null) + { + Guard.NotNull(hexString, nameof(hexString)); + + if (encoding == null) encoding = Encoding.UTF8; + + var bytes = hexString.ToHexBytes(); + return encoding.GetString(bytes); + } + + /// + /// 将byte[]编码为十六进制字符串 + /// + /// byte[]数组 + /// 十六进制字符串 + public static string ToHexString(this byte[] bytes) + { + Guard.NotNull(bytes, nameof(bytes)); + + return bytes.Aggregate(string.Empty, (current, t) => current + t.ToString("X2")); + } + + /// + /// 将十六进制字符串转换为byte[] + /// + /// 十六进制字符串 + /// byte[]数组 + public static byte[] ToHexBytes(this string hexString) + { + hexString = hexString ?? ""; + hexString = hexString.Replace(" ", ""); + byte[] bytes = new byte[hexString.Length / 2]; + for (int i = 0; i < bytes.Length; i++) + { + bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + } + + return bytes; + } + + /// + /// 将字符串进行Unicode编码,变成形如“\u7f16\u7801”的形式 + /// + /// 要进行编号的字符串 + public static string ToUnicodeString(this string source) + { + Guard.NotNull(source, nameof(source)); + + var regex = new Regex(@"[^\u0000-\u00ff]"); + return regex.Replace(source, m => string.Format(@"\u{0:x4}", (short)m.Value[0])); + } + + /// + /// 将形如“\u7f16\u7801”的Unicode字符串解码 + /// + public static string FromUnicodeString(this string source) + { + var regex = new Regex(@"\\u([0-9a-fA-F]{4})", RegexOptions.Compiled); + return regex.Replace(source, + m => + { + short s; + if (short.TryParse(m.Groups[1].Value, NumberStyles.HexNumber, CultureInfo.InstalledUICulture, + out s)) + { + return "" + (char)s; + } + + return m.Value; + }); + } + + /// + /// 将驼峰字符串的第一个字符小写 + /// + public static string LowerFirstChar(this string str) + { + if (string.IsNullOrEmpty(str) || !char.IsUpper(str[0])) + { + return str; + } + + if (str.Length == 1) + { + return char.ToLower(str[0]).ToString(); + } + + return char.ToLower(str[0]) + str.Substring(1, str.Length - 1); + } + + /// + /// 将小驼峰字符串的第一个字符大写 + /// + public static string UpperFirstChar(this string str) + { + if (string.IsNullOrEmpty(str) || !char.IsLower(str[0])) + { + return str; + } + + if (str.Length == 1) + { + return char.ToUpper(str[0]).ToString(); + } + + return char.ToUpper(str[0]) + str.Substring(1, str.Length - 1); + } + + /// + /// 计算当前字符串与指定字符串的编辑距离(相似度) + /// + /// 源字符串 + /// 目标字符串 + /// 输出相似度 + /// 是否忽略大小写 + /// 编辑距离 + public static int LevenshteinDistance(this string source, string target, out double similarity, + bool ignoreCase = false) + { + if (string.IsNullOrEmpty(source)) + { + if (string.IsNullOrEmpty(target)) + { + similarity = 1; + return 0; + } + + similarity = 0; + return target.Length; + } + + if (string.IsNullOrEmpty(target)) + { + similarity = 0; + return source.Length; + } + + string from, to; + if (ignoreCase) + { + from = source; + to = target; + } + else + { + from = source.ToLower(); + to = source.ToLower(); + } + + int m = from.Length, n = to.Length; + int[,] mn = new int[m + 1, n + 1]; + for (int i = 0; i <= m; i++) + { + mn[i, 0] = i; + } + + for (int j = 1; j <= n; j++) + { + mn[0, j] = j; + } + + for (int i = 1; i <= m; i++) + { + char c = from[i - 1]; + for (int j = 1; j <= n; j++) + { + if (c == to[j - 1]) + { + mn[i, j] = mn[i - 1, j - 1]; + } + else + { + mn[i, j] = Math.Min(mn[i - 1, j - 1], Math.Min(mn[i - 1, j], mn[i, j - 1])) + 1; + } + } + } + + int maxLength = Math.Max(m, n); + similarity = (double)(maxLength - mn[m, n]) / maxLength; + return mn[m, n]; + } + + /// + /// 计算两个字符串的相似度,应用公式:相似度=kq*q/(kq*q+kr*r+ks*s)(kq>0,kr>=0,ka>=0) + /// 其中,q是字符串1和字符串2中都存在的单词的总数,s是字符串1中存在,字符串2中不存在的单词总数,r是字符串2中存在,字符串1中不存在的单词总数. kq,kr和ka分别是q,r,s的权重,根据实际的计算情况,我们设kq=2,kr=ks=1. + /// + /// 源字符串 + /// 目标字符串 + /// 是否忽略大小写 + /// 字符串相似度 + public static double GetSimilarityWith(this string source, string target, bool ignoreCase = false) + { + if (string.IsNullOrEmpty(source) && string.IsNullOrEmpty(target)) + { + return 1; + } + + if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(target)) + { + return 0; + } + + const double kq = 2, kr = 1, ks = 1; + char[] sourceChars = source.ToCharArray(), targetChars = target.ToCharArray(); + + //获取交集数量 + int q = sourceChars.Intersect(targetChars).Count(), s = sourceChars.Length - q, r = targetChars.Length - q; + return kq * q / (kq * q + kr * r + ks * s); + } + + /// + /// 标准化Path字符串,将 \\ 转换为 / + /// + /// Path字符串 + public static string NormalizePath(this string path) + { + return path.Replace('\\', '/'); + } + + /// + /// (Pascal) 命名法 的字符串 改为 短横线分隔式命名 + /// 例如UserName => user-name + /// + public static string PascalToKebabCase(this string value) + { + if (string.IsNullOrEmpty(value)) + { + return value; + } + + return Regex.Replace( + value, + "(? +/// StringBuilder 扩展方法类 +/// +public static class StringBuilderExtensions +{ + /// + /// 去除开头的空格 + /// + /// + /// 返回修改后的StringBuilder,主要用于链式操作 + public static StringBuilder TrimStart(this StringBuilder stringBuilder) + { + if (stringBuilder is null) throw new ArgumentNullException(); + + return stringBuilder.TrimStart(' '); + } + + /// + /// 去除开头的指定 + /// + /// + /// 要去掉的 + /// + public static StringBuilder TrimStart(this StringBuilder stringBuilder, char c) + { + if (stringBuilder is null) throw new ArgumentNullException(); + + if (stringBuilder.Length == 0) + { + return stringBuilder; + } + + while (c.Equals(stringBuilder[0])) + { + stringBuilder.Remove(0, 1); + } + + return stringBuilder; + } + + /// + /// 去除开头的指定字符数组 + /// + /// + /// 要去掉的字符数组 + /// + public static StringBuilder TrimStart(this StringBuilder stringBuilder, char[] chars) + { + if (stringBuilder is null) throw new ArgumentNullException(); + + return stringBuilder.TrimStart(new string(chars)); + } + + /// + /// 去除开头的指定的 + /// + /// + /// 要去掉的 + /// + public static StringBuilder TrimStart(this StringBuilder stringBuilder, string str) + { + if (stringBuilder is null) throw new ArgumentNullException(); + + if (string.IsNullOrEmpty(str) + || stringBuilder.Length == 0 + || str.Length > stringBuilder.Length) + { + return stringBuilder; + } + + while (stringBuilder.SubString(0, str.Length).Equals(str)) + { + stringBuilder.Remove(0, str.Length); + if (str.Length > stringBuilder.Length) + { + break; + } + } + + return stringBuilder; + } + + /// + /// 去除StringBuilder结尾的空格 + /// + /// StringBuilder + /// 返回修改后的StringBuilder,主要用于链式操作 + public static StringBuilder TrimEnd(this StringBuilder stringBuilder) + { + return stringBuilder.TrimEnd(' '); + } + + /// + /// 去除结尾指定字符 + /// + /// + /// 要去掉的字符 + /// + public static StringBuilder TrimEnd(this StringBuilder stringBuilder, char c) + { + if (stringBuilder is null) throw new ArgumentNullException(); + if (stringBuilder.Length == 0) + { + return stringBuilder; + } + + while (c.Equals(stringBuilder[stringBuilder.Length - 1])) + { + stringBuilder.Remove(stringBuilder.Length - 1, 1); + } + + return stringBuilder; + } + + /// + /// 去除结尾指定字符数组 + /// + /// + /// 要去除的字符数组 + /// + public static StringBuilder TrimEnd(this StringBuilder stringBuilder, char[] chars) + { + if (stringBuilder is null) throw new ArgumentNullException(); + + return stringBuilder.TrimEnd(new string(chars)); + } + + /// + /// 去除结尾指定字符串 + /// + /// + /// 要去除的字符串 + /// + public static StringBuilder TrimEnd(this StringBuilder stringBuilder, string str) + { + if (stringBuilder is null) throw new ArgumentNullException(); + if (string.IsNullOrEmpty(str) + || stringBuilder.Length == 0 + || str!.Length > stringBuilder.Length) + { + return stringBuilder; + } + + while (stringBuilder.SubString(stringBuilder.Length - str.Length, str.Length).Equals(str)) + { + stringBuilder.Remove(stringBuilder.Length - str.Length, str.Length); + if (stringBuilder.Length < str.Length) + { + break; + } + } + + return stringBuilder; + } + + /// + /// 去除StringBuilder两端的空格 + /// + /// StringBuilder + /// 返回修改后的StringBuilder,主要用于链式操作 + public static StringBuilder Trim(this StringBuilder stringBuilder) + { + if (stringBuilder is null) throw new ArgumentNullException(); + + if (stringBuilder.Length == 0) + { + return stringBuilder; + } + + return stringBuilder.TrimEnd().TrimStart(); + } + + /// + /// 返回从起始位置指定长度的字符串 + /// + /// + /// 起始位置 + /// 长度 + /// 字符串 + /// 超出字符串索引长度异常 + public static string SubString(this StringBuilder stringBuilder, int start, int length) + { + if (stringBuilder is null) throw new ArgumentNullException(); + + if (start + length > stringBuilder.Length) + { + throw new ArgumentOutOfRangeException(); + } + + var cs = new char[length]; + for (var i = 0; i < length; i++) + { + cs[i] = stringBuilder[start + i]; + } + + return new string(cs); + } + + public static StringBuilder AppendLineWithControlChar(this StringBuilder stringBuilder, StringBuilder sb, string newLine) + { + if (stringBuilder is null) throw new ArgumentNullException(); + stringBuilder = AppendWithControlChar(stringBuilder, sb.ToString()); + return stringBuilder.Append(newLine); + } + + public static StringBuilder AppendLineWithControlChar(this StringBuilder stringBuilder, string str, string newLine) + { + if (stringBuilder is null) throw new ArgumentNullException(); + stringBuilder = AppendWithControlChar(stringBuilder, str); + return stringBuilder.Append(newLine); + } + + public static StringBuilder AppendWithControlChar(this StringBuilder stringBuilder, StringBuilder sb) + { + if (stringBuilder is null) throw new ArgumentNullException(); + return AppendWithControlChar(stringBuilder, sb.ToString()); + } + + public static StringBuilder AppendWithControlChar(this StringBuilder stringBuilder, string str) + { + if (str.Contains('\b')) + { + foreach (var c in str) + { + if (c == '\b') + { + stringBuilder.Length--; + } + else + { + stringBuilder.Append(c); + } + } + } + else + { + stringBuilder.Append(str); + } + + return stringBuilder; + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Localization/GlobalUsings.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/GlobalUsings.cs new file mode 100644 index 00000000..0558e9d8 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/GlobalUsings.cs @@ -0,0 +1,8 @@ +// Global using directives + +global using Lion.AbpPro.Localization; +global using Volo.Abp.Autofac; +global using Volo.Abp.Localization; +global using Volo.Abp.Localization.ExceptionHandling; +global using Volo.Abp.Modularity; +global using Volo.Abp.VirtualFileSystem; \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion.AbpPro.Localization.csproj b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion.AbpPro.Localization.csproj new file mode 100644 index 00000000..c0db730b --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion.AbpPro.Localization.csproj @@ -0,0 +1,19 @@ + + + + netstandard2.1 + Lion.AbpPro.Localization + + + + + + + + + + + + + + diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/LionAbpProLocalizationConsts.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/LionAbpProLocalizationConsts.cs new file mode 100644 index 00000000..e86482d3 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/LionAbpProLocalizationConsts.cs @@ -0,0 +1,19 @@ +namespace Lion.AbpPro; + +public class LionAbpProLocalizationConsts +{ + /// + /// 名称空间 + /// + public const string NameSpace = "Lion.AbpPro"; + + /// + /// 默认语言 + /// + public const string DefaultCultureName = "zh-Hans"; + + /// + /// 默认本地化文件虚拟路径 + /// + public const string DefaultLocalizationResourceVirtualPath = "/Localization/Resources"; +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/LionAbpProLocalizationModule.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/LionAbpProLocalizationModule.cs new file mode 100644 index 00000000..5e89afde --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/LionAbpProLocalizationModule.cs @@ -0,0 +1,24 @@ +namespace Lion.AbpPro; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(AbpLocalizationModule) +)] +public class LionAbpProLocalizationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => { options.FileSets.AddEmbedded(LionAbpProLocalizationConsts.NameSpace); }); + + Configure(options => + { + options.Resources + .Add(LionAbpProLocalizationConsts.DefaultCultureName) + .AddVirtualJson(LionAbpProLocalizationConsts.DefaultLocalizationResourceVirtualPath); + + options.DefaultResourceType = typeof(LionAbpProLocalizationResource); + }); + + Configure(options => { options.MapCodeNamespace(LionAbpProLocalizationConsts.NameSpace, typeof(LionAbpProLocalizationResource)); }); + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/LionAbpProLocalizationResource.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/LionAbpProLocalizationResource.cs new file mode 100644 index 00000000..7a26ae12 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/LionAbpProLocalizationResource.cs @@ -0,0 +1,7 @@ +namespace Lion.AbpPro.Localization; + +[LocalizationResourceName("LionAbpProLocalizationResource")] +public class LionAbpProLocalizationResource +{ + +} \ No newline at end of file diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/Resources/en.json b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/Resources/en.json new file mode 100644 index 00000000..3180088f --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/Resources/en.json @@ -0,0 +1,6 @@ +{ + "culture": "en", + "texts": { + "Welcome": "Welcome" + } +} diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/Resources/zh-Hans.json b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/Resources/zh-Hans.json new file mode 100644 index 00000000..0963e295 --- /dev/null +++ b/aspnet-core/frameworks/src/Lion.AbpPro.Localization/Lion/AbpPro/Localization/Resources/zh-Hans.json @@ -0,0 +1,6 @@ +{ + "culture": "zh-Hans", + "texts": { + "Welcome": "欢迎" + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/GlobalUsings.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/GlobalUsings.cs new file mode 100644 index 00000000..243872dd --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/GlobalUsings.cs @@ -0,0 +1,4 @@ +// Global using directives + +global using Shouldly; +global using Xunit; \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion.AbpPro.Core.Tests.csproj b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion.AbpPro.Core.Tests.csproj new file mode 100644 index 00000000..dc443d4a --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion.AbpPro.Core.Tests.csproj @@ -0,0 +1,27 @@ + + + + net6.0 + enable + false + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion/AbpPro/Core/LionAbpProTestBase.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion/AbpPro/Core/LionAbpProTestBase.cs new file mode 100644 index 00000000..df3f7b2d --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion/AbpPro/Core/LionAbpProTestBase.cs @@ -0,0 +1,13 @@ +using Volo.Abp; +using Volo.Abp.Testing; + +namespace Lion.AbpPro.Core +{ + public abstract class LionAbpProTestBase : AbpIntegratedTest + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion/AbpPro/Core/LionAbpProTestBaseModule.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion/AbpPro/Core/LionAbpProTestBaseModule.cs new file mode 100644 index 00000000..63971161 --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/Lion/AbpPro/Core/LionAbpProTestBaseModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace Lion.AbpPro.Core +{ + [DependsOn(typeof(AbpTestBaseModule), + typeof(AbpAutofacModule))] + public class LionAbpProTestBaseModule : AbpModule + { + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/BooleanExtensionsTests.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/BooleanExtensionsTests.cs new file mode 100644 index 00000000..61b61b2f --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/BooleanExtensionsTests.cs @@ -0,0 +1,22 @@ +namespace System; + +public class BooleanExtensionsTests +{ + [Fact] + public void ToLowerTest() + { + true.ToLower().ShouldBe("true"); + false.ToLower().ShouldBe("false"); + } + + [Fact] + public void TrueThrowTest() + { + Should.Throw(() => + { + true.TrueThrow(new Exception()); + }); + + false.TrueThrow(new Exception()); + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Collections/Generic/CollectionExtensionsTests.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Collections/Generic/CollectionExtensionsTests.cs new file mode 100644 index 00000000..a785cb46 --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Collections/Generic/CollectionExtensionsTests.cs @@ -0,0 +1,36 @@ +namespace System.Collections.Generic; + +public class CollectionExtensionsTests +{ + [Fact] + public void AddIfNotExistTest() + { + var numbers = new List() { 1, 2, 3 }; + numbers.AddIfNotExist(2); + numbers.Count(m => m == 2).ShouldBe(1); + numbers.AddIfNotExist(5); + numbers.Count(m => m == 5).ShouldBe(1); + + numbers = null; + Should.Throw(() => + { + numbers.AddIfNotExist(3); + }); + } + + [Fact] + public void AddIfNotNullTest() + { + var strings = new List() { "abc", "bcd", "cde" }; + strings.AddIfNotNull(null); + strings.Count.ShouldBe(3); + strings.AddIfNotNull("abc"); + strings.Count.ShouldBe(4); + + strings = null; + Should.Throw(() => + { + strings.AddIfNotNull("abc"); + }); + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/DateTimeExtensionsTests.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/DateTimeExtensionsTests.cs new file mode 100644 index 00000000..6a567abf --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/DateTimeExtensionsTests.cs @@ -0,0 +1,61 @@ +namespace System; + +public class DateTimeExtensionsTests +{ + [Fact] + public void IsWeekendTest() + { + var dt = new DateTime(2021, 4, 24); + dt.IsWeekend().ShouldBeTrue(); + dt = new DateTime(2021, 4, 25); + dt.IsWeekend().ShouldBeTrue(); + for (var i = 1; i <= 5; i++) + { + dt = new DateTime(2021, 4, 25 + i); + dt.IsWeekend().ShouldBeFalse(); + } + } + + [Fact] + public void IsWeekdayTest() + { + var dt = new DateTime(2021, 4, 24); + dt.IsWeekday().ShouldBeFalse(); + dt = new DateTime(2021, 4, 25); + dt.IsWeekday().ShouldBeFalse(); + for (var i = 1; i <= 5; i++) + { + dt = new DateTime(2021, 4, 25 + i); + dt.IsWeekday().ShouldBeTrue(); + } + } + + [Fact] + public void ToUniqueStringTest() + { + var dt = new DateTime(2021, 4, 24,21,30,23); + dt.ToUniqueString().ShouldBe("202111477423"); + dt = dt.AddMilliseconds(-1); + dt.ToUniqueString(true).ShouldBe("202111477422999"); + } + + [Fact] + public void ToYyyyMMddTest() + { + var dt1 = new DateTime(2021, 9, 1); + dt1.ToYyyyMmDd().ShouldBe(20210901); + + var dt2 = new DateTime(2020, 12, 31); + dt2.ToYyyyMmDd().ShouldBe(20201231); + } + + [Fact] + public void ToYyyyMMTest() + { + var dt1 = new DateTime(2021, 9, 6); + dt1.ToYyyyMm().ShouldBe(202109); + + var dt2 = new DateTime(2020, 12, 31); + dt2.ToYyyyMm().ShouldBe(202012); + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/DecimalExtensionsTests.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/DecimalExtensionsTests.cs new file mode 100644 index 00000000..ae3033c0 --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/DecimalExtensionsTests.cs @@ -0,0 +1,26 @@ +namespace System; + +public class DecimalExtensionsTest +{ + [Fact] + public void TrimEndZero() + { + var d1 = 0.1M; + var d2 = 1M; + var d3 = 1.001M; + var d4 = 1.0000M; + var d5 = 0.1010M; + var result1 = d1.TrimEndZero(); + var result2 = d2.TrimEndZero(); + var result3 = d3.TrimEndZero(); + var result4 = d4.TrimEndZero(); + var result5 = d5.TrimEndZero(); + + result1.ToString().ShouldBe("0.1"); + result2.ToString().ShouldBe("1"); + result3.ToString().ShouldBe("1.001"); + result4.ToString().ShouldBe("1"); + result5.ToString().ShouldBe("0.101"); + + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Reflection/AssemblyExtensionsTests.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Reflection/AssemblyExtensionsTests.cs new file mode 100644 index 00000000..b2174377 --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Reflection/AssemblyExtensionsTests.cs @@ -0,0 +1,11 @@ +namespace System.Reflection; + +public class AssemblyExtensionsTests +{ + [Fact] + public void GetFileVersionTest() + { + var assembly = typeof(AssemblyExtensionsTests).Assembly; + assembly.GetFileVersion().ShouldBe("1.0.0.0"); + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Text/StringBuilderExtensionsTest.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Text/StringBuilderExtensionsTest.cs new file mode 100644 index 00000000..bc5cd65d --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Core.Tests/System/Text/StringBuilderExtensionsTest.cs @@ -0,0 +1,58 @@ +namespace System.Text; + +public class StringBuilderExtensionsTest +{ + [Fact] + public void TrimTest() + { + var sb = new StringBuilder(" hello world "); + sb.Trim().ToString().ShouldBe("hello world"); + } + + [Fact] + public void TrimStartTest() + { + var sb = new StringBuilder(); + sb.TrimStart('a').ToString().ShouldBe(string.Empty); + + sb.Append("asdfgef"); + sb.TrimStart('a').ToString().ShouldBe("sdfgef"); + + sb.Insert(0, " "); + sb.TrimStart().ToString().ShouldBe("sdfgef"); + + sb.TrimStart("sdf").ToString().ShouldBe("gef"); + + sb.TrimStart("gef").ToString().ShouldBe(string.Empty); + } + + [Fact] + public void TrimEndTest() + { + var sb = new StringBuilder("asdfgef"); + + sb.TrimEnd((string)null).ToString().ShouldBe("asdfgef"); + + sb.TrimEnd('a').ToString().ShouldBe("asdfgef"); + + sb.TrimEnd('f').ToString().ShouldBe("asdfge"); + + sb.Append(" "); + sb.TrimEnd().ToString().ShouldBe("asdfge"); + + sb.TrimEnd(new[] { 'g', 'e' }).ToString().ShouldBe("asdf"); + sb.TrimEnd("asdf").ToString().ShouldBe(string.Empty); + } + + [Fact] + public void SubStringTest() + { + var sb = new StringBuilder("asdfgef"); + Should.Throw(() => + { + sb.SubString(0, 8); + }); + sb.SubString(0, 3).ToString().ShouldBe("asd"); + + } +} \ No newline at end of file diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion.AbpPro.Localization.Tests.csproj b/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion.AbpPro.Localization.Tests.csproj new file mode 100644 index 00000000..9ecd3ffc --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion.AbpPro.Localization.Tests.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + enable + false + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTestBase.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTestBase.cs new file mode 100644 index 00000000..d3b97dc9 --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTestBase.cs @@ -0,0 +1,14 @@ +using Volo.Abp; +using Volo.Abp.Testing; + +namespace Lion.AbpPro +{ + + public abstract class LionAbpProLocalizationTestBase : AbpIntegratedTest + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + } +} diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTestBaseModule.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTestBaseModule.cs new file mode 100644 index 00000000..7234d095 --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTestBaseModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp; +using Volo.Abp.Modularity; + +namespace Lion.AbpPro +{ + + [DependsOn(typeof(LionAbpProLocalizationModule))] + [DependsOn(typeof(AbpTestBaseModule))] + public class LionAbpProLocalizationTestBaseModule : AbpModule + { + } +} diff --git a/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTests.cs b/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTests.cs new file mode 100644 index 00000000..099878ed --- /dev/null +++ b/aspnet-core/frameworks/test/Lion.AbpPro.Localization.Tests/Lion/AbpPro/LionAbpProLocalizationTests.cs @@ -0,0 +1,34 @@ +using Lion.AbpPro.Localization; +using Microsoft.Extensions.Localization; +using Shouldly; +using Volo.Abp.Localization; +using Xunit; + +namespace Lion.AbpPro +{ + public sealed class LionAbpProLocalizationTests : LionAbpProLocalizationTestBase + { + private readonly IStringLocalizer _stringLocalizer; + + public LionAbpProLocalizationTests() + { + _stringLocalizer = GetRequiredService>(); + } + + [Fact] + public void Test() + { + using (CultureHelper.Use("en")) + { + _stringLocalizer["Welcome"].Value + .ShouldBe("Welcome"); + } + + using (CultureHelper.Use("zh-Hans")) + { + _stringLocalizer["Welcome"].Value + .ShouldBe("欢迎"); + } + } + } +} \ No newline at end of file diff --git a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/GlobalUsings.cs b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/GlobalUsings.cs index df8da7ef..ad86891c 100644 --- a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/GlobalUsings.cs +++ b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/GlobalUsings.cs @@ -3,7 +3,7 @@ global using System.ComponentModel.DataAnnotations; global using Lion.AbpPro.BasicManagement.OrganizationUnits.Dto; global using Lion.AbpPro.BasicManagement.Tenants.Dtos; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Volo.Abp.Application.Dtos; global using Volo.Abp.Application.Services; global using Volo.Abp.AspNetCore.Mvc.MultiTenancy; diff --git a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Lion.AbpPro.BasicManagement.Application.Contracts.csproj b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Lion.AbpPro.BasicManagement.Application.Contracts.csproj index 529f875e..753e2d87 100644 --- a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Lion.AbpPro.BasicManagement.Application.Contracts.csproj +++ b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Lion.AbpPro.BasicManagement.Application.Contracts.csproj @@ -5,8 +5,8 @@ - - + + @@ -16,8 +16,6 @@ - - diff --git a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/GlobalUsings.cs b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/GlobalUsings.cs index dfa459e8..f9ba6ca5 100644 --- a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/GlobalUsings.cs +++ b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/GlobalUsings.cs @@ -1,11 +1,11 @@ // Global using directives global using System.Globalization; -global using AutoMapper.Internal.Mappers; global using Lion.AbpPro.BasicManagement.OrganizationUnits.Dto; global using Lion.AbpPro.BasicManagement.Permissions; +global using Lion.AbpPro.BasicManagement.Roles.Dtos; global using Lion.AbpPro.BasicManagement.Tenants.Dtos; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Microsoft.AspNetCore.Authorization; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Localization; diff --git a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Roles/RoleAppService.cs b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Roles/RoleAppService.cs index e167f138..a9c6757a 100644 --- a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Roles/RoleAppService.cs +++ b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Roles/RoleAppService.cs @@ -1,87 +1,84 @@ -using Lion.AbpPro.BasicManagement.Roles.Dtos; +namespace Lion.AbpPro.BasicManagement.Roles; -namespace Lion.AbpPro.BasicManagement.Roles +[Authorize] +public class RoleAppService : BasicManagementAppService, IRoleAppService { - [Authorize] - public class RoleAppService : BasicManagementAppService, IRoleAppService - { - private readonly IIdentityRoleAppService _identityRoleAppService; + private readonly IIdentityRoleAppService _identityRoleAppService; - private readonly IIdentityRoleRepository _roleRepository; + private readonly IIdentityRoleRepository _roleRepository; - public RoleAppService( - IIdentityRoleAppService identityRoleAppService, - IIdentityRoleRepository roleRepository) - { - _identityRoleAppService = identityRoleAppService; + public RoleAppService( + IIdentityRoleAppService identityRoleAppService, + IIdentityRoleRepository roleRepository) + { + _identityRoleAppService = identityRoleAppService; - _roleRepository = roleRepository; - } + _roleRepository = roleRepository; + } - /// - /// 获取所有角色 - /// + /// + /// 获取所有角色 + /// - public async Task> AllListAsync() - { - List source = - await _roleRepository.GetListAsync() - .ConfigureAwait(continueOnCapturedContext: false); - return new ListResultDto( - ObjectMapper.Map, List>(source)); - } + public async Task> AllListAsync() + { + List source = + await _roleRepository.GetListAsync() + .ConfigureAwait(continueOnCapturedContext: false); + return new ListResultDto( + ObjectMapper.Map, List>(source)); + } - /// - /// 分页查询角色 - /// - /// - /// - public async Task> ListAsync(PagingRoleListInput input) + /// + /// 分页查询角色 + /// + /// + /// + public async Task> ListAsync(PagingRoleListInput input) + { + var request = new GetIdentityRolesInput { - var request = new GetIdentityRolesInput - { - Filter = input.Filter?.Trim(), MaxResultCount = input.PageSize, - SkipCount = input.SkipCount - }; - List list = await _roleRepository - .GetListAsync(request.Sorting, request.MaxResultCount, request.SkipCount, - request.Filter) - .ConfigureAwait(continueOnCapturedContext: false); - return new PagedResultDto( - await _roleRepository.GetCountAsync(request.Filter) - .ConfigureAwait(continueOnCapturedContext: false), - ObjectMapper.Map, List>(list)); - } + Filter = input.Filter?.Trim(), MaxResultCount = input.PageSize, + SkipCount = input.SkipCount + }; + List list = await _roleRepository + .GetListAsync(request.Sorting, request.MaxResultCount, request.SkipCount, + request.Filter) + .ConfigureAwait(continueOnCapturedContext: false); + return new PagedResultDto( + await _roleRepository.GetCountAsync(request.Filter) + .ConfigureAwait(continueOnCapturedContext: false), + ObjectMapper.Map, List>(list)); + } - /// - /// 创建角色 - /// - /// - /// - [Authorize(IdentityPermissions.Roles.Create)] - public async Task CreateAsync(IdentityRoleCreateDto input) - { - return await _identityRoleAppService.CreateAsync(input); - } + /// + /// 创建角色 + /// + /// + /// + [Authorize(IdentityPermissions.Roles.Create)] + public async Task CreateAsync(IdentityRoleCreateDto input) + { + return await _identityRoleAppService.CreateAsync(input); + } - /// - /// 更新角色 - /// - [Authorize(IdentityPermissions.Roles.Update)] - public async Task UpdateAsync(UpdateRoleInput input) - { - return await _identityRoleAppService.UpdateAsync(input.RoleId, input.RoleInfo); - } + /// + /// 更新角色 + /// + [Authorize(IdentityPermissions.Roles.Update)] + public async Task UpdateAsync(UpdateRoleInput input) + { + return await _identityRoleAppService.UpdateAsync(input.RoleId, input.RoleInfo); + } - /// - /// 删除角色 - /// - [Authorize(IdentityPermissions.Roles.Delete)] - public async Task DeleteAsync(IdInput input) - { - await _identityRoleAppService.DeleteAsync(input.Id); - } + /// + /// 删除角色 + /// + [Authorize(IdentityPermissions.Roles.Delete)] + public async Task DeleteAsync(IdInput input) + { + await _identityRoleAppService.DeleteAsync(input.Id); } } \ No newline at end of file diff --git a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Roles/RolePermissionAppService.cs b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Roles/RolePermissionAppService.cs index 88e60b00..c723bd2b 100644 --- a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Roles/RolePermissionAppService.cs +++ b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Roles/RolePermissionAppService.cs @@ -1,4 +1,3 @@ -using Lion.AbpPro.BasicManagement.Roles.Dtos; using Volo.Abp.PermissionManagement; namespace Lion.AbpPro.BasicManagement.Roles diff --git a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/BasicManagementDomainSharedModule.cs b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/BasicManagementDomainSharedModule.cs index 23fbd563..690e327d 100644 --- a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/BasicManagementDomainSharedModule.cs +++ b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/BasicManagementDomainSharedModule.cs @@ -1,4 +1,6 @@ -namespace Lion.AbpPro.BasicManagement; +using Lion.AbpPro.Core; + +namespace Lion.AbpPro.BasicManagement; [DependsOn( typeof(AbpAuditLoggingDomainSharedModule), @@ -7,7 +9,8 @@ typeof(AbpIdentityDomainSharedModule), typeof(AbpPermissionManagementDomainSharedModule), typeof(AbpSettingManagementDomainSharedModule), - typeof(AbpTenantManagementDomainSharedModule) + typeof(AbpTenantManagementDomainSharedModule), + typeof(LionAbpProCoreModule) )] public class BasicManagementDomainSharedModule : AbpModule { diff --git a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/Lion.AbpPro.BasicManagement.Domain.Shared.csproj b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/Lion.AbpPro.BasicManagement.Domain.Shared.csproj index d87e7295..9d018961 100644 --- a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/Lion.AbpPro.BasicManagement.Domain.Shared.csproj +++ b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/Lion.AbpPro.BasicManagement.Domain.Shared.csproj @@ -23,5 +23,10 @@ + + + + + diff --git a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.HttpApi/GlobalUsings.cs b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.HttpApi/GlobalUsings.cs index f6079937..0f018541 100644 --- a/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.HttpApi/GlobalUsings.cs +++ b/aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.HttpApi/GlobalUsings.cs @@ -10,7 +10,7 @@ global using Lion.AbpPro.BasicManagement.Settings.Dtos; global using Lion.AbpPro.BasicManagement.Tenants.Dtos; global using Lion.AbpPro.BasicManagement.Users; global using Lion.AbpPro.BasicManagement.Users.Dtos; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Microsoft.AspNetCore.Mvc; global using Swashbuckle.AspNetCore.Annotations; global using Volo.Abp.Application.Dtos; diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Application.Contracts/GlobalUsings.cs b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Application.Contracts/GlobalUsings.cs index 80cf0834..f863732f 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Application.Contracts/GlobalUsings.cs +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Application.Contracts/GlobalUsings.cs @@ -9,7 +9,7 @@ global using System.Threading; global using System.Threading.Tasks; global using Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Dtos; global using Lion.AbpPro.DataDictionaryManagement.Localization; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Volo.Abp.Application; global using Volo.Abp.Application.Dtos; global using Volo.Abp.Application.Services; diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Application/GlobalUsings.cs b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Application/GlobalUsings.cs index 7070bc9b..4a85ac94 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Application/GlobalUsings.cs +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Application/GlobalUsings.cs @@ -10,8 +10,7 @@ global using Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Dto; global using Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Dtos; global using Lion.AbpPro.DataDictionaryManagement.Localization; global using Lion.AbpPro.DataDictionaryManagement.Permissions; -global using Lion.AbpPro.Extension.Customs.Dtos; -global using Lion.AbpPro.Extension.System; +global using Lion.AbpPro.Core; global using Microsoft.AspNetCore.Authorization; global using Microsoft.Extensions.DependencyInjection; global using Volo.Abp.Application; diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain.Shared/DataDictionaryManagementDomainSharedModule.cs b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain.Shared/DataDictionaryManagementDomainSharedModule.cs index 82cf6dd5..165ec3ba 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain.Shared/DataDictionaryManagementDomainSharedModule.cs +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain.Shared/DataDictionaryManagementDomainSharedModule.cs @@ -1,7 +1,10 @@ +using Lion.AbpPro.Core; + namespace Lion.AbpPro.DataDictionaryManagement { [DependsOn( - typeof(AbpValidationModule) + typeof(AbpValidationModule), + typeof(LionAbpProCoreModule) )] public class DataDictionaryManagementDomainSharedModule : AbpModule { diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain.Shared/Lion.AbpPro.DataDictionaryManagement.Domain.Shared.csproj b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain.Shared/Lion.AbpPro.DataDictionaryManagement.Domain.Shared.csproj index 4cac065d..1119308d 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain.Shared/Lion.AbpPro.DataDictionaryManagement.Domain.Shared.csproj +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain.Shared/Lion.AbpPro.DataDictionaryManagement.Domain.Shared.csproj @@ -12,7 +12,6 @@ - @@ -20,4 +19,8 @@ + + + + diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaries/Aggregates/DataDictionary.cs b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaries/Aggregates/DataDictionary.cs index aff08f83..dc701e0f 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaries/Aggregates/DataDictionary.cs +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaries/Aggregates/DataDictionary.cs @@ -1,116 +1,115 @@ -namespace Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Aggregates +namespace Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Aggregates; + +/// +/// 数据字典 +/// +public class DataDictionary : FullAuditedAggregateRoot, IMultiTenant { /// - /// 数据字典 + /// 租户id /// - public class DataDictionary : FullAuditedAggregateRoot, IMultiTenant - { - /// - /// 租户id - /// - public Guid? TenantId { get; private set; } - - /// - /// 字典编码 - /// - [Required] - [MaxLength(DataDictionaryMaxLengths.Code)] - public string Code { get; private set; } - - /// - /// 显示名 - /// - [Required] - [MaxLength(DataDictionaryMaxLengths.DisplayText)] - public string DisplayText { get; private set; } - - - /// - /// 描述 - /// - [Required] - [MaxLength(DataDictionaryMaxLengths.Description)] - public string Description { get; private set; } - - /// - /// 字典明细集合 - /// - public List Details { get; private set; } - - private DataDictionary() - { - Details = new List(); - } + public Guid? TenantId { get; private set; } - public DataDictionary( - Guid id, - string code, - string displayText, - string description = null, - Guid? tenantId = null) : base(id) - { - SetProperties(code, displayText, description, tenantId); - Details = new List(); - } + /// + /// 字典编码 + /// + [Required] + [MaxLength(DataDictionaryMaxLengths.Code)] + public string Code { get; private set; } - private void SetProperties(string code, string displayText, string description, Guid? tenantId) - { - SetCode(code); - SetDisplayText(displayText); - SetDescription(description); - SetTenantId(tenantId); - } + /// + /// 显示名 + /// + [Required] + [MaxLength(DataDictionaryMaxLengths.DisplayText)] + public string DisplayText { get; private set; } - public void SetTenantId(Guid? tenantId) - { - TenantId = tenantId; - } - public void SetCode(string code) - { - Guard.NotNullOrWhiteSpace(code, nameof(code), DataDictionaryMaxLengths.Code); - Code = code; - } + /// + /// 描述 + /// + [Required] + [MaxLength(DataDictionaryMaxLengths.Description)] + public string Description { get; private set; } - private void SetDisplayText(string displayText) - { - Guard.NotNullOrWhiteSpace(displayText, nameof(displayText), DataDictionaryMaxLengths.DisplayText); - DisplayText = displayText; - } + /// + /// 字典明细集合 + /// + public List Details { get; private set; } - private void SetDescription(string description) - { - Guard.Length(description, nameof(description), DataDictionaryMaxLengths.Description); - Description = description ?? string.Empty; - } + private DataDictionary() + { + Details = new List(); + } - public void AddDetail(Guid dataDictionayDetailId, string code, string displayText, int order = 1, - string description = "", bool isEnabled = true) - { - if (Details.Any(e => e.Code == code.Trim())) - { - throw new DataDictionaryDomainException(message: "数据字典项已存在"); - } + public DataDictionary( + Guid id, + string code, + string displayText, + string description = null, + Guid? tenantId = null) : base(id) + { + SetProperties(code, displayText, description, tenantId); + Details = new List(); + } - Details.Add(new DataDictionaryDetail(dataDictionayDetailId, Id, code, displayText, order, isEnabled, - description)); - } + private void SetProperties(string code, string displayText, string description, Guid? tenantId) + { + SetCode(code); + SetDisplayText(displayText); + SetDescription(description); + SetTenantId(tenantId); + } - public void RemoveDetail(string detailCode) - { - var detail = Details.FirstOrDefault(item => item.Code == detailCode); - if (null == detail) - { - throw new DataDictionaryDomainException(message: "数据字典项不存在"); - } + public void SetTenantId(Guid? tenantId) + { + TenantId = tenantId; + } + + public void SetCode(string code) + { + Guard.NotNullOrWhiteSpace(code, nameof(code), DataDictionaryMaxLengths.Code); + Code = code; + } + + private void SetDisplayText(string displayText) + { + Guard.NotNullOrWhiteSpace(displayText, nameof(displayText), DataDictionaryMaxLengths.DisplayText); + DisplayText = displayText; + } + + private void SetDescription(string description) + { + Guard.Length(description, nameof(description), DataDictionaryMaxLengths.Description); + Description = description ?? string.Empty; + } - Details.Remove(detail); + public void AddDetail(Guid dataDictionayDetailId, string code, string displayText, int order = 1, + string description = "", bool isEnabled = true) + { + if (Details.Any(e => e.Code == code.Trim())) + { + throw new DataDictionaryDomainException(message: "数据字典项已存在"); } - public void Update(Guid dataDictionayDetailId,string displayText,string description) + Details.Add(new DataDictionaryDetail(dataDictionayDetailId, Id, code, displayText, order, isEnabled, + description)); + } + + public void RemoveDetail(string detailCode) + { + var detail = Details.FirstOrDefault(item => item.Code == detailCode); + if (null == detail) { - SetDescription(description); - SetDisplayText(displayText); + throw new DataDictionaryDomainException(message: "数据字典项不存在"); } + + Details.Remove(detail); + } + + public void Update(Guid dataDictionayDetailId,string displayText,string description) + { + SetDescription(description); + SetDisplayText(displayText); } } \ No newline at end of file diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaryManagementDomainModule.cs b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaryManagementDomainModule.cs index 46122e3e..67a57f43 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaryManagementDomainModule.cs +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaryManagementDomainModule.cs @@ -1,3 +1,5 @@ +using Volo.Abp.AutoMapper; + namespace Lion.AbpPro.DataDictionaryManagement { [DependsOn( diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/GlobalUsings.cs b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/GlobalUsings.cs index 67b9195c..028a1074 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/GlobalUsings.cs +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/GlobalUsings.cs @@ -9,10 +9,9 @@ global using System.Threading.Tasks; global using AutoMapper; global using Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Aggregates; global using Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Dto; -global using Lion.AbpPro.Extension.Customs; +global using Lion.AbpPro.Core; global using Microsoft.Extensions.DependencyInjection; global using Volo.Abp; -global using Volo.Abp.AutoMapper; global using Volo.Abp.Caching; global using Volo.Abp.Data; global using Volo.Abp.DependencyInjection; diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/Lion.AbpPro.DataDictionaryManagement.Domain.csproj b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/Lion.AbpPro.DataDictionaryManagement.Domain.csproj index 0b087f01..1defd52d 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/Lion.AbpPro.DataDictionaryManagement.Domain.csproj +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/Lion.AbpPro.DataDictionaryManagement.Domain.csproj @@ -8,7 +8,7 @@ - + diff --git a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.HttpApi/GlobalUsings.cs b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.HttpApi/GlobalUsings.cs index 9743327b..b8e60a5a 100644 --- a/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.HttpApi/GlobalUsings.cs +++ b/aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.HttpApi/GlobalUsings.cs @@ -2,7 +2,7 @@ global using System.Threading.Tasks; global using Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Dtos; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Microsoft.AspNetCore.Mvc; global using Swashbuckle.AspNetCore.Annotations; global using Volo.Abp.Application.Dtos; \ No newline at end of file diff --git a/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/GlobalUsings.cs b/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/GlobalUsings.cs index f6f12ba8..1cd3447d 100644 --- a/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/GlobalUsings.cs +++ b/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/GlobalUsings.cs @@ -1,7 +1,7 @@ // Global using directives global using System.ComponentModel.DataAnnotations; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Lion.AbpPro.FileManagement.Localization; global using Volo.Abp.Application; global using Volo.Abp.Authorization; diff --git a/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Lion.AbpPro.FileManagement.Application.Contracts.csproj b/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Lion.AbpPro.FileManagement.Application.Contracts.csproj index 0acca856..c699fdd5 100644 --- a/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Lion.AbpPro.FileManagement.Application.Contracts.csproj +++ b/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Application.Contracts/Lion.AbpPro.FileManagement.Application.Contracts.csproj @@ -9,7 +9,6 @@ - diff --git a/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementDomainSharedModule.cs b/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementDomainSharedModule.cs index f59a361b..584fc23d 100644 --- a/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementDomainSharedModule.cs +++ b/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/FileManagementDomainSharedModule.cs @@ -1,7 +1,10 @@ +using Lion.AbpPro.Core; + namespace Lion.AbpPro.FileManagement; [DependsOn( - typeof(AbpValidationModule) + typeof(AbpValidationModule), + typeof(LionAbpProCoreModule) )] public class FileManagementDomainSharedModule : AbpModule { diff --git a/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Lion.AbpPro.FileManagement.Domain.Shared.csproj b/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Lion.AbpPro.FileManagement.Domain.Shared.csproj index 11348083..262d0941 100644 --- a/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Lion.AbpPro.FileManagement.Domain.Shared.csproj +++ b/aspnet-core/modules/FileManagement/src/Lion.AbpPro.FileManagement.Domain.Shared/Lion.AbpPro.FileManagement.Domain.Shared.csproj @@ -20,4 +20,8 @@ + + + + diff --git a/aspnet-core/modules/NotificationManagement/host/Lion.AbpPro.NotificationManagement.HttpApi.Host/Lion.AbpPro.NotificationManagement.HttpApi.Host.csproj b/aspnet-core/modules/NotificationManagement/host/Lion.AbpPro.NotificationManagement.HttpApi.Host/Lion.AbpPro.NotificationManagement.HttpApi.Host.csproj index f35464bc..95014414 100644 --- a/aspnet-core/modules/NotificationManagement/host/Lion.AbpPro.NotificationManagement.HttpApi.Host/Lion.AbpPro.NotificationManagement.HttpApi.Host.csproj +++ b/aspnet-core/modules/NotificationManagement/host/Lion.AbpPro.NotificationManagement.HttpApi.Host/Lion.AbpPro.NotificationManagement.HttpApi.Host.csproj @@ -33,7 +33,7 @@ - + diff --git a/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/GlobalUsings.cs b/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/GlobalUsings.cs index 96cebeb8..7c8757ae 100644 --- a/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/GlobalUsings.cs +++ b/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Application.Contracts/GlobalUsings.cs @@ -5,8 +5,7 @@ global using System.Collections.Generic; global using System.ComponentModel.DataAnnotations; global using System.Threading; global using System.Threading.Tasks; -global using Lion.AbpPro.Extension.Customs.Dtos; -global using Lion.AbpPro.Extension.System; +global using Lion.AbpPro.Core; global using Lion.AbpPro.NotificationManagement.Localization; global using Lion.AbpPro.NotificationManagement.Notifications.Dtos; global using Lion.AbpPro.NotificationManagement.Notifications.Enums; diff --git a/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Lion.AbpPro.NotificationManagement.Domain.Shared.csproj b/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Lion.AbpPro.NotificationManagement.Domain.Shared.csproj index 41165cfb..fe97bd59 100644 --- a/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Lion.AbpPro.NotificationManagement.Domain.Shared.csproj +++ b/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Lion.AbpPro.NotificationManagement.Domain.Shared.csproj @@ -23,7 +23,7 @@ - + diff --git a/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/NotificationManagementDomainSharedModule.cs b/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/NotificationManagementDomainSharedModule.cs index f363963c..16d75426 100644 --- a/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/NotificationManagementDomainSharedModule.cs +++ b/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/NotificationManagementDomainSharedModule.cs @@ -1,7 +1,10 @@ +using Lion.AbpPro.Core; + namespace Lion.AbpPro.NotificationManagement { [DependsOn( - typeof(AbpValidationModule) + typeof(AbpValidationModule), + typeof(LionAbpProCoreModule) )] public class NotificationManagementDomainSharedModule : AbpModule { diff --git a/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/GlobalUsings.cs b/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/GlobalUsings.cs index 9c5d93e4..6edcd3c1 100644 --- a/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/GlobalUsings.cs +++ b/aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/GlobalUsings.cs @@ -8,7 +8,7 @@ global using System.Runtime.Serialization; global using System.Threading; global using System.Threading.Tasks; global using AutoMapper; -global using Lion.AbpPro.Extension.Customs; +global using Lion.AbpPro.Core; global using Lion.AbpPro.NotificationManagement.Notifications; global using Lion.AbpPro.NotificationManagement.Notifications.Aggregates; global using Lion.AbpPro.NotificationManagement.Notifications.LocalEvents; diff --git a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs index 68b96b4e..09dd4f0e 100644 --- a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs +++ b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/GlobalUsings.cs @@ -14,7 +14,7 @@ global using Hangfire.States; global using Hangfire.Storage; global using Lion.AbpPro.CAP; global using Lion.AbpPro.EntityFrameworkCore; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Lion.AbpPro.Extensions; global using Lion.AbpPro.Extensions.Hangfire; global using Lion.AbpPro.Extensions.Middlewares; diff --git a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Lion.AbpPro.HttpApi.Host.csproj b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Lion.AbpPro.HttpApi.Host.csproj index a54d269b..b1d7f37b 100644 --- a/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Lion.AbpPro.HttpApi.Host.csproj +++ b/aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/Lion.AbpPro.HttpApi.Host.csproj @@ -44,8 +44,7 @@ - - + diff --git a/aspnet-core/services/src/Lion.AbpPro.Application.Contracts/ElasticSearches/ILionAbpProLogAppService.cs b/aspnet-core/services/src/Lion.AbpPro.Application.Contracts/ElasticSearches/ILionAbpProLogAppService.cs index f8fb3b98..180852de 100644 --- a/aspnet-core/services/src/Lion.AbpPro.Application.Contracts/ElasticSearches/ILionAbpProLogAppService.cs +++ b/aspnet-core/services/src/Lion.AbpPro.Application.Contracts/ElasticSearches/ILionAbpProLogAppService.cs @@ -9,6 +9,6 @@ namespace Lion.AbpPro.ElasticSearches /// /// /// - Task> PaingAsync(PagingElasticSearchLogInput input); + Task> PaingAsync(PagingElasticSearchLogInput input); } } \ No newline at end of file diff --git a/aspnet-core/services/src/Lion.AbpPro.Application.Contracts/GlobalUsings.cs b/aspnet-core/services/src/Lion.AbpPro.Application.Contracts/GlobalUsings.cs index dd1c25a3..c48184fc 100644 --- a/aspnet-core/services/src/Lion.AbpPro.Application.Contracts/GlobalUsings.cs +++ b/aspnet-core/services/src/Lion.AbpPro.Application.Contracts/GlobalUsings.cs @@ -3,7 +3,7 @@ global using System; global using System.Threading.Tasks; global using Lion.AbpPro.DataDictionaryManagement; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Volo.Abp.Application.Services; global using Volo.Abp.Authorization.Permissions; global using Volo.Abp.DependencyInjection; diff --git a/aspnet-core/services/src/Lion.AbpPro.Application/AbpProApplicationModule.cs b/aspnet-core/services/src/Lion.AbpPro.Application/AbpProApplicationModule.cs index 39371f62..177a81d7 100644 --- a/aspnet-core/services/src/Lion.AbpPro.Application/AbpProApplicationModule.cs +++ b/aspnet-core/services/src/Lion.AbpPro.Application/AbpProApplicationModule.cs @@ -17,7 +17,6 @@ namespace Lion.AbpPro { options.AddMaps(); }); - } } } diff --git a/aspnet-core/services/src/Lion.AbpPro.Application/ElasticSearches/LionAbpProLogAppService.cs b/aspnet-core/services/src/Lion.AbpPro.Application/ElasticSearches/LionAbpProLogAppService.cs index d4debae3..3c31c193 100644 --- a/aspnet-core/services/src/Lion.AbpPro.Application/ElasticSearches/LionAbpProLogAppService.cs +++ b/aspnet-core/services/src/Lion.AbpPro.Application/ElasticSearches/LionAbpProLogAppService.cs @@ -13,7 +13,7 @@ namespace Lion.AbpPro.ElasticSearches _configuration = configuration; } [Authorize(Policy = AbpProPermissions.SystemManagement.ES)] - public async Task> PaingAsync(PagingElasticSearchLogInput input) + public async Task> PaingAsync(PagingElasticSearchLogInput input) { var IndexName = _configuration.GetValue("ElasticSearch:SearchIndexFormat"); // 默认查询当天 @@ -52,7 +52,7 @@ namespace Lion.AbpPro.ElasticSearches if (result.HitsMetadata != null) { - return new CustomePagedResultDto + return new CustomPagedResultDto ( result.HitsMetadata.Total.Value, ObjectMapper diff --git a/aspnet-core/services/src/Lion.AbpPro.Application/GlobalUsings.cs b/aspnet-core/services/src/Lion.AbpPro.Application/GlobalUsings.cs index b78b13ca..52b6be05 100644 --- a/aspnet-core/services/src/Lion.AbpPro.Application/GlobalUsings.cs +++ b/aspnet-core/services/src/Lion.AbpPro.Application/GlobalUsings.cs @@ -9,8 +9,7 @@ global using Lion.AbpPro.BasicManagement; global using Lion.AbpPro.DataDictionaryManagement; global using Lion.AbpPro.ElasticSearches.Dto; global using Lion.AbpPro.ElasticSearches.Providers; -global using Lion.AbpPro.Extension.Customs.Dtos; -global using Lion.AbpPro.Extension.System; +global using Lion.AbpPro.Core; global using Lion.AbpPro.FreeSqlRepository; global using Lion.AbpPro.NotificationManagement; global using Lion.AbpPro.Permissions; diff --git a/aspnet-core/services/src/Lion.AbpPro.Domain.Shared/AbpProDomainSharedModule.cs b/aspnet-core/services/src/Lion.AbpPro.Domain.Shared/AbpProDomainSharedModule.cs index 7f990d96..5fc54d51 100644 --- a/aspnet-core/services/src/Lion.AbpPro.Domain.Shared/AbpProDomainSharedModule.cs +++ b/aspnet-core/services/src/Lion.AbpPro.Domain.Shared/AbpProDomainSharedModule.cs @@ -1,12 +1,14 @@ using Lion.AbpPro.BasicManagement; using Lion.AbpPro.BasicManagement.Localization; +using Lion.AbpPro.Core; namespace Lion.AbpPro { [DependsOn( typeof(BasicManagementDomainSharedModule), typeof(DataDictionaryManagementDomainSharedModule), - typeof(NotificationManagementDomainSharedModule) + typeof(NotificationManagementDomainSharedModule), + typeof(LionAbpProCoreModule) )] public class AbpProDomainSharedModule : AbpModule { diff --git a/aspnet-core/services/src/Lion.AbpPro.Domain.Shared/Lion.AbpPro.Domain.Shared.csproj b/aspnet-core/services/src/Lion.AbpPro.Domain.Shared/Lion.AbpPro.Domain.Shared.csproj index e8a3a31b..c73d5e6e 100644 --- a/aspnet-core/services/src/Lion.AbpPro.Domain.Shared/Lion.AbpPro.Domain.Shared.csproj +++ b/aspnet-core/services/src/Lion.AbpPro.Domain.Shared/Lion.AbpPro.Domain.Shared.csproj @@ -15,7 +15,6 @@ - diff --git a/aspnet-core/services/src/Lion.AbpPro.HttpApi/Controllers/Systems/LionAbpProLogController.cs b/aspnet-core/services/src/Lion.AbpPro.HttpApi/Controllers/Systems/LionAbpProLogController.cs index 4103624d..a6dc4aa3 100644 --- a/aspnet-core/services/src/Lion.AbpPro.HttpApi/Controllers/Systems/LionAbpProLogController.cs +++ b/aspnet-core/services/src/Lion.AbpPro.HttpApi/Controllers/Systems/LionAbpProLogController.cs @@ -12,7 +12,7 @@ namespace Lion.AbpPro.Controllers.Systems [HttpPost("page")] [SwaggerOperation(summary: "分页获取Es日志", Tags = new[] { "EsLog" })] - public Task> PaingAsync(PagingElasticSearchLogInput input) + public Task> PaingAsync(PagingElasticSearchLogInput input) { return _companyNameAbpProLogAppService.PaingAsync(input); } diff --git a/aspnet-core/services/src/Lion.AbpPro.HttpApi/GlobalUsings.cs b/aspnet-core/services/src/Lion.AbpPro.HttpApi/GlobalUsings.cs index 5d61f705..674055ae 100644 --- a/aspnet-core/services/src/Lion.AbpPro.HttpApi/GlobalUsings.cs +++ b/aspnet-core/services/src/Lion.AbpPro.HttpApi/GlobalUsings.cs @@ -3,7 +3,7 @@ global using Lion.AbpPro.DataDictionaryManagement; global using Lion.AbpPro.ElasticSearches; global using Lion.AbpPro.ElasticSearches.Dto; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Lion.AbpPro.NotificationManagement; global using Localization.Resources.AbpUi; global using Microsoft.AspNetCore.Mvc; diff --git a/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/GlobalUsings.cs b/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/GlobalUsings.cs index 3cbb2286..089ec437 100644 --- a/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/GlobalUsings.cs +++ b/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/GlobalUsings.cs @@ -6,7 +6,7 @@ global using System.Linq; global using System.Net; global using System.Reflection; global using Consul; -global using Lion.AbpPro.Extension.Customs.Dtos; +global using Lion.AbpPro.Core; global using Lion.AbpPro.Shared.Hosting.Microservices.Microsoft.Extensions.DependencyInjection; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Cors; diff --git a/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion.AbpPro.Shared.Hosting.Microservices.csproj b/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion.AbpPro.Shared.Hosting.Microservices.csproj index e7e198e4..5367cc1f 100644 --- a/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion.AbpPro.Shared.Hosting.Microservices.csproj +++ b/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Lion.AbpPro.Shared.Hosting.Microservices.csproj @@ -17,6 +17,6 @@ - + diff --git a/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/SharedHostingMicroserviceModule.cs b/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/SharedHostingMicroserviceModule.cs index c8629570..ca4530a4 100644 --- a/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/SharedHostingMicroserviceModule.cs +++ b/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/SharedHostingMicroserviceModule.cs @@ -4,7 +4,8 @@ namespace Lion.AbpPro.Shared.Hosting.Microservices { [DependsOn( typeof(AbpSwashbuckleModule), - typeof(AbpAutofacModule))] + typeof(AbpAutofacModule), + typeof(LionAbpProCoreModule))] public class SharedHostingMicroserviceModule : AbpModule { private const string DefaultCorsPolicyName = "Default";