Repository: personball/abplus Branch: master Commit: df6418a615e5 Files: 460 Total size: 1.6 MB Directory structure: gitextract_3b8q698k/ ├── .gitignore ├── .nuget/ │ └── NuGet.Config ├── Abplus.sln ├── LICENSE ├── Nupkg/ │ ├── pack.bat │ └── push-all-packages-in-current_folder.bat ├── README.md ├── common.props ├── src/ │ ├── Abplus/ │ │ ├── Abplus.csproj │ │ ├── Abplus.nuspec │ │ ├── Application/ │ │ │ ├── Navigation/ │ │ │ │ └── MenuItemDefinitionPlugInExtensions.cs │ │ │ └── Services/ │ │ │ └── Dto/ │ │ │ ├── IHasDateTimeFilterRequest.cs │ │ │ ├── IHasKeywordFilterRequest.cs │ │ │ ├── IPaginationResultRequest.cs │ │ │ └── PaginationRequestInput.cs │ │ ├── Currencies/ │ │ │ └── ChineseCentExtension.cs │ │ ├── Events/ │ │ │ └── Bus/ │ │ │ └── ChangedEventData.cs │ │ ├── Extensions/ │ │ │ ├── DateTimeExtensions.cs │ │ │ ├── EnumExtensions.cs │ │ │ ├── GuidExtensions.cs │ │ │ ├── IntExtension.cs │ │ │ ├── NullableDateTimeExtensions.cs │ │ │ └── StringExtensions.cs │ │ ├── IO/ │ │ │ ├── IFileStorage.cs │ │ │ └── NullFileStorage.cs │ │ ├── Interceptors/ │ │ │ ├── AsyncHandlingInterceptor.cs │ │ │ └── IAsyncInterceptorHandler.cs │ │ ├── Json/ │ │ │ └── LargeNumJsonConverter.cs │ │ ├── MqMessages/ │ │ │ ├── IMqMessagePublisher.cs │ │ │ ├── MessageTrackers/ │ │ │ │ ├── DefaultInMemoryMessageTracker.cs │ │ │ │ └── IMessageTracker.cs │ │ │ └── NullMqMessagePublisher.cs │ │ ├── PlugIns/ │ │ │ ├── IPlugInAreaRegistration.cs │ │ │ ├── IPlugInAuthorizationProvider.cs │ │ │ └── IPlugInNavigationProvider.cs │ │ ├── QrCode/ │ │ │ └── IQrCodeScannedRealTimeNotifier.cs │ │ ├── Reservations/ │ │ │ ├── Events/ │ │ │ │ ├── ReservationCancelledEventData.cs │ │ │ │ ├── ReservationEventDataBase.cs │ │ │ │ └── ReservationSuccessEventData.cs │ │ │ ├── IReservation.cs │ │ │ ├── IReservationBody.cs │ │ │ ├── ReservationBase.cs │ │ │ └── ReservationBodyBase.cs │ │ ├── Runtime/ │ │ │ └── OS/ │ │ │ ├── EnvDescription.cs │ │ │ └── EnvironmentHelper.cs │ │ └── TimeRanges/ │ │ └── TimeRange.cs │ ├── Abplus.AspNetCore.SignalR/ │ │ ├── Abplus.AspNetCore.SignalR.csproj │ │ ├── Abplus.AspNetCore.SignalR.nuspec │ │ ├── Configuration/ │ │ │ └── Startup/ │ │ │ └── RedisOnlineClientManagerConfiguationExtensions.cs │ │ ├── RealTime/ │ │ │ ├── IRedisOnlineClientManagerModuleConfig.cs │ │ │ ├── RedisOnlineClientManager.cs │ │ │ ├── RedisOnlineClientManagerModule.cs │ │ │ └── RedisOnlineClientManagerModuleConfig.cs │ │ └── Web/ │ │ └── SignalR/ │ │ └── QrScan/ │ │ ├── SignalRQrCodeScannedRealTimeNotifier.cs │ │ └── SignalRQrCodeScannedRealTimeNotifierModule.cs │ ├── Abplus.IO.AliyunOSSStorage/ │ │ ├── Abplus.IO.AliyunOSSStorage.csproj │ │ ├── Configuration/ │ │ │ └── Startup/ │ │ │ └── AliyunOSSStorageConfigurationExtensions.cs │ │ ├── IO/ │ │ │ ├── AliyunOSSStorage/ │ │ │ │ ├── AliyunOSSStorage.cs │ │ │ │ ├── AliyunOSSStorageModule.cs │ │ │ │ ├── AliyunOSSStorageModuleConfiguration.cs │ │ │ │ └── IAliyunOSSStorageModuleConfiguration.cs │ │ │ └── AliyunOSSStorageConsts.cs │ │ └── Localization/ │ │ ├── AliyunOSSStorageLocalizationConfigurer.cs │ │ └── SourceFiles/ │ │ ├── AliyunOSSStorage-zh-Hans.xml │ │ └── AliyunOSSStorage.xml │ ├── Abplus.IO.AzureBlobStorage/ │ │ ├── Abplus.IO.AzureBlobStorage.csproj │ │ ├── Abplus.IO.AzureBlobStorage.nuspec │ │ ├── Configuration/ │ │ │ └── Startup/ │ │ │ └── AzureBlobFileStorageConfigurationExtensions.cs │ │ ├── IO/ │ │ │ ├── AzureBlobStorage/ │ │ │ │ ├── AzureBlobFileStorage.cs │ │ │ │ ├── AzureBlobFileStorageConfig.cs │ │ │ │ ├── AzureBlobFileStorageModule.cs │ │ │ │ ├── AzureBlobFileStorageModuleConfig.cs │ │ │ │ ├── Configuration/ │ │ │ │ │ ├── AzureBlobFileStorageSetting.cs │ │ │ │ │ ├── AzureBlobFileStorageSettingNames.cs │ │ │ │ │ └── AzureBlobFileStorageSettingProvider.cs │ │ │ │ ├── IAzureBlobFileStorageConfig.cs │ │ │ │ └── IAzureBlobFileStorageModuleConfig.cs │ │ │ └── AzureBlobStorageConsts.cs │ │ └── Localization/ │ │ ├── AzureBlobStorageLocalizationConfigurer.cs │ │ └── SourceFiles/ │ │ ├── AbplusAzureBlobStorage-zh-Hans.xml │ │ └── AbplusAzureBlobStorage.xml │ ├── Abplus.IO.LocalFileSystem/ │ │ ├── Abplus.IO.LocalFileSystem.csproj │ │ ├── IO/ │ │ │ ├── LocalFileSystem/ │ │ │ │ ├── ILocalFileSystemStorageConfig.cs │ │ │ │ ├── LocalFileSystemStorage.cs │ │ │ │ ├── LocalFileSystemStorageConfig.cs │ │ │ │ ├── LocalFileSystemStorageModule.cs │ │ │ │ ├── LocalFileSystemStorageSettingNames.cs │ │ │ │ └── LocalFileSystemStorageSettingProvider.cs │ │ │ └── LocalFileSystemConsts.cs │ │ └── Localization/ │ │ ├── LocalFileSystemLocalizationConfigurer.cs │ │ └── SourceFiles/ │ │ ├── AbplusLocalFileSystem-zh-Hans.xml │ │ └── AbplusLocalFileSystem.xml │ ├── Abplus.MqMessages/ │ │ ├── Abplus.MqMessages.csproj │ │ ├── Abplus.MqMessages.nuspec │ │ ├── Configuration/ │ │ │ └── Startup/ │ │ │ └── ExceptionLogInterceptorRegistrar.cs │ │ └── MqMessages/ │ │ ├── AuditingStores/ │ │ │ └── AuditInfoMqMessage.cs │ │ ├── AutoGeneration/ │ │ │ └── DontGenerateMqMessage.cs │ │ ├── AutoMapper/ │ │ │ └── AutoEventsMapToMqMessagesHelper.cs │ │ ├── Handlers/ │ │ │ └── EventDataPublishHandlerBase.cs │ │ └── MqHandlers/ │ │ ├── AbpMqHandlerBase.cs │ │ └── ExceptionLoggling/ │ │ ├── ExceptionLogAttribute.cs │ │ ├── ExceptionLogHandler.cs │ │ └── ExceptionLogInterceptor.cs │ ├── Abplus.MqMessages.AuditingConsumerHandler/ │ │ ├── Abplus.MqMessages.AuditingConsumerHandler.csproj │ │ ├── Abplus.MqMessages.AuditingConsumerHandler.nuspec │ │ ├── Auditing/ │ │ │ └── AuditingStore/ │ │ │ ├── AuditingConsumerRebusHandlerModule.cs │ │ │ ├── AuditingConsumerRebusHandlerModuleConfig.cs │ │ │ ├── IAuditingConsumerRebusHandlerModuleConfig.cs │ │ │ └── MqMessageAuditingStoreRebusHandler.cs │ │ └── Configuration/ │ │ └── Startup/ │ │ └── AuditingConsumerRebusHandlerConfigurationExtensions.cs │ ├── Abplus.MqMessages.AuditingStore/ │ │ ├── Abplus.MqMessages.AuditingStore.csproj │ │ ├── Abplus.MqMessages.AuditingStore.nuspec │ │ └── Auditing/ │ │ └── AuditingStores/ │ │ ├── MqMessageAuditingStore.cs │ │ └── MqMessageAuditingStoreModule.cs │ ├── Abplus.MqMessages.IndexToES/ │ │ ├── Abplus.MqMessages.IndexToES.csproj │ │ ├── Abplus.MqMessages.IndexToES.nuspec │ │ ├── DateTimeExtensions.cs │ │ ├── IndexFreq.cs │ │ └── MqMessages/ │ │ └── MqHandlers/ │ │ ├── MqMessageIndexToESHandlerBase.cs │ │ ├── MqMessageIndexToESHandlerBuilder.cs │ │ ├── MqMessageIndexToESHandlerBuilder.tt │ │ ├── MqMessagesT4Register.cs │ │ └── T4MultipleOutputManager.ttinclude │ ├── Abplus.MqMessages.RebusCore/ │ │ ├── Abplus.MqMessages.RebusCore.csproj │ │ ├── Abplus.MqMessages.RebusCore.nuspec │ │ └── MqMessages/ │ │ └── Publishers/ │ │ ├── RebusRabbitMqPublisher.cs │ │ └── RebusRabbitMqPublisherCoreModule.cs │ ├── Abplus.MqMessages.RebusRabbitMqConsumer/ │ │ ├── Abplus.MqMessages.RebusRabbitMqConsumer.csproj │ │ ├── Abplus.MqMessages.RebusRabbitMqConsumer.nuspec │ │ ├── Configuration/ │ │ │ └── Startup/ │ │ │ └── RebusRabbitMqConsumerConfigurationExtensions.cs │ │ └── MqMessages/ │ │ └── Consumers/ │ │ ├── IRebusRabbitMqConsumerModuleConfig.cs │ │ ├── RebusRabbitMqConsumerModule.cs │ │ └── RebusRabbitMqConsumerModuleConfig.cs │ ├── Abplus.MqMessages.RebusRabbitMqPublisher/ │ │ ├── Abplus.MqMessages.RebusRabbitMqPublisher.csproj │ │ ├── Abplus.MqMessages.RebusRabbitMqPublisher.nuspec │ │ ├── Configuration/ │ │ │ └── Startup/ │ │ │ └── RebusRabbitMqPublisherConfigurationExtensions.cs │ │ └── MqMessages/ │ │ └── Publishers/ │ │ ├── IRebusRabbitMqPublisherModuleConfig.cs │ │ ├── RebusRabbitMqPublisherModule.cs │ │ └── RebusRabbitMqPublisherModuleConfig.cs │ ├── Abplus.MqMessages.RedisStoreMessageTracker/ │ │ ├── Abplus.MqMessages.RedisStoreMessageTracker.csproj │ │ ├── Abplus.MqMessages.RedisStoreMessageTracker.nuspec │ │ └── MqMessages/ │ │ └── MessageTrackers/ │ │ ├── RedisStoreMessageTracker.cs │ │ └── RedisStoreMessageTrackerModule.cs │ ├── Abplus.T4.PermissionsFromJson/ │ │ ├── Abplus.T4.PermissionsFromJson.csproj │ │ ├── Abplus.T4.PermissionsFromJson.nuspec │ │ └── Authorization/ │ │ └── Builders/ │ │ ├── BuilderUtils.cs │ │ ├── PermissionBuilder.cs │ │ ├── PermissionBuilder.tt │ │ ├── Permissions/ │ │ │ └── Sample.json │ │ └── T4MultipleOutputManager.ttinclude │ └── Samples/ │ ├── AuditingConsumer/ │ │ ├── Sample.AuditingConsumerHandler/ │ │ │ ├── Program.cs │ │ │ ├── Sample.AuditingConsumerHandler.csproj │ │ │ ├── SampleAuditingConsumerHandlerBootstrap.cs │ │ │ └── SampleAuditingConsumerHandlerModule.cs │ │ └── Sample.MqMessageAuditingStore/ │ │ ├── Application/ │ │ │ ├── ITestAuditingStoreAppService.cs │ │ │ ├── TestAuditingInput.cs │ │ │ └── TestAuditingStoreAppService.cs │ │ ├── BackgroudWorker/ │ │ │ └── TestWorker.cs │ │ ├── Program.cs │ │ ├── Sample.MqMessageAuditingStore.csproj │ │ ├── SampleMqMessageAuditingStoreBootstrap.cs │ │ └── SampleMqMessageAuditingStoreModule.cs │ ├── FileStorage/ │ │ ├── Sample.AliyunOSSStorage/ │ │ │ ├── BackgroundWorker/ │ │ │ │ └── TestWorker.cs │ │ │ ├── Program.cs │ │ │ ├── Sample.AliyunOSSStorageConsole.csproj │ │ │ ├── SampleAliyunOSSStorageBootstrap.cs │ │ │ └── SampleAliyunOSSStorageModule.cs │ │ ├── Sample.AzureBlobStorage/ │ │ │ ├── BackgroundWorker/ │ │ │ │ └── TestWorker.cs │ │ │ ├── Program.cs │ │ │ ├── Sample.AzureBlobStorageConsole.csproj │ │ │ ├── SampleAzureBlobStorageBootstrap.cs │ │ │ └── SampleAzureBlobStorageModule.cs │ │ └── Sample.LocalFileSystem/ │ │ ├── Program.cs │ │ ├── Sample.LocalFileSystemConsole.csproj │ │ ├── SampleLocalFileSystemBootstrap.cs │ │ └── SampleLocalFileSystemModule.cs │ ├── Sample.DotNetCoreConsumerHost/ │ │ ├── Handlers/ │ │ │ └── TestHandler.cs │ │ ├── Program.cs │ │ ├── Sample.DotNetCoreConsumerHost.csproj │ │ ├── SampleConsumerHostBootstrap.cs │ │ └── SampleConsumerHostModule.cs │ ├── Sample.DotNetCorePublisherHost/ │ │ ├── BackgroundWorker/ │ │ │ └── TestWorker.cs │ │ ├── Program.cs │ │ ├── Sample.DotNetCorePublisherHost.csproj │ │ ├── SamplePublisherHostBootstrap.cs │ │ └── SamplePublisherHostModule.cs │ ├── Sample.DotNetFxConsumerHost/ │ │ ├── App.config │ │ ├── DotNetFxConsumerHostBootstrap.cs │ │ ├── DotNetFxConsumerHostModule.cs │ │ ├── Handlers/ │ │ │ └── TestHandler.cs │ │ ├── NLog.config │ │ ├── NLog.xsd │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── AssemblyInfo.cs │ │ ├── Sample.DotNetFxConsumerHost.csproj │ │ └── packages.config │ ├── Sample.DotNetFxPublisherHost/ │ │ ├── App.config │ │ ├── BackgroundWorker/ │ │ │ └── TestWorker.cs │ │ ├── DotNetFxPublisherHostBootstrap.cs │ │ ├── DotNetFxPublisherHostModule.cs │ │ ├── NLog.config │ │ ├── NLog.xsd │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── AssemblyInfo.cs │ │ ├── Sample.DotNetFxPublisherHost.csproj │ │ └── packages.config │ └── Sample.MqMessages/ │ ├── Sample.MqMessages.csproj │ └── TestMessage.cs └── src2/ ├── Abplus/ │ ├── Abplus.csproj │ ├── Abplus.nuspec │ ├── AbplusConsts.cs │ ├── Application/ │ │ ├── Navigation/ │ │ │ └── MenuItemDefinitionPlugInExtensions.cs │ │ └── Services/ │ │ └── Dto/ │ │ ├── IHasDateTimeFilterRequest.cs │ │ ├── IHasKeywordFilterRequest.cs │ │ ├── IPaginationResultRequest.cs │ │ └── PaginationRequestInput.cs │ ├── Currencies/ │ │ └── ChineseCentExtension.cs │ ├── Events/ │ │ └── Bus/ │ │ ├── ChangedEventData.cs │ │ └── IShouldBePublish.cs │ ├── Extensions/ │ │ ├── DateTimeExtensions.cs │ │ ├── EnumExtensions.cs │ │ ├── GuidExtensions.cs │ │ ├── IntExtension.cs │ │ ├── NullableDateTimeExtensions.cs │ │ └── StringExtensions.cs │ ├── Interceptors/ │ │ ├── AsyncHandlingInterceptor.cs │ │ └── IAsyncInterceptorHandler.cs │ ├── Json/ │ │ └── LargeNumJsonConverter.cs │ ├── MqMessages/ │ │ ├── IMqMessagePublisher.cs │ │ ├── MessageTrackers/ │ │ │ ├── DefaultInMemoryMessageTracker.cs │ │ │ └── IMessageTracker.cs │ │ └── NullMqMessagePublisher.cs │ ├── PlugIns/ │ │ ├── IPlugInAreaRegistration.cs │ │ ├── IPlugInAuthorizationProvider.cs │ │ └── IPlugInNavigationProvider.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── QrCode/ │ │ └── IQrCodeScannedRealTimeNotifier.cs │ ├── Reservations/ │ │ ├── Events/ │ │ │ ├── ReservationCancelledEventData.cs │ │ │ ├── ReservationEventDataBase.cs │ │ │ └── ReservationSuccessEventData.cs │ │ ├── IReservation.cs │ │ ├── IReservationBody.cs │ │ ├── ReservationBase.cs │ │ └── ReservationBodyBase.cs │ ├── TimeRanges/ │ │ └── TimeRange.cs │ ├── app.config │ └── packages.config ├── Abplus.Common/ │ ├── Abplus.Common.csproj │ ├── Abplus.Common.nuspec │ ├── Application/ │ │ └── Services/ │ │ └── Dto/ │ │ ├── IPagedQueryInput.cs │ │ └── PagedQueryInput.cs │ ├── Linq/ │ │ └── Extensions/ │ │ └── IQueryableExtension.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.EntityFramework/ │ ├── Abplus.EntityFramework.csproj │ ├── Abplus.EntityFramework.nuspec │ ├── App.config │ ├── EntityFramework/ │ │ ├── DbContextUtils.cs │ │ └── DbModelBuilderExtensions.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ └── packages.config ├── Abplus.Events.Producer/ │ ├── Abplus.Events.Producer.csproj │ ├── Abplus.Events.Producer.nuspec │ ├── Events/ │ │ └── Producer/ │ │ ├── AbpEventsProducerModule.cs │ │ ├── Handler/ │ │ │ └── PublishAllEventsHandler.cs │ │ ├── IProducer.cs │ │ └── NullProducer.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ └── packages.config ├── Abplus.MqMessages/ │ ├── Abplus.MqMessages.csproj │ ├── Abplus.MqMessages.nuspec │ ├── Configuration/ │ │ └── Startup/ │ │ └── ExceptionLogInterceptorRegistrar.cs │ ├── MqMessages/ │ │ ├── AutoMapper/ │ │ │ └── AutoEventsMapToMqMessagesHelper.cs │ │ ├── Handlers/ │ │ │ └── EventDataPublishHandlerBase.cs │ │ └── MqHandlers/ │ │ ├── AbpMqHandlerBase.cs │ │ └── ExceptionLoggling/ │ │ ├── ExceptionLogAttribute.cs │ │ ├── ExceptionLogHandler.cs │ │ └── ExceptionLogInterceptor.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.MqMessages.AuditingConsumerHandler/ │ ├── Abplus.MqMessages.AuditingConsumerRebusHandler.csproj │ ├── Auditing/ │ │ └── AuditingStore/ │ │ ├── AuditingConsumerRebusHandlerModule.cs │ │ ├── AuditingConsumerRebusHandlerModuleConfig.cs │ │ ├── IAuditingConsumerRebusHandlerModuleConfig.cs │ │ └── MqMessageAuditingStoreRebusHandler.cs │ ├── Configuration/ │ │ └── Startup/ │ │ └── AuditingConsumerRebusHandlerConfigurationExtensions.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.MqMessages.AuditingStore/ │ ├── Abplus.MqMessages.AuditingStore.csproj │ ├── Abplus.MqMessages.AuditingStore.nuspec │ ├── Auditing/ │ │ └── AuditingStores/ │ │ ├── AuditInfoMqMessage.cs │ │ ├── MqMessageAuditingStore.cs │ │ └── MqMessageAuditingStoreModule.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.MqMessages.IndexToES/ │ ├── Abplus.MqMessages.IndexToES.csproj │ ├── Abplus.MqMessages.IndexToES.nuspec │ ├── DateTimeExtensions.cs │ ├── IndexFreq.cs │ ├── MqMessages/ │ │ └── MqHandlers/ │ │ ├── MqMessageIndexToESHandlerBase.cs │ │ ├── MqMessageIndexToESHandlerBuilder.cs │ │ ├── MqMessageIndexToESHandlerBuilder.tt │ │ ├── MqMessagesT4Register.cs │ │ └── T4MultipleOutputManager.ttinclude │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.MqMessages.RebusConsumer/ │ ├── Abplus.MqMessages.RebusConsumer.nuspec │ ├── Abplus.MqMessages.RebusRabbitMqConsumer.csproj │ ├── Configuration/ │ │ └── Startup/ │ │ └── RebusRabbitMqConsumerConfigurationExtensions.cs │ ├── MqMessages/ │ │ └── Consumers/ │ │ ├── IRebusRabbitMqConsumerModuleConfig.cs │ │ ├── RebusRabbitMqConsumerModule.cs │ │ └── RebusRabbitMqConsumerModuleConfig.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.MqMessages.RebusCore/ │ ├── Abplus.MqMessages.RebusCore.csproj │ ├── Abplus.MqMessages.RebusCore.nuspec │ ├── MqMessages/ │ │ └── Publishers/ │ │ ├── RebusRabbitMqPublisher.cs │ │ └── RebusRabbitMqPublisherCoreModule.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.MqMessages.RebusPublisher/ │ ├── Abplus.MqMessages.RebusPublisher.nuspec │ ├── Abplus.MqMessages.RebusRabbitMqPublisher.csproj │ ├── Configuration/ │ │ └── Startup/ │ │ └── RebusRabbitMqPublisherConfigurationExtensions.cs │ ├── MqMessages/ │ │ └── Publishers/ │ │ ├── IRebusRabbitMqPublisherModuleConfig.cs │ │ ├── RebusRabbitMqPublisherModule.cs │ │ └── RebusRabbitMqPublisherModuleConfig.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.MqMessages.RedisStoreMessageTracker/ │ ├── Abplus.MqMessages.RedisStoreMessageTracker.csproj │ ├── Abplus.MqMessages.RedisStoreMessageTracker.nuspec │ ├── MqMessages/ │ │ └── MessageTrackers/ │ │ ├── RedisStoreMessageTracker.cs │ │ └── RedisStoreMessageTrackerModule.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.RebusRabbitmqConsumer/ │ ├── Abplus.RebusRabbitmqConsumer.csproj │ ├── Abplus.RebusRabbitmqConsumer.nuspec │ ├── Configuration/ │ │ └── Startup/ │ │ └── AbpRebusRabbitMqConsumerConfigurationExtensions.cs │ ├── Events/ │ │ └── Consumer/ │ │ └── RebusRabbitMq/ │ │ ├── AbpRebusRabbitMqConsumerModule.cs │ │ ├── AbpRebusRabbitMqConsumerModuleConfig.cs │ │ └── IAbpRebusRabbitMqConsumerModuleConfig.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ └── packages.config ├── Abplus.RebusRabbitmqProducer/ │ ├── Abplus.RebusRabbitmqProducer.csproj │ ├── Abplus.RebusRabbitmqProducer.nuspec │ ├── Configuration/ │ │ └── Startup/ │ │ └── AbpRebusRabbitMqProducerConfigurationExtensions.cs │ ├── Events/ │ │ └── Producer/ │ │ └── RebusRabbitMq/ │ │ ├── AbpRebusRabbitMqProducerModule.cs │ │ ├── AbpRebusRabbitMqProducerModuleConfig.cs │ │ ├── IAbpRebusRabbitMqProducerModuleConfig.cs │ │ └── RebusRabbitMqProducer.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Abplus.T4.PermissionsFromJson/ │ ├── Abplus.T4.PermissionsFromJson.csproj │ ├── Abplus.T4.PermissionsFromJson.nuspec │ ├── Authorization/ │ │ └── Builders/ │ │ ├── BuilderUtils.cs │ │ ├── PermissionBuilder.cs │ │ ├── PermissionBuilder.tt │ │ ├── Permissions/ │ │ │ └── Sample.json │ │ └── T4MultipleOutputManager.ttinclude │ └── Properties/ │ └── AssemblyInfo.cs ├── Abplus.Web.Api/ │ ├── Abplus.Web.Api.csproj │ ├── Abplus.Web.Api.nuspec │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── WebApi/ │ │ └── JsonMediaTypeFormatterExtension.cs │ ├── WebApiVersionRoute/ │ │ ├── RoutingConstraints/ │ │ │ ├── VersionConstraint.cs │ │ │ └── VersionedRoute.cs │ │ ├── SysCode.cs │ │ ├── Version.cs │ │ ├── VersionConsts.cs │ │ └── VersionRange.cs │ ├── app.config │ └── packages.config ├── Abplus.Web.PlugIns/ │ ├── Abplus.Web.PlugIns.csproj │ ├── Abplus.Web.PlugIns.csproj.nuspec │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── Web/ │ │ └── Mvc/ │ │ ├── AbpWebPlugInModule.cs │ │ └── Controllers/ │ │ └── PlugInWindsorControllerFactory.cs │ └── packages.config ├── Abplus.Web.SignalR/ │ ├── Abplus.Web.SignalR.csproj │ ├── Abplus.Web.SignalR.nuspec │ ├── Configuration/ │ │ └── Startup/ │ │ └── RedisOnlineClientManagerConfiguationExtensions.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── RealTime/ │ │ ├── IRedisOnlineClientManagerModuleConfig.cs │ │ ├── RedisOnlineClientManager.cs │ │ ├── RedisOnlineClientManagerModule.cs │ │ └── RedisOnlineClientManagerModuleConfig.cs │ ├── Web/ │ │ └── SignalR/ │ │ └── QrScan/ │ │ ├── SignalRQrCodeScannedRealTimeNotifier.cs │ │ └── SignalRQrCodeScannedRealTimeNotifierModule.cs │ ├── app.config │ └── packages.config ├── Abplus.Web.SimpleCaptcha/ │ ├── Abplus.Web.SimpleCaptcha.csproj │ ├── Abplus.Web.SimpleCaptcha.nuspec │ ├── Configuration/ │ │ └── Startup/ │ │ └── SimpleCaptchaManagerConfigurationExtension.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── Web/ │ │ └── SimpleCaptcha/ │ │ ├── ISimpleCaptchaModuleConfig.cs │ │ ├── IVerificationCodeStore.cs │ │ ├── SimpleCaptchaManager.cs │ │ ├── SimpleCaptchaModule.cs │ │ ├── SimpleCaptchaModuleConfig.cs │ │ └── VerificationCodeStores/ │ │ ├── CacheVerificationCodeStore.cs │ │ ├── CookieVerificationCodeStore.cs │ │ └── SessionVerificationCodeStore.cs │ ├── app.config │ └── packages.config ├── Abplus.WebApiClient/ │ ├── Abplus.WebApiClient.csproj │ ├── Abplus.WebApiClient.nuspec │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── WebApiClient/ │ │ ├── AbplusWebApiClient.cs │ │ ├── AbplusWebApiClientModule.cs │ │ ├── AbplusWebApiClientRemoteCallException.cs │ │ └── IAbplusWebApiClient.cs │ ├── app.config │ └── packages.config ├── Samples/ │ ├── Abplus.WebApiVersionRoute.Sample/ │ │ ├── Abplus.WebApiVersionRoute.Sample.csproj │ │ ├── App_Start/ │ │ │ └── WebApiConfig.cs │ │ ├── Controllers/ │ │ │ └── ValueController.cs │ │ ├── Global.asax │ │ ├── Global.asax.cs │ │ ├── Properties/ │ │ │ └── AssemblyInfo.cs │ │ ├── Web.Debug.config │ │ ├── Web.Release.config │ │ ├── Web.config │ │ └── packages.config │ ├── Sample.MqMessages/ │ │ ├── MqMessages/ │ │ │ └── TestMqMessage.cs │ │ ├── Properties/ │ │ │ └── AssemblyInfo.cs │ │ └── Sample.MqMessages.csproj │ ├── Sample.RebusRabbitMqConsumer/ │ │ ├── App.config │ │ ├── Handlers/ │ │ │ └── TestHandler.cs │ │ ├── NLog.config │ │ ├── NLog.xsd │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── AssemblyInfo.cs │ │ ├── Sample.RebusRabbitMqConsumer.csproj │ │ ├── SampleRebusRabbitMqConsumerBootstrap.cs │ │ ├── SampleRebusRabbitMqConsumerModule.cs │ │ └── packages.config │ └── Sample.RebusRabbitMqPublisher/ │ ├── App.config │ ├── BackgroundWorks/ │ │ └── TestWorker.cs │ ├── NLog.config │ ├── NLog.xsd │ ├── Program.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── Sample.RebusRabbitMqPublisher.csproj │ ├── SampleRebusRabbitMqPublisherBootstrap.cs │ ├── SampleRebusRabbitMqPublisherModule.cs │ └── packages.config └── Tests/ └── Abplus.Tests/ ├── Abplus.Tests.csproj ├── Properties/ │ └── AssemblyInfo.cs ├── TimeRanges/ │ └── TimeRange_Tests.cs ├── app.config └── packages.config ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ # Visual Studio 2015 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUNIT *.VisualState.xml TestResult.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # DNX project.lock.json artifacts/ *_i.c *_p.c *_i.h *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # JustCode is a .NET coding add-in .JustCode # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # TODO: Comment the next line if you want to checkin your web deploy settings # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # The packages folder can be ignored because of Package Restore **/packages/* # except build/, which is used as an MSBuild target. !**/packages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/packages/repositories.config # NuGet v3's project.json files produces more ignoreable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.pfx *.publishsettings node_modules/ orleans.codegen.cs # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm # SQL Server files *.mdf *.ldf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # JetBrains Rider .idea/ *.sln.iml /nugetpack /src/Abplus.Common/Configuration /Nupkg/nugetpush.bat /Nupkg/push-all-packages.bat ================================================ FILE: .nuget/NuGet.Config ================================================  ================================================ FILE: Abplus.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{28E1F8EC-E22A-45D3-941F-2A0756D6331D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus", "src\Abplus\Abplus.csproj", "{10C03A51-881C-4779-9B24-5BFCE234C175}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.MqMessages", "src\Abplus.MqMessages\Abplus.MqMessages.csproj", "{5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.MqMessages.AuditingConsumerHandler", "src\Abplus.MqMessages.AuditingConsumerHandler\Abplus.MqMessages.AuditingConsumerHandler.csproj", "{B5E2EC5D-4D8A-4FBE-9434-23B422644B68}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.MqMessages.AuditingStore", "src\Abplus.MqMessages.AuditingStore\Abplus.MqMessages.AuditingStore.csproj", "{AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.MqMessages.IndexToES", "src\Abplus.MqMessages.IndexToES\Abplus.MqMessages.IndexToES.csproj", "{17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.MqMessages.RebusCore", "src\Abplus.MqMessages.RebusCore\Abplus.MqMessages.RebusCore.csproj", "{D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.MqMessages.RedisStoreMessageTracker", "src\Abplus.MqMessages.RedisStoreMessageTracker\Abplus.MqMessages.RedisStoreMessageTracker.csproj", "{7A5BE15C-4B89-4397-920F-A15FB8A76FA5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.T4.PermissionsFromJson", "src\Abplus.T4.PermissionsFromJson\Abplus.T4.PermissionsFromJson.csproj", "{629C519A-14DD-4F1A-B235-AC73AC2622F7}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.MqMessages.RebusRabbitMqConsumer", "src\Abplus.MqMessages.RebusRabbitMqConsumer\Abplus.MqMessages.RebusRabbitMqConsumer.csproj", "{E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.MqMessages.RebusRabbitMqPublisher", "src\Abplus.MqMessages.RebusRabbitMqPublisher\Abplus.MqMessages.RebusRabbitMqPublisher.csproj", "{1C7E75D5-F462-43C7-A230-4E31FAF8CC00}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BE7C78D3-C20F-46D4-A4DD-F66136691F17}" ProjectSection(SolutionItems) = preProject common.props = common.props EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.AspNetCore.SignalR", "src\Abplus.AspNetCore.SignalR\Abplus.AspNetCore.SignalR.csproj", "{6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9D43F9A2-6C7D-44DC-A0A0-3F0C693B9663}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.MqMessages", "src\Samples\Sample.MqMessages\Sample.MqMessages.csproj", "{D71B7FBA-E998-4141-81E6-E319C3941659}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.DotNetCoreConsumerHost", "src\Samples\Sample.DotNetCoreConsumerHost\Sample.DotNetCoreConsumerHost.csproj", "{3AFDA053-190A-4BBF-BF0D-626718239FA4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.DotNetCorePublisherHost", "src\Samples\Sample.DotNetCorePublisherHost\Sample.DotNetCorePublisherHost.csproj", "{3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AuditingConsumer", "AuditingConsumer", "{D67F59C7-8882-4517-AD61-394DA98E94E5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AuditingConsumerHandler", "src\Samples\AuditingConsumer\Sample.AuditingConsumerHandler\Sample.AuditingConsumerHandler.csproj", "{E840877E-2C05-4BF1-859A-3C6D49DFEFE6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.MqMessageAuditingStore", "src\Samples\AuditingConsumer\Sample.MqMessageAuditingStore\Sample.MqMessageAuditingStore.csproj", "{5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.IO.LocalFileSystem", "src\Abplus.IO.LocalFileSystem\Abplus.IO.LocalFileSystem.csproj", "{5D62EA19-7E50-467A-B0BC-76334C2C69E9}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.IO.AzureBlobStorage", "src\Abplus.IO.AzureBlobStorage\Abplus.IO.AzureBlobStorage.csproj", "{3CD46A0D-61E6-4A0C-AF2D-176462DCF601}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileStorage", "FileStorage", "{89AE722E-588C-43F2-B4CB-A05CE184F721}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AzureBlobStorageConsole", "src\Samples\FileStorage\Sample.AzureBlobStorage\Sample.AzureBlobStorageConsole.csproj", "{EF146053-4951-4D97-9AAA-E0C1CA4801D6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.LocalFileSystemConsole", "src\Samples\FileStorage\Sample.LocalFileSystem\Sample.LocalFileSystemConsole.csproj", "{0FCE1B76-0720-4AD0-B353-F604C93DC05F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abplus.IO.AliyunOSSStorage", "src\Abplus.IO.AliyunOSSStorage\Abplus.IO.AliyunOSSStorage.csproj", "{D6E5E010-D782-4B02-94A1-1162852916D9}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AliyunOSSStorageConsole", "src\Samples\FileStorage\Sample.AliyunOSSStorage\Sample.AliyunOSSStorageConsole.csproj", "{543B7B29-B10C-4837-9479-949F7066DAAC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {10C03A51-881C-4779-9B24-5BFCE234C175}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Debug|Any CPU.Build.0 = Debug|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Debug|x64.ActiveCfg = Debug|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Debug|x64.Build.0 = Debug|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Debug|x86.ActiveCfg = Debug|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Debug|x86.Build.0 = Debug|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Release|Any CPU.ActiveCfg = Release|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Release|Any CPU.Build.0 = Release|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Release|x64.ActiveCfg = Release|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Release|x64.Build.0 = Release|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Release|x86.ActiveCfg = Release|Any CPU {10C03A51-881C-4779-9B24-5BFCE234C175}.Release|x86.Build.0 = Release|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Debug|Any CPU.Build.0 = Debug|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Debug|x64.ActiveCfg = Debug|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Debug|x64.Build.0 = Debug|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Debug|x86.ActiveCfg = Debug|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Debug|x86.Build.0 = Debug|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Release|Any CPU.ActiveCfg = Release|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Release|Any CPU.Build.0 = Release|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Release|x64.ActiveCfg = Release|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Release|x64.Build.0 = Release|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Release|x86.ActiveCfg = Release|Any CPU {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2}.Release|x86.Build.0 = Release|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Debug|Any CPU.Build.0 = Debug|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Debug|x64.ActiveCfg = Debug|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Debug|x64.Build.0 = Debug|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Debug|x86.ActiveCfg = Debug|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Debug|x86.Build.0 = Debug|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Release|Any CPU.ActiveCfg = Release|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Release|Any CPU.Build.0 = Release|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Release|x64.ActiveCfg = Release|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Release|x64.Build.0 = Release|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Release|x86.ActiveCfg = Release|Any CPU {B5E2EC5D-4D8A-4FBE-9434-23B422644B68}.Release|x86.Build.0 = Release|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Debug|Any CPU.Build.0 = Debug|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Debug|x64.ActiveCfg = Debug|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Debug|x64.Build.0 = Debug|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Debug|x86.ActiveCfg = Debug|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Debug|x86.Build.0 = Debug|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Release|Any CPU.ActiveCfg = Release|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Release|Any CPU.Build.0 = Release|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Release|x64.ActiveCfg = Release|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Release|x64.Build.0 = Release|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Release|x86.ActiveCfg = Release|Any CPU {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7}.Release|x86.Build.0 = Release|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Debug|x64.ActiveCfg = Debug|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Debug|x64.Build.0 = Debug|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Debug|x86.ActiveCfg = Debug|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Debug|x86.Build.0 = Debug|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Release|Any CPU.Build.0 = Release|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Release|x64.ActiveCfg = Release|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Release|x64.Build.0 = Release|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Release|x86.ActiveCfg = Release|Any CPU {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD}.Release|x86.Build.0 = Release|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Debug|x64.ActiveCfg = Debug|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Debug|x64.Build.0 = Debug|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Debug|x86.ActiveCfg = Debug|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Debug|x86.Build.0 = Debug|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Release|Any CPU.Build.0 = Release|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Release|x64.ActiveCfg = Release|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Release|x64.Build.0 = Release|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Release|x86.ActiveCfg = Release|Any CPU {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B}.Release|x86.Build.0 = Release|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Debug|Any CPU.Build.0 = Debug|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Debug|x64.ActiveCfg = Debug|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Debug|x64.Build.0 = Debug|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Debug|x86.ActiveCfg = Debug|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Debug|x86.Build.0 = Debug|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Release|Any CPU.ActiveCfg = Release|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Release|Any CPU.Build.0 = Release|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Release|x64.ActiveCfg = Release|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Release|x64.Build.0 = Release|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Release|x86.ActiveCfg = Release|Any CPU {7A5BE15C-4B89-4397-920F-A15FB8A76FA5}.Release|x86.Build.0 = Release|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Debug|Any CPU.Build.0 = Debug|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Debug|x64.ActiveCfg = Debug|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Debug|x64.Build.0 = Debug|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Debug|x86.ActiveCfg = Debug|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Debug|x86.Build.0 = Debug|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Release|Any CPU.ActiveCfg = Release|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Release|Any CPU.Build.0 = Release|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Release|x64.ActiveCfg = Release|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Release|x64.Build.0 = Release|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Release|x86.ActiveCfg = Release|Any CPU {629C519A-14DD-4F1A-B235-AC73AC2622F7}.Release|x86.Build.0 = Release|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Debug|Any CPU.Build.0 = Debug|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Debug|x64.ActiveCfg = Debug|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Debug|x64.Build.0 = Debug|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Debug|x86.ActiveCfg = Debug|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Debug|x86.Build.0 = Debug|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Release|Any CPU.ActiveCfg = Release|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Release|Any CPU.Build.0 = Release|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Release|x64.ActiveCfg = Release|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Release|x64.Build.0 = Release|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Release|x86.ActiveCfg = Release|Any CPU {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94}.Release|x86.Build.0 = Release|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Debug|Any CPU.Build.0 = Debug|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Debug|x64.ActiveCfg = Debug|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Debug|x64.Build.0 = Debug|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Debug|x86.ActiveCfg = Debug|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Debug|x86.Build.0 = Debug|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Release|Any CPU.ActiveCfg = Release|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Release|Any CPU.Build.0 = Release|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Release|x64.ActiveCfg = Release|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Release|x64.Build.0 = Release|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Release|x86.ActiveCfg = Release|Any CPU {1C7E75D5-F462-43C7-A230-4E31FAF8CC00}.Release|x86.Build.0 = Release|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Debug|x64.ActiveCfg = Debug|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Debug|x64.Build.0 = Debug|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Debug|x86.ActiveCfg = Debug|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Debug|x86.Build.0 = Debug|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Release|Any CPU.ActiveCfg = Release|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Release|Any CPU.Build.0 = Release|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Release|x64.ActiveCfg = Release|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Release|x64.Build.0 = Release|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Release|x86.ActiveCfg = Release|Any CPU {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF}.Release|x86.Build.0 = Release|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Debug|Any CPU.Build.0 = Debug|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Debug|x64.ActiveCfg = Debug|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Debug|x64.Build.0 = Debug|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Debug|x86.ActiveCfg = Debug|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Debug|x86.Build.0 = Debug|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Release|Any CPU.ActiveCfg = Release|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Release|Any CPU.Build.0 = Release|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Release|x64.ActiveCfg = Release|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Release|x64.Build.0 = Release|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Release|x86.ActiveCfg = Release|Any CPU {D71B7FBA-E998-4141-81E6-E319C3941659}.Release|x86.Build.0 = Release|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Debug|Any CPU.Build.0 = Debug|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Debug|x64.ActiveCfg = Debug|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Debug|x64.Build.0 = Debug|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Debug|x86.ActiveCfg = Debug|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Debug|x86.Build.0 = Debug|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Release|Any CPU.ActiveCfg = Release|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Release|Any CPU.Build.0 = Release|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Release|x64.ActiveCfg = Release|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Release|x64.Build.0 = Release|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Release|x86.ActiveCfg = Release|Any CPU {3AFDA053-190A-4BBF-BF0D-626718239FA4}.Release|x86.Build.0 = Release|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Debug|Any CPU.Build.0 = Debug|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Debug|x64.ActiveCfg = Debug|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Debug|x64.Build.0 = Debug|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Debug|x86.ActiveCfg = Debug|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Debug|x86.Build.0 = Debug|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Release|Any CPU.ActiveCfg = Release|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Release|Any CPU.Build.0 = Release|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Release|x64.ActiveCfg = Release|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Release|x64.Build.0 = Release|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Release|x86.ActiveCfg = Release|Any CPU {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F}.Release|x86.Build.0 = Release|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Debug|x64.ActiveCfg = Debug|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Debug|x64.Build.0 = Debug|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Debug|x86.ActiveCfg = Debug|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Debug|x86.Build.0 = Debug|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Release|Any CPU.Build.0 = Release|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Release|x64.ActiveCfg = Release|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Release|x64.Build.0 = Release|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Release|x86.ActiveCfg = Release|Any CPU {E840877E-2C05-4BF1-859A-3C6D49DFEFE6}.Release|x86.Build.0 = Release|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Debug|Any CPU.Build.0 = Debug|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Debug|x64.ActiveCfg = Debug|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Debug|x64.Build.0 = Debug|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Debug|x86.ActiveCfg = Debug|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Debug|x86.Build.0 = Debug|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Release|Any CPU.ActiveCfg = Release|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Release|Any CPU.Build.0 = Release|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Release|x64.ActiveCfg = Release|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Release|x64.Build.0 = Release|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Release|x86.ActiveCfg = Release|Any CPU {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91}.Release|x86.Build.0 = Release|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Debug|Any CPU.Build.0 = Debug|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Debug|x64.ActiveCfg = Debug|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Debug|x64.Build.0 = Debug|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Debug|x86.ActiveCfg = Debug|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Debug|x86.Build.0 = Debug|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Release|Any CPU.ActiveCfg = Release|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Release|Any CPU.Build.0 = Release|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Release|x64.ActiveCfg = Release|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Release|x64.Build.0 = Release|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Release|x86.ActiveCfg = Release|Any CPU {5D62EA19-7E50-467A-B0BC-76334C2C69E9}.Release|x86.Build.0 = Release|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Debug|Any CPU.Build.0 = Debug|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Debug|x64.ActiveCfg = Debug|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Debug|x64.Build.0 = Debug|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Debug|x86.ActiveCfg = Debug|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Debug|x86.Build.0 = Debug|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Release|Any CPU.ActiveCfg = Release|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Release|Any CPU.Build.0 = Release|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Release|x64.ActiveCfg = Release|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Release|x64.Build.0 = Release|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Release|x86.ActiveCfg = Release|Any CPU {3CD46A0D-61E6-4A0C-AF2D-176462DCF601}.Release|x86.Build.0 = Release|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Debug|Any CPU.Build.0 = Debug|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Debug|x64.ActiveCfg = Debug|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Debug|x64.Build.0 = Debug|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Debug|x86.ActiveCfg = Debug|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Debug|x86.Build.0 = Debug|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Release|Any CPU.ActiveCfg = Release|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Release|Any CPU.Build.0 = Release|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Release|x64.ActiveCfg = Release|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Release|x64.Build.0 = Release|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Release|x86.ActiveCfg = Release|Any CPU {EF146053-4951-4D97-9AAA-E0C1CA4801D6}.Release|x86.Build.0 = Release|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Debug|Any CPU.Build.0 = Debug|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Debug|x64.ActiveCfg = Debug|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Debug|x64.Build.0 = Debug|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Debug|x86.ActiveCfg = Debug|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Debug|x86.Build.0 = Debug|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Release|Any CPU.ActiveCfg = Release|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Release|Any CPU.Build.0 = Release|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Release|x64.ActiveCfg = Release|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Release|x64.Build.0 = Release|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Release|x86.ActiveCfg = Release|Any CPU {0FCE1B76-0720-4AD0-B353-F604C93DC05F}.Release|x86.Build.0 = Release|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Debug|Any CPU.Build.0 = Debug|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Debug|x64.ActiveCfg = Debug|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Debug|x64.Build.0 = Debug|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Debug|x86.ActiveCfg = Debug|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Debug|x86.Build.0 = Debug|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Release|Any CPU.ActiveCfg = Release|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Release|Any CPU.Build.0 = Release|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Release|x64.ActiveCfg = Release|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Release|x64.Build.0 = Release|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Release|x86.ActiveCfg = Release|Any CPU {D6E5E010-D782-4B02-94A1-1162852916D9}.Release|x86.Build.0 = Release|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Debug|Any CPU.Build.0 = Debug|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Debug|x64.ActiveCfg = Debug|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Debug|x64.Build.0 = Debug|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Debug|x86.ActiveCfg = Debug|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Debug|x86.Build.0 = Debug|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Release|Any CPU.ActiveCfg = Release|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Release|Any CPU.Build.0 = Release|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Release|x64.ActiveCfg = Release|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Release|x64.Build.0 = Release|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Release|x86.ActiveCfg = Release|Any CPU {543B7B29-B10C-4837-9479-949F7066DAAC}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {10C03A51-881C-4779-9B24-5BFCE234C175} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {5FE016D8-4FBC-4D85-A7D8-165E6F7887F2} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {B5E2EC5D-4D8A-4FBE-9434-23B422644B68} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {AC823FF0-0EEA-46D8-B6FF-BA9E255F5EB7} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {17E54BAB-2FF4-42A1-ACBA-0F88066FF4FD} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {D27E21C1-96C8-4EFF-AA4D-43A8ED7CC40B} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {7A5BE15C-4B89-4397-920F-A15FB8A76FA5} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {629C519A-14DD-4F1A-B235-AC73AC2622F7} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {E0E26A07-B7A6-41FD-AB74-1CFCB5191F94} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {1C7E75D5-F462-43C7-A230-4E31FAF8CC00} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {6FA9C7E5-7ED9-4D09-856E-0D30D6D0E7AF} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {D71B7FBA-E998-4141-81E6-E319C3941659} = {9D43F9A2-6C7D-44DC-A0A0-3F0C693B9663} {3AFDA053-190A-4BBF-BF0D-626718239FA4} = {9D43F9A2-6C7D-44DC-A0A0-3F0C693B9663} {3EB8E5B8-B4A1-41EE-8E26-EED6AFF8AC8F} = {9D43F9A2-6C7D-44DC-A0A0-3F0C693B9663} {D67F59C7-8882-4517-AD61-394DA98E94E5} = {9D43F9A2-6C7D-44DC-A0A0-3F0C693B9663} {E840877E-2C05-4BF1-859A-3C6D49DFEFE6} = {D67F59C7-8882-4517-AD61-394DA98E94E5} {5DFA45F0-4E0E-4DF2-85E5-53ACF50CDD91} = {D67F59C7-8882-4517-AD61-394DA98E94E5} {5D62EA19-7E50-467A-B0BC-76334C2C69E9} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {3CD46A0D-61E6-4A0C-AF2D-176462DCF601} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {89AE722E-588C-43F2-B4CB-A05CE184F721} = {9D43F9A2-6C7D-44DC-A0A0-3F0C693B9663} {EF146053-4951-4D97-9AAA-E0C1CA4801D6} = {89AE722E-588C-43F2-B4CB-A05CE184F721} {0FCE1B76-0720-4AD0-B353-F604C93DC05F} = {89AE722E-588C-43F2-B4CB-A05CE184F721} {D6E5E010-D782-4B02-94A1-1162852916D9} = {28E1F8EC-E22A-45D3-941F-2A0756D6331D} {543B7B29-B10C-4837-9479-949F7066DAAC} = {89AE722E-588C-43F2-B4CB-A05CE184F721} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F860D614-C29A-4EBF-954C-8CB27921AB49} EndGlobalSection EndGlobal ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2016 personball Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Nupkg/pack.bat ================================================ dotnet pack ..\src\Abplus\Abplus.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.AspNetCore.SignalR\Abplus.AspNetCore.SignalR.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.MqMessages\Abplus.MqMessages.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.MqMessages.AuditingConsumerHandler\Abplus.MqMessages.AuditingConsumerHandler.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.MqMessages.AuditingStore\Abplus.MqMessages.AuditingStore.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.MqMessages.IndexToES\Abplus.MqMessages.IndexToES.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.MqMessages.RebusCore\Abplus.MqMessages.RebusCore.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.MqMessages.RebusRabbitMqConsumer\Abplus.MqMessages.RebusRabbitMqConsumer.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.MqMessages.RebusRabbitMqPublisher\Abplus.MqMessages.RebusRabbitMqPublisher.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.MqMessages.RedisStoreMessageTracker\Abplus.MqMessages.RedisStoreMessageTracker.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.T4.PermissionsFromJson\Abplus.T4.PermissionsFromJson.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.IO.AzureBlobStorage\Abplus.IO.AzureBlobStorage.csproj -o ..\..\nupkg\ dotnet pack ..\src\Abplus.IO.AliyunOSSStorage\Abplus.IO.AliyunOSSStorage.csproj -o ..\..\nupkg\ ================================================ FILE: Nupkg/push-all-packages-in-current_folder.bat ================================================ @echo off setlocal enabledelayedexpansion set filepath=%cd% FOR /R %filepath% %%i IN (*.nupkg) DO ( set file=%%i call ./nugetpush.bat !file! ) pause exit ================================================ FILE: README.md ================================================ ![abplus_icon](https://github.com/personball/abplus/blob/master/abplus_icon.png?raw=true) # abplus Abp plus, an extension for Abp Framework. *From 2.0.0, all components upgrade to netstandard2.0.* 注明 (deprecated)的将不再支持,将针对ef core, aspnet core, signalr core提供扩展。 ## Packages |Package|Status| |:------|:-----| |Abplus|[![NuGet version](https://badge.fury.io/nu/Abplus.svg)](https://badge.fury.io/nu/Abplus)| |Abplus.MqMessages|[![NuGet version](https://badge.fury.io/nu/Abplus.MqMessages.svg)](https://badge.fury.io/nu/Abplus.MqMessages)| |Abplus.MqMessages.AuditingStore|[![NuGet version](https://badge.fury.io/nu/Abplus.MqMessages.AuditingStore.svg)](https://badge.fury.io/nu/Abplus.MqMessages.AuditingStore)| |Abplus.MqMessages.AuditingConsumerHandler|[![NuGet version](https://badge.fury.io/nu/Abplus.MqMessages.AuditingConsumerHandler.svg)](https://badge.fury.io/nu/Abplus.MqMessages.AuditingConsumerHandler)| |Abplus.MqMessages.RebusCore|[![NuGet version](https://badge.fury.io/nu/Abplus.MqMessages.RebusCore.svg)](https://badge.fury.io/nu/Abplus.MqMessages.RebusCore)| |Abplus.MqMessages.RebusRabbitMqConsumer|[![NuGet version](https://badge.fury.io/nu/Abplus.MqMessages.RebusRabbitMqConsumer.svg)](https://badge.fury.io/nu/Abplus.MqMessages.RebusRabbitMqConsumer)| |Abplus.MqMessages.RebusRabbitMqPublisher|[![NuGet version](https://badge.fury.io/nu/Abplus.MqMessages.RebusRabbitMqPublisher.svg)](https://badge.fury.io/nu/Abplus.MqMessages.RebusRabbitMqPublisher)| |Abplus.MqMessages.RedisStoreMessageTracker|[![NuGet version](https://badge.fury.io/nu/Abplus.MqMessages.RedisStoreMessageTracker.svg)](https://badge.fury.io/nu/Abplus.MqMessages.RedisStoreMessageTracker)| |Abplus.T4.PermissionsFromJson|[![NuGet version](https://badge.fury.io/nu/Abplus.T4.PermissionsFromJson.svg)](https://badge.fury.io/nu/Abplus.T4.PermissionsFromJson)| |Abplus.MqMessages.IndexToES|[![NuGet version](https://badge.fury.io/nu/Abplus.MqMessages.IndexToES.svg)](https://badge.fury.io/nu/Abplus.MqMessages.IndexToES)| |Abplus.AspNetCore.SignalR|[![NuGet version](https://badge.fury.io/nu/Abplus.AspNetCore.SignalR.svg)](https://badge.fury.io/nu/Abplus.AspNetCore.SignalR)| |Abplus.EntityFramework (**deprecated**)|[![NuGet version](https://badge.fury.io/nu/Abplus.EntityFramework.svg)](https://badge.fury.io/nu/Abplus.EntityFramework)| |Abplus.Web.Api (**deprecated**)|[![NuGet version](https://badge.fury.io/nu/Abplus.Web.Api.svg)](https://badge.fury.io/nu/Abplus.Web.Api)| |Abplus.Web.SignalR (**deprecated**)|[![NuGet version](https://badge.fury.io/nu/Abplus.Web.SignalR.svg)](https://badge.fury.io/nu/Abplus.Web.SignalR)| ## Remarks |Package|Remark| |:------|:-----| |Abplus|基础概念扩展及接口定义| |Abplus.MqMessages|集成消息队列的扩展方案| |Abplus.MqMessages.AuditingStore|集成消息队列的扩展方案,审计日志发送消息队列,使用方法参考 src/Samples/AuditingConsumer| |Abplus.MqMessages.AuditingConsumerHandler|集成消息队列的扩展方案,审计日志队列消费端,使用方法参考 src/Samples/AuditingConsumer| |Abplus.MqMessages.RebusCore|集成消息队列的扩展方案,Rebus Publisher的实现| |Abplus.MqMessages.RebusRabbitMqConsumer|集成消息队列的扩展方案,消费端模块(具备发布消息能力),使用方法参考src/Samples/Sample.DotNetCoreConsumerHost或Sample.DotNetFxConsumerHost| |Abplus.MqMessages.RebusRabbitMqPublisher|集成消息队列的扩展方案,生产端模块,使用方法参考Samples/Sample.DotNetCorePublisherHost或Sample.DotNetFxPublisherHost| |Abplus.MqMessages.RedisStoreMessageTracker|集成消息队列的扩展方案,消费端消费行为的幂等支持| |Abplus.T4.PermissionsFromJson|提供T4工具,自动从Json文件定义中生成权限定义和权限树| |Abplus.MqMessages.IndexToES|提供一个泛型版RebusHandler及T4工具,自动替在MqMessagesT4Register注册的MqMessages通过T4生成代码,将消息索引到ElasticSearch。| |Abplus.AspNetCore.SignalR|基于Redis的OnlineClientManager,解决Abp自带的[OnlineClientManager](https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp/RealTime/OnlineClientManager.cs#L26)在线状态不跨进程共享的问题。| |Abplus.EntityFramework(**deprecated**)|EF辅助方法:预热,自动注册FluentApi配置类| |Abplus.Web.Api(**deprecated**)|WebApi基于请求头的版本化机制,使用方法见Samples/Abplus.WebApiVersionRoute.Sample。| |Abplus.Web.SignalR(**deprecated**)|基于Redis的OnlineClientManager,解决Abp自带的[OnlineClientManager](https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp/RealTime/OnlineClientManager.cs#L26)在线状态不跨进程共享的问题。| ## License [MIT](LICENSE) ================================================ FILE: common.props ================================================ 6.0.0 ================================================ FILE: src/Abplus/Abplus.csproj ================================================  net5.0 Abp Abplus ================================================ FILE: src/Abplus/Abplus.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2019 ================================================ FILE: src/Abplus/Application/Navigation/MenuItemDefinitionPlugInExtensions.cs ================================================ using System.Linq; using Abp.Extensions; using Abp.Localization; namespace Abp.Application.Navigation { public static class MenuItemDefinitionPlugInExtensions { public static MenuItemDefinition GetOrCreatePlugInsRootMenu(this MenuDefinition menu, string url, string icon, string plugInMenuName = "PlugIns", string fixedDisplayName = null, string requiredPermission = null) { if (plugInMenuName.IsNullOrWhiteSpace()) { plugInMenuName = "PlugIns"; } if (fixedDisplayName.IsNullOrWhiteSpace()) { fixedDisplayName = "PlugIns"; } var plugInRoot = menu.Items.FirstOrDefault(i => i.Name == plugInMenuName); if (plugInRoot == null) { plugInRoot = new MenuItemDefinition( plugInMenuName, new FixedLocalizableString(fixedDisplayName), url: url, icon: icon //permissionDependency: //requiredPermissionName: requiredPermission ); menu.AddItem(plugInRoot); } return plugInRoot; } } } ================================================ FILE: src/Abplus/Application/Services/Dto/IHasDateTimeFilterRequest.cs ================================================ namespace Abp.Application.Services.Dto { using System; public interface IHasDateTimeFilterRequest { DateTime? StartTime { get; set; } DateTime? EndTime { get; set; } } } ================================================ FILE: src/Abplus/Application/Services/Dto/IHasKeywordFilterRequest.cs ================================================ namespace Abp.Application.Services.Dto { public interface IHasKeywordFilterRequest { string Keyword { get; set; } } } ================================================ FILE: src/Abplus/Application/Services/Dto/IPaginationResultRequest.cs ================================================ namespace Abp.Application.Services.Dto { public interface IPaginationResultRequest : ISortedResultRequest { int PageIndex { get; set; } int PageSize { get; set; } } } ================================================ FILE: src/Abplus/Application/Services/Dto/PaginationRequestInput.cs ================================================ namespace Abp.Application.Services.Dto { using System.ComponentModel.DataAnnotations; public class PaginationResultRequestInput : IPaginationResultRequest { public PaginationResultRequestInput() { PageIndex = 1; PageSize = 10; } [Range(1, 1000)] public int PageIndex { get; set; } [Range(1, 1000)] public int PageSize { get; set; } public string Sorting { get; set; } } } ================================================ FILE: src/Abplus/Currencies/ChineseCentExtension.cs ================================================ namespace Abp.Currencies { public static class ChineseCentExtension { public static decimal ToYuan(this int moneyInCent) { return moneyInCent / 100m; } public static string ToYuanString(this int moneyInCent) { return $"{moneyInCent.ToYuan().ToString("0.00")}元"; } } } ================================================ FILE: src/Abplus/Events/Bus/ChangedEventData.cs ================================================ namespace Abp.Events.Bus { public abstract class ChangedEventData : EventData { public T Origin { get; set; } public T Current { get; set; } } } ================================================ FILE: src/Abplus/Extensions/DateTimeExtensions.cs ================================================ namespace Abp.Extensions { using System; /// /// Extension methods for . /// public static class DateTimeExtensions { /// /// 转换为完整时间的字符串(yyyy-MM-dd HH:mm:ss) /// public static string ToFullTimeString(this DateTime source) { return source.ToString("yyyy-MM-dd HH:mm:ss"); } /// /// 转换为短时间的字符串(yyyy-MM-dd HH:mm) /// public static string ToShortTimeString(this DateTime source) { return source.ToString("yyyy-MM-dd HH:mm"); } /// /// 转换为只有日期的字符串(yyyy-MM-dd) /// public static string ToDateString(this DateTime source) { return source.ToString("yyyy-MM-dd"); } } } ================================================ FILE: src/Abplus/Extensions/EnumExtensions.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Abp.Extensions { public static class EnumExtensions { public static string GetDisplayName(FieldInfo field) { DisplayAttribute display = field.GetCustomAttribute(inherit: false); if (display != null) { string name = display.GetName(); if (!String.IsNullOrEmpty(name)) { return name; } } return field.Name; } } } ================================================ FILE: src/Abplus/Extensions/GuidExtensions.cs ================================================ namespace Abp.Extensions { using System; public static class GuidExtensions { /// /// 将Guid转换为经过Base64编码的22位字符串 /// public static string ToShortString(this Guid source) { string base64 = Convert.ToBase64String(source.ToByteArray()); string result = base64.Replace("/", "_").Replace("+", "-").Substring(0, 22); return result; } /// /// 转换成sqlserver有序Guid,时间相关,精度为300分之一毫秒 /// /// /// public static Guid ToCombGuid(this Guid source) { byte[] guidArray = source.ToByteArray(); DateTime baseDate = new DateTime(1900, 1, 1); DateTime now = DateTime.Now; // Get the days and milliseconds which will be used to build the byte string TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks); TimeSpan msecs = new TimeSpan(now.Ticks - (new DateTime(now.Year, now.Month, now.Day).Ticks)); // Convert to a byte array // Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 byte[] daysArray = BitConverter.GetBytes(days.Days); byte[] msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds / 3.333333)); // Reverse the bytes to match SQL Servers ordering Array.Reverse(daysArray); Array.Reverse(msecsArray); // Copy the bytes into the guid Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2); Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4); return new Guid(guidArray); } } } ================================================ FILE: src/Abplus/Extensions/IntExtension.cs ================================================ using System; using Abp.Application.Services.Dto; namespace Abp.Extensions { public static class IntExtension { public static int ToSkipCount(this IPaginationResultRequest pagination) { CheckErrors(pagination); return (pagination.PageIndex - 1) * pagination.PageSize; } public static int ToMaxResultCount(this IPaginationResultRequest pagination) { CheckErrors(pagination); return pagination.PageSize; } private static void CheckErrors(IPaginationResultRequest pagination) { if (pagination == null) { throw new ArgumentNullException("pagination"); } if (pagination.PageSize < 1) { throw new ArgumentOutOfRangeException("pagesize"); } if (pagination.PageIndex < 1) { throw new ArgumentOutOfRangeException("pageindex"); } } } } ================================================ FILE: src/Abplus/Extensions/NullableDateTimeExtensions.cs ================================================ namespace Abp.Extensions { using System; public static class NullableDateTimeExtensions { /// /// 转换为完整时间的字符串(yyyy-MM-dd HH:mm:ss) /// public static string ToFullString(this DateTime? source) { return source.HasValue ? source.Value.ToFullTimeString() : string.Empty; } /// /// 转换为短时间的字符串(yyyy-MM-dd HH:mm) /// public static string ToShortString(this DateTime? source) { return source.HasValue ? source.Value.ToShortTimeString() : string.Empty; } /// /// 转换为只有日期的字符串(yyyy-MM-dd) /// public static string ToDateString(this DateTime? source) { return source.HasValue ? source.Value.ToDateString() : string.Empty; } } } ================================================ FILE: src/Abplus/Extensions/StringExtensions.cs ================================================ namespace Abp.Extensions { using System; using Newtonsoft.Json; public static class StringExtensions { /// /// 字符串转换为Guid类型 /// /// /// 默认返回Guid.Empty public static Guid ToGuid(this string str) { return str.ToGuid(null); } /// /// 指定格式字符串转换为Guid类型 /// /// /// /// 默认返回Guid.Empty public static Guid ToGuid(this string str, string format) { var result = Guid.Empty; if (!format.IsNullOrWhiteSpace()) { Guid.TryParseExact(str, format, out result); } else { Guid.TryParse(str, out result); } return result; } /// /// 字符串转换为Guid类型或者null,不成功返回null /// public static Guid? ToGuidOrNull(this string str) { Guid? result = null; if (!string.IsNullOrWhiteSpace(str)) { Guid tmp; if (Guid.TryParse(str, out tmp)) { result = tmp; } } return result; } /// /// 字符串转换为int类型或者null,不成功返回null /// public static int? ToIntOrNull(this string str) { int? result = null; if (!string.IsNullOrWhiteSpace(str)) { int tmp; if (int.TryParse(str, out tmp)) { result = tmp; } } return result; } /// /// 将经过Base64编码的22位字符串还原为Guid /// public static Guid Base64ToGuid(this string str) { Guid result = Guid.Empty; str = str.Trim(); string encoded = string.Concat(str.Trim().Replace("-", "+").Replace("_", "/"), "=="); try { byte[] base64 = Convert.FromBase64String(encoded); result = new Guid(base64); } catch (Exception ex) { throw new AbpException("不是有效的参数格式", ex); } return result; } /// /// 由json字符串反序列化成指定类型的对象,字符串为空或不符合格式,则返回类型的默认值 /// public static T ToObject(this string json) { var obj = default(T); if (json.IsNullOrWhiteSpace()) { return obj; } try { obj = JsonConvert.DeserializeObject(json); } catch { //eat exception to return default value } return obj; } } } ================================================ FILE: src/Abplus/IO/IFileStorage.cs ================================================ using System.IO; using System.Threading.Tasks; using Abp.Dependency; namespace Abp.IO { public interface IFileStorage : ITransientDependency { Task Save(Stream source, string fileName, string subPath = null); Task Save(byte[] source, string fileName, string subPath = null); Task Delete(string fileName, string subPath = null); Task ReadAsBytes(string fileName, string subPath = null); } } ================================================ FILE: src/Abplus/IO/NullFileStorage.cs ================================================ using System.IO; using System.Threading.Tasks; namespace Abp.IO { public class NullFileStorage : IFileStorage { public static NullFileStorage Instance { get; } = new NullFileStorage(); public Task Delete(string fileName, string subPath = null) { return Task.FromResult(0); } public Task ReadAsBytes(string fileName, string subPath = null) { return Task.FromResult(new byte[0]); } public Task Save(Stream source, string fileName, string subPath = null) { return Task.FromResult(""); } public Task Save(byte[] source, string fileName, string subPath = null) { return Task.FromResult(""); } } } ================================================ FILE: src/Abplus/Interceptors/AsyncHandlingInterceptor.cs ================================================ using System.Reflection; using System.Threading.Tasks; using Castle.DynamicProxy; namespace Abp.Interceptors { public abstract class AsyncHandlingInterceptor : IInterceptor { protected readonly IAsyncInterceptorHandler Handler; private static readonly MethodInfo HandleAsyncMethodInfo = typeof(AsyncHandlingInterceptor).GetMethod("HandleAsyncWithResult", BindingFlags.Instance | BindingFlags.NonPublic); /// /// /// /// protected AsyncHandlingInterceptor(IAsyncInterceptorHandler handler) { Handler = handler; } public void Intercept(IInvocation invocation) { var delegateType = GetDelegateType(invocation); if (delegateType == MethodType.Synchronous) { Handler.Handle(invocation); //Handle(() => invocation.Proceed()); } if (delegateType == MethodType.AsyncAction) { Handler.HandleAsync(invocation); //invocation.Proceed(); //invocation.ReturnValue = HandleAsync((Task)invocation.ReturnValue); } if (delegateType == MethodType.AsyncFunction) { //invocation.Proceed(); ExecuteHandleAsyncWithResultUsingReflection(invocation); } } private void ExecuteHandleAsyncWithResultUsingReflection(IInvocation invocation) { var resultType = invocation.Method.ReturnType.GetGenericArguments()[0]; var mi = HandleAsyncMethodInfo.MakeGenericMethod(resultType); invocation.ReturnValue = mi.Invoke(this, new[] { invocation }); } /// /// Used by Reflection /// /// /// /// protected virtual async Task HandleAsyncWithResult(IInvocation invocation) { return await Handler.HandleAsync(invocation); } private MethodType GetDelegateType(IInvocation invocation) { var returnType = invocation.Method.ReturnType; if (returnType == typeof(Task)) return MethodType.AsyncAction; if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>)) return MethodType.AsyncFunction; return MethodType.Synchronous; } private enum MethodType { Synchronous, AsyncAction, AsyncFunction } } } ================================================ FILE: src/Abplus/Interceptors/IAsyncInterceptorHandler.cs ================================================ using System.Threading.Tasks; using Castle.DynamicProxy; namespace Abp.Interceptors { /// /// /// public interface IAsyncInterceptorHandler { /// /// /// /// void Handle(IInvocation invocation); /// /// /// /// /// Task HandleAsync(IInvocation invocation); /// /// /// /// /// /// Task HandleAsync(IInvocation invocation); } } ================================================ FILE: src/Abplus/Json/LargeNumJsonConverter.cs ================================================ using System; using System.Collections.Generic; using Newtonsoft.Json; namespace Abp.Json { /// /// csharp long type number maybe overflow when it assigned to javascript in a json object, so serialize it as string when its value overflow. /// public class LargeNumJsonConverter : JsonConverter { public override bool CanRead => false; public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var num = value as long?; if (num.HasValue && (num > _maxJsNum || num < _minJsNum)) { writer.WriteValue(num.ToString()); } else { writer.WriteValue(value); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (LargeNumTypes.Contains(objectType)) { long result; if (reader.Value != null && long.TryParse(reader.Value.ToString(), out result)) { return result; } return (long?)null; } return reader.Value; } public override bool CanConvert(Type objectType) { //9007199254740992 return LargeNumTypes.Contains(objectType); } private static long _maxJsNum = 9007199254740992; private static long _minJsNum = -9007199254740992; private static readonly List LargeNumTypes = new List { typeof(long), typeof(long?) }; } } ================================================ FILE: src/Abplus/MqMessages/IMqMessagePublisher.cs ================================================ using System.Threading.Tasks; using Abp.Dependency; namespace Abp.MqMessages { /// /// 消息发布接口 /// public interface IMqMessagePublisher : ITransientDependency { /// /// 发布 /// /// void Publish(object mqMessages); /// /// 发布 /// /// /// Task PublishAsync(object mqMessages); } } ================================================ FILE: src/Abplus/MqMessages/MessageTrackers/DefaultInMemoryMessageTracker.cs ================================================ using System.Collections.Concurrent; using System.Linq; using System.Threading.Tasks; namespace Abp.MqMessages.MessageTrackers { public class DefaultInMemoryMessageTracker : IMessageTracker { private static readonly ConcurrentBag InMemoryStore; static DefaultInMemoryMessageTracker() { InMemoryStore = new ConcurrentBag(); } public static DefaultInMemoryMessageTracker Instance { get; } = new DefaultInMemoryMessageTracker(); public Task MarkAsProcessed(string processId) { InMemoryStore.Add(processId); return Task.FromResult(0); } public Task HasProcessed(string processId) { return Task.FromResult(InMemoryStore.Contains(processId)); } } } ================================================ FILE: src/Abplus/MqMessages/MessageTrackers/IMessageTracker.cs ================================================ using System.Threading.Tasks; namespace Abp.MqMessages.MessageTrackers { public interface IMessageTracker { /// /// 查询是否已处理过 /// /// 能唯一标记本次处理过程的Id,可采用msgId+HandlerName等组合 /// Task HasProcessed(string processId); /// /// 标记为已处理过 /// /// 能唯一标记本次处理过程的Id,可采用msgId+HandlerName等组合 /// Task MarkAsProcessed(string processId); } } ================================================ FILE: src/Abplus/MqMessages/NullMqMessagePublisher.cs ================================================ using System.Threading.Tasks; namespace Abp.MqMessages { /// /// 空模式 /// public class NullMqMessagePublisher : IMqMessagePublisher { /// /// /// public static NullMqMessagePublisher Instance { get; } = new NullMqMessagePublisher(); /// /// /// /// /// public Task PublishAsync(object mqMessages) { //do nothing. return Task.FromResult(0); } /// /// /// /// public void Publish(object mqMessages) { //do nothing. } } } ================================================ FILE: src/Abplus/PlugIns/IPlugInAreaRegistration.cs ================================================ namespace Abp.PlugIns { public interface IPlugInAreaRegistration { } } ================================================ FILE: src/Abplus/PlugIns/IPlugInAuthorizationProvider.cs ================================================ namespace Abp.PlugIns { public interface IPlugInAuthorizationProvider { } } ================================================ FILE: src/Abplus/PlugIns/IPlugInNavigationProvider.cs ================================================ namespace Abp.PlugIns { public interface IPlugInNavigationProvider { } } ================================================ FILE: src/Abplus/QrCode/IQrCodeScannedRealTimeNotifier.cs ================================================ using System.Threading.Tasks; namespace Abp.QrCode { public interface IQrCodeScannedRealTimeNotifier { Task Notify(string scannerIdentifier, string connectionId, object properties = null); } } ================================================ FILE: src/Abplus/Reservations/Events/ReservationCancelledEventData.cs ================================================ namespace Abp.Reservations.Events { /// /// 预定取消事件抽象基类 /// public abstract class ReservationCancelledEventData : ReservationEventDataBase { } } ================================================ FILE: src/Abplus/Reservations/Events/ReservationEventDataBase.cs ================================================ using Abp.Events.Bus; using Abp.TimeRanges; namespace Abp.Reservations.Events { /// /// 预定发生变化的事件基类 /// public abstract class ReservationEventDataBase : EventData { /// /// 预定记录唯一标识 /// public string ReservationCode { get; set; } /// /// 预定主题 /// public string ReservationSubject { get; set; } /// /// 预定时间区间 /// public TimeRange ReservationTimeRange { get; set; } } } ================================================ FILE: src/Abplus/Reservations/Events/ReservationSuccessEventData.cs ================================================ namespace Abp.Reservations.Events { /// /// 预定成功事件抽象基类 /// public abstract class ReservationSuccessEventData : ReservationEventDataBase { } } ================================================ FILE: src/Abplus/Reservations/IReservation.cs ================================================ using System.Collections.Generic; using Abp.TimeRanges; namespace Abp.Reservations { /// /// 预定 /// public interface IReservation { /// /// 预定的主题 /// string ReservationSubject { get; } /// /// 预定的类型 /// string ReservationType { get; } /// /// 预定的唯一编码 /// string ReservationCode { get; } /// /// 预定的时间 /// TimeRange ReservationTime { get; } /// /// 同一预定主体的两个预定应检测是否冲突 /// /// /// bool IsConflict(IReservation reservation); /// /// /// /// /// bool IsConflict(IEnumerable reservations); } } ================================================ FILE: src/Abplus/Reservations/IReservationBody.cs ================================================ using System; using System.Collections.Generic; namespace Abp.Reservations { /// /// 可被预定的资源主体 /// /// public interface IReservationBody where T : IReservation { /// /// 可被预定的资源唯一标识(建议8位数字) /// string ResourceCode { get; } /// /// 资源的预定列表 /// ICollection Reservations { get; } /// /// 预定 /// /// /// /// /// T Reserve(string subject, DateTime from, DateTime to); /// /// 取消预定 /// /// /// T CancelReservation(string reservationCode); } } ================================================ FILE: src/Abplus/Reservations/ReservationBase.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using Abp.Domain.Entities.Auditing; using Abp.TimeRanges; namespace Abp.Reservations { /// /// 预定基类,可被预定的资源拥有一个预定的列表,具体预定的实现可继承本基类 /// public abstract class ReservationBase : CreationAuditedEntity, IReservation { /// /// 默认最小预定时间区间长度(单位:分钟) /// public const int DefaultMinTimeRangeLengthForReservationInMinutes = 3;//预定记录唯一编码受预定时间区间粒度影响 protected ReservationBase() { } public ReservationBase(string reservationSubject, TimeRange reservationTime, string reservationType, string reservationResourceCode) { if (reservationTime.To.Subtract(reservationTime.From).TotalMinutes < MinTimeRangeLengthForReservationInMinutes) { throw new ArgumentException($"预定时间区间应大于{MinTimeRangeLengthForReservationInMinutes}分钟!"); } ReservationType = reservationType; ReservationSubject = reservationSubject; ReservationTime = reservationTime; SetReservationCode(reservationResourceCode); } protected virtual int MinTimeRangeLengthForReservationInMinutes { get { return DefaultMinTimeRangeLengthForReservationInMinutes; } } /// /// 生成预定唯一编码 /// /// protected virtual void SetReservationCode(string resourceCode) { ReservationCode = $"{ReservationType}-{resourceCode}-{ReservationTime.From.ToString("yyyyMMddHHmm")}"; } /// /// 预定类型 /// [MaxLength(10)] public string ReservationType { get; private set; } /// /// 预定唯一编码 /// public string ReservationCode { get; private set; } /// /// 预定主题 /// [MaxLength(256)] public string ReservationSubject { get; private set; } /// /// 所预定的时间区间 /// public TimeRange ReservationTime { get; private set; } /// /// 是否冲突 /// /// /// public virtual bool IsConflict(IReservation reservation) { return ReservationTime.IsIntersect(reservation.ReservationTime); } /// /// 是否冲突 /// /// /// public virtual bool IsConflict(IEnumerable reservations)//ICollection 不支持逆变 { var times = reservations.Select(r => r.ReservationTime).ToList(); return ReservationTime.IsIntersect(times); } } } ================================================ FILE: src/Abplus/Reservations/ReservationBodyBase.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using Abp.Domain.Entities; using Abp.Events.Bus; using Abp.TimeRanges; using Abp.Timing; namespace Abp.Reservations { /// /// 可被预定主体的抽象基类 /// /// /// public abstract class ReservationBodyBase : AggregateRoot, IReservationBody where TReservation : IReservation { /// /// 可被预定主体的唯一标识 /// public string ResourceCode { get; protected set; } /// /// 预定列表 /// public virtual ICollection Reservations { get; protected set; } /// /// 获取预定取消时应触发的事件 /// protected abstract Func GetReservationCancelledEventData { get; } /// /// 检查新增预定是否与已有预定相冲突 /// protected abstract Func, bool> GetIfTheseReservationsConflict { get; } /// /// 获取预定成功时应触发的事件 /// protected abstract Func GetReserveSuccessEventData { get; } /// /// 如果新增预定与已有预定相冲突时,应抛出的具体异常 /// protected abstract Action ThrowIfTheseReservationsConflict { get; } /// /// 取消预定 /// /// /// public virtual TReservation CancelReservation(string reservationCode) { Check.NotNullOrWhiteSpace(reservationCode, nameof(reservationCode)); var reservation = Reservations.FirstOrDefault(r => r.ReservationCode == reservationCode); if (reservation == null) { return reservation; } Reservations.Remove(reservation); DomainEvents.Add(GetReservationCancelledEventData(reservation)); return reservation; } /// /// 预定 /// /// 预定主题 /// 时间区间起 /// 时间区间止 /// public virtual TReservation Reserve(string subject, DateTime from, DateTime to) { Check.NotNullOrWhiteSpace(subject, nameof(subject)); TReservation newReservation = (TReservation)Activator.CreateInstance(typeof(TReservation), subject, new TimeRange(from, to), ResourceCode); var reservations = Reservations.Where(r => r.ReservationTime.To > Clock.Now).ToList(); if (reservations.Any()) { if (GetIfTheseReservationsConflict(newReservation, reservations)) { ThrowIfTheseReservationsConflict(); } } Reservations.Add(newReservation); DomainEvents.Add(GetReserveSuccessEventData(newReservation)); return newReservation; } } } ================================================ FILE: src/Abplus/Runtime/OS/EnvDescription.cs ================================================ namespace Abp.Runtime.OS { public class EnvDescription { public string FrameworkDescription { get; set; } public string OSDescription { get; set; } public string OSArchitecture { get; set; } public string ProcessArchitecture { get; set; } } } ================================================ FILE: src/Abplus/Runtime/OS/EnvironmentHelper.cs ================================================ using System.Runtime.InteropServices; namespace Abp.Runtime.OS { public static class EnvironmentHelper { public static EnvDescription GetRuntimeInformation() { return new EnvDescription { FrameworkDescription = RuntimeInformation.FrameworkDescription, OSArchitecture = RuntimeInformation.OSArchitecture.ToString(), OSDescription = RuntimeInformation.OSDescription, ProcessArchitecture = RuntimeInformation.ProcessArchitecture.ToString() }; } } } ================================================ FILE: src/Abplus/TimeRanges/TimeRange.cs ================================================ using System; using System.Collections.Generic; using Abp.Domain.Values; namespace Abp.TimeRanges { public class TimeRange : ValueObject { protected TimeRange() { } public TimeRange(DateTime from, DateTime to) { Check.NotNull(from, nameof(from)); Check.NotNull(to, nameof(to)); if (from >= to) { throw new ArgumentException("时间区间的起点必须小于终点!"); } From = from; To = to; } /// /// 时间区间起 /// public DateTime From { get; private set; } /// /// 时间区间止 /// public DateTime To { get; private set; } /// /// 包含,一般用于匹配 /// /// /// public bool IsIncluding(TimeRange that) { Check.NotNull(that, nameof(that)); return From <= that.From && To >= that.To; } /// /// 相交,一般用于检测冲突 /// /// /// public bool IsIntersect(TimeRange that) { Check.NotNull(that, nameof(that)); return To >= that.From && To <= that.To || From >= that.From && To <= that.To || From >= that.From && From <= that.To; } /// /// 相交,一般用于检测冲突 /// /// /// public bool IsIntersect(ICollection those) { Check.NotNull(those, nameof(those)); foreach (var that in those) { if (IsIntersect(that)) { return true; } } return false; } protected override IEnumerable GetAtomicValues() { yield return From; yield return To; } } } ================================================ FILE: src/Abplus.AspNetCore.SignalR/Abplus.AspNetCore.SignalR.csproj ================================================  net5.0 Abp Abplus.AspNetCore.SignalR ================================================ FILE: src/Abplus.AspNetCore.SignalR/Abplus.AspNetCore.SignalR.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.AspNetCore.SignalR/Configuration/Startup/RedisOnlineClientManagerConfiguationExtensions.cs ================================================ using Abp.RealTime; namespace Abp.Configuration.Startup { public static class RedisOnlineClientManagerConfiguationExtensions { public static IRedisOnlineClientManagerModuleConfig UseRedisOnlineClientManager(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abplus.RedisOnlineClientManager", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src/Abplus.AspNetCore.SignalR/RealTime/IRedisOnlineClientManagerModuleConfig.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Abp.RealTime { public interface IRedisOnlineClientManagerModuleConfig { /// /// Redis连接字符串 /// string ConnectionString { get; } /// /// 在线状态列表存储的键名 /// string StoreKey { get; } IRedisOnlineClientManagerModuleConfig ConnectTo(string connectionString); IRedisOnlineClientManagerModuleConfig WithStoreKey(string storeKey); } } ================================================ FILE: src/Abplus.AspNetCore.SignalR/RealTime/RedisOnlineClientManager.cs ================================================ using System; using System.Collections.Generic; using System.Collections.Immutable; using Abp.Dependency; using Abp.Extensions; using Abp.Json; using Castle.Core.Logging; using Newtonsoft.Json; using StackExchange.Redis; namespace Abp.RealTime { /// /// 基于Redis的OnlineClientManager /// public class RedisOnlineClientManager : IOnlineClientManager { /// /// Client 连接成功时 /// public event EventHandler ClientConnected; /// /// Client断开连接时 /// public event EventHandler ClientDisconnected; /// /// 用户连接成功时 /// public event EventHandler UserConnected; /// /// 用户断开连接时 /// public event EventHandler UserDisconnected; private readonly string _connectionString; private readonly string _storeKey; private readonly string _clientStoreKey; private readonly string _userStoreKey; private readonly Lazy _connectionMultiplexer; private readonly object _syncObj = new object(); /// /// 日志 /// public ILogger Logger { get; set; } /// /// ctor /// public RedisOnlineClientManager() { var config = IocManager.Instance.Resolve(); if (config == null || config.ConnectionString.IsNullOrWhiteSpace() || config.StoreKey.IsNullOrWhiteSpace()) { throw new Exception("RedisOnlineClientManagerModuleConfig is invalid!"); } _connectionString = config.ConnectionString; _storeKey = config.StoreKey; _clientStoreKey = _storeKey + ".Clients"; _userStoreKey = _storeKey + ".Users"; Logger = NullLogger.Instance; _connectionMultiplexer = new Lazy(CreateConnectionMultiplexer); } private ConnectionMultiplexer CreateConnectionMultiplexer() { return ConnectionMultiplexer.Connect(_connectionString); } /// /// 获取Redis Database /// /// protected IDatabase GetDatabase() { return _connectionMultiplexer.Value.GetDatabase(); } /// /// 添加Client /// /// public void Add(IOnlineClient client) { lock (_syncObj) { var userWasAlreadyOnline = false; var user = client.ToUserIdentifierOrNull(); if (user != null) { userWasAlreadyOnline = IsUserOnline(user); } AddClientToRedisStore(client); ClientConnected.InvokeSafely(this, new OnlineClientEventArgs(client)); if (user != null && !userWasAlreadyOnline) { UserConnected.InvokeSafely(this, new OnlineUserEventArgs(user, client)); } } } private bool IsUserOnline(UserIdentifier user) { var _database = GetDatabase(); return _database.HashExists(_userStoreKey, user.ToUserIdentifierString()); } private void AddClientToRedisStore(IOnlineClient client) { var _database = GetDatabase(); _database.HashSet(_clientStoreKey, new HashEntry[] { new HashEntry(client.ConnectionId, client.ToString()) }); var userId = client.ToUserIdentifierOrNull(); if (userId == null) { return; } var userClients = new List(); var userClientsValue = _database.HashGet(_userStoreKey, userId.ToUserIdentifierString()); if (userClientsValue.HasValue) { userClients = JsonConvert.DeserializeObject>(userClientsValue); } if (userClients.Contains(client.ConnectionId)) { return; } userClients.Add(client.ConnectionId); _database.HashSet(_userStoreKey, new HashEntry[] { new HashEntry(userId.ToUserIdentifierString(), userClients.ToJsonString()) }); } /// /// 获取所有Clients /// /// public IReadOnlyList GetAllClients() { lock (_syncObj) { var _database = GetDatabase(); var clientsEntries = _database.HashGetAll(_clientStoreKey); var clients = new List(); foreach (var entry in clientsEntries) { clients.Add(JsonConvert.DeserializeObject(entry.Value)); } return clients.ToImmutableList(); } } /// /// 根据连接id获取client /// /// /// public IOnlineClient GetByConnectionIdOrNull(string connectionId) { lock (_syncObj) { var _database = GetDatabase(); var clientValue = _database.HashGet(_clientStoreKey, connectionId); if (clientValue.IsNullOrEmpty) { return null; } return JsonConvert.DeserializeObject(clientValue); } } /// /// 移除Client /// /// /// public bool Remove(string connectionId) { lock (_syncObj) { var _database = GetDatabase(); var clientValue = _database.HashGet(_clientStoreKey, connectionId); if (clientValue.IsNullOrEmpty) { return true; } var client = JsonConvert.DeserializeObject(clientValue); var user = client.ToUserIdentifierOrNull(); if (user != null) { //从_userStoreKey中移除一个client var userClientsValue = _database.HashGet(_userStoreKey, user.ToUserIdentifierString()); if (userClientsValue.HasValue) { var userClients = JsonConvert.DeserializeObject>(userClientsValue); userClients.Remove(connectionId); if (userClients.Count > 0) { //更新 _database.HashSet(_userStoreKey, new HashEntry[] { new HashEntry(user.ToUserIdentifierString(), userClients.ToJsonString()) }); } else { //删除 _database.HashDelete(_userStoreKey, user.ToUserIdentifierString()); } } _database.HashDelete(_clientStoreKey, connectionId); if (!IsUserOnline(user)) { UserDisconnected.InvokeSafely(this, new OnlineUserEventArgs(user, client)); } } ClientDisconnected.InvokeSafely(this, new OnlineClientEventArgs(client)); return true; } } /// /// 获取指定user的所有clients /// /// /// public IReadOnlyList GetAllByUserId(IUserIdentifier user) { var clients = new List(); var userIdentifier = new UserIdentifier(user.TenantId, user.UserId); if (!IsUserOnline(userIdentifier)) { return clients; } lock (_syncObj) { var _database = GetDatabase(); var userClients = new List(); var userClientsValue = _database.HashGet(_userStoreKey, userIdentifier.ToUserIdentifierString()); if (userClientsValue.HasValue) { userClients = JsonConvert.DeserializeObject>(userClientsValue); foreach (var connectionId in userClients) { var clientValue = _database.HashGet(_clientStoreKey, connectionId); if (clientValue.IsNullOrEmpty) { continue; } clients.Add(JsonConvert.DeserializeObject(clientValue)); } } } return clients; } } } ================================================ FILE: src/Abplus.AspNetCore.SignalR/RealTime/RedisOnlineClientManagerModule.cs ================================================ using System.Reflection; using Abp.Dependency; using Abp.Modules; namespace Abp.RealTime { public class RedisOnlineClientManagerModule : AbpModule { public override void PreInitialize() { //base.PreInitialize(); IocManager.Register(); IocManager.Register(DependencyLifeStyle.Singleton); } public override void Initialize() { //base.Initialize(); IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } } } ================================================ FILE: src/Abplus.AspNetCore.SignalR/RealTime/RedisOnlineClientManagerModuleConfig.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Abp.RealTime { public class RedisOnlineClientManagerModuleConfig : IRedisOnlineClientManagerModuleConfig { public string ConnectionString { get; private set; } public string StoreKey { get; private set; } public RedisOnlineClientManagerModuleConfig() { ConnectionString = string.Empty; StoreKey = "Abplus.RealTime.OnlineClients"; } public IRedisOnlineClientManagerModuleConfig ConnectTo(string connectionString) { ConnectionString = connectionString; return this; } public IRedisOnlineClientManagerModuleConfig WithStoreKey(string storeKey) { StoreKey = storeKey; return this; } } } ================================================ FILE: src/Abplus.AspNetCore.SignalR/Web/SignalR/QrScan/SignalRQrCodeScannedRealTimeNotifier.cs ================================================ using System; using System.Threading.Tasks; using Abp.AspNetCore.SignalR.Hubs; using Abp.QrCode; using Castle.Core.Logging; using Microsoft.AspNetCore.SignalR; namespace Abp.Web.SignalR.QrScan { public class SignalRQrCodeScannedRealTimeNotifier : IQrCodeScannedRealTimeNotifier { /// /// Reference to the logger. /// public ILogger Logger { get; set; } private readonly IHubContext _commonHub; /// /// Initializes a new instance of the class. /// public SignalRQrCodeScannedRealTimeNotifier(IHubContext commonHub) { Logger = NullLogger.Instance; _commonHub = commonHub; } public Task Notify(string scannerId, string connectionId, object properties = null) { try { var signalRClient = _commonHub.Clients.Client(connectionId); if (signalRClient == null) { throw new Exception($"Can not find the client with connectionId:{connectionId}"); } signalRClient.SendAsync("qrScanned",scannerId, properties); } catch (Exception ex) { Logger.Warn(ex.ToString(), ex); } return Task.FromResult(0); } } } ================================================ FILE: src/Abplus.AspNetCore.SignalR/Web/SignalR/QrScan/SignalRQrCodeScannedRealTimeNotifierModule.cs ================================================ using Abp.Modules; using Abp.QrCode; namespace Abp.Web.SignalR.QrScan { public class SignalRQrCodeScannedRealTimeNotifierModule : AbpModule { public override void PreInitialize() { //base.PreInitialize(); IocManager.Register(); } } } ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/Abplus.IO.AliyunOSSStorage.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/Configuration/Startup/AliyunOSSStorageConfigurationExtensions.cs ================================================ using Abp.IO.AliyunOSSStorage; namespace Abp.Configuration.Startup { public static class AliyunOSSStorageConfigurationExtensions { public static IAliyunOSSStorageModuleConfiguration UseAliyunOSSStorage(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abplus.AliyunOSSStorage", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/IO/AliyunOSSStorage/AliyunOSSStorage.cs ================================================ using System; using System.IO; using System.Threading; using System.Threading.Tasks; using Abp.Dependency; using Abp.Extensions; using Abp.IO.Extensions; using Aliyun.OSS; using Castle.Core.Logging; namespace Abp.IO.AliyunOSSStorage { public class AliyunOSSStorage : IFileStorage { private static Lazy _client = new Lazy(InitClient, LazyThreadSafetyMode.PublicationOnly); private static OssClient InitClient() { var c = IocManager.Instance.Resolve(); return new OssClient(c.Endpoint, c.AccessKeyId, c.AccessKeySecret); } private readonly IAliyunOSSStorageModuleConfiguration _config; protected ILogger Logger { get; set; } public AliyunOSSStorage(IAliyunOSSStorageModuleConfiguration config) { _config = config; Logger = NullLogger.Instance; } public Task Delete(string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('/'); } _client.Value.DeleteObject(_config.BucketName, $"{subPath}{fileName}"); return Task.FromResult(0); } public Task ReadAsBytes(string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('/'); } var ossObj = _client.Value.GetObject(_config.BucketName, $"{subPath}{fileName}"); try { using (var rs = ossObj.Content) { var bytes = rs.GetAllBytes(); return Task.FromResult(bytes); } } catch (Exception ex) { Logger.Error(ex.Message, ex); throw ex; } } public Task Save(Stream source, string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('/'); } _client.Value.PutObject(_config.BucketName, $"{subPath}{fileName}", source); if (!_config.UriPrefix.IsNullOrWhiteSpace()) { return Task.FromResult($"{_config.UriPrefix.EnsureEndsWith('/')}{subPath}{fileName}"); } return Task.FromResult($"{subPath}{fileName}"); } public Task Save(byte[] source, string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('/'); } var stream = new MemoryStream(source); _client.Value.PutObject(_config.BucketName, $"{subPath}{fileName}", stream); if (!_config.UriPrefix.IsNullOrWhiteSpace()) { return Task.FromResult($"{_config.UriPrefix.EnsureEndsWith('/')}{subPath}{fileName}"); } return Task.FromResult($"{subPath}{fileName}"); } } } ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/IO/AliyunOSSStorage/AliyunOSSStorageModule.cs ================================================ using System.Reflection; using Abp.Localization; using Abp.Modules; namespace Abp.IO.AliyunOSSStorage { [DependsOn(typeof(AbpKernelModule))] public class AliyunOSSStorageModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.Register(); IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); AliyunOSSStorageLocalizationConfigurer.Configure(Configuration.Localization); } } } ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/IO/AliyunOSSStorage/AliyunOSSStorageModuleConfiguration.cs ================================================ namespace Abp.IO.AliyunOSSStorage { public class AliyunOSSStorageModuleConfiguration : IAliyunOSSStorageModuleConfiguration { public string AccessKeyId { get; private set; } public string AccessKeySecret { get; private set; } public string Endpoint { get; private set; } public string BucketName { get; private set; } public string UriPrefix { get; private set; } public IAliyunOSSStorageModuleConfiguration SetAccessKeyId(string id) { AccessKeyId = id; return this; } public IAliyunOSSStorageModuleConfiguration SetAccessKeySecret(string secret) { AccessKeySecret = secret; return this; } public IAliyunOSSStorageModuleConfiguration SetBucketName(string bucketName) { BucketName = bucketName; return this; } public IAliyunOSSStorageModuleConfiguration SetEndpoint(string endpoint) { Endpoint = endpoint; return this; } public IAliyunOSSStorageModuleConfiguration WithUriPrefix(string prefix) { UriPrefix = prefix; return this; } } } ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/IO/AliyunOSSStorage/IAliyunOSSStorageModuleConfiguration.cs ================================================ namespace Abp.IO.AliyunOSSStorage { public interface IAliyunOSSStorageModuleConfiguration { string AccessKeyId { get; } string AccessKeySecret { get; } string Endpoint { get; } string BucketName { get; } string UriPrefix { get; } IAliyunOSSStorageModuleConfiguration SetAccessKeyId(string id); IAliyunOSSStorageModuleConfiguration SetAccessKeySecret(string secret); IAliyunOSSStorageModuleConfiguration SetEndpoint(string endpoint); IAliyunOSSStorageModuleConfiguration SetBucketName(string bucketName); IAliyunOSSStorageModuleConfiguration WithUriPrefix(string prefix); } } ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/IO/AliyunOSSStorageConsts.cs ================================================ namespace Abp.IO { public class AliyunOSSStorageConsts { public const string LocalizationSourceName = "AliyunOSSStorage"; } } ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/Localization/AliyunOSSStorageLocalizationConfigurer.cs ================================================ using Abp.Configuration.Startup; using Abp.IO; using Abp.Localization.Dictionaries; using Abp.Localization.Dictionaries.Xml; using Abp.Reflection.Extensions; namespace Abp.Localization { public class AliyunOSSStorageLocalizationConfigurer { public static void Configure(ILocalizationConfiguration localizationConfiguration) { localizationConfiguration.Sources.Add( new DictionaryBasedLocalizationSource(AliyunOSSStorageConsts.LocalizationSourceName, new XmlEmbeddedFileLocalizationDictionaryProvider( typeof(AliyunOSSStorageLocalizationConfigurer).GetAssembly(), "Abp.Localization.SourceFiles" ) ) ); } } } ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/Localization/SourceFiles/AliyunOSSStorage-zh-Hans.xml ================================================  ================================================ FILE: src/Abplus.IO.AliyunOSSStorage/Localization/SourceFiles/AliyunOSSStorage.xml ================================================  ================================================ FILE: src/Abplus.IO.AzureBlobStorage/Abplus.IO.AzureBlobStorage.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.IO.AzureBlobStorage/Abplus.IO.AzureBlobStorage.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2019 ================================================ FILE: src/Abplus.IO.AzureBlobStorage/Configuration/Startup/AzureBlobFileStorageConfigurationExtensions.cs ================================================ using Abp.IO.AzureBlobStorage; namespace Abp.Configuration.Startup { public static class AzureBlobFileStorageConfigurationExtensions { public static IAzureBlobFileStorageModuleConfig UseAzureBlobFileStorage(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abplus.AzureBlobFileStorage", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/AzureBlobFileStorage.cs ================================================ using System; using System.IO; using System.Threading.Tasks; using Abp.Extensions; using Abp.IO.Extensions; using Castle.Core.Logging; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Auth; using Microsoft.WindowsAzure.Storage.Blob; namespace Abp.IO.AzureBlobStorage { public class AzureBlobFileStorage : IFileStorage { private readonly IAzureBlobFileStorageConfig _config; protected ILogger Logger { get; set; } public AzureBlobFileStorage(IAzureBlobFileStorageConfig config) { _config = config; Logger = NullLogger.Instance; } public async Task Delete(string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('/'); } var container = GetCloudBlobContainer(_config); // Get the reference to the block blob from the container CloudBlockBlob blockBlob = container.GetBlockBlobReference($"{subPath}{fileName}"); try { await blockBlob.DeleteIfExistsAsync(); } catch (Exception ex) { Logger.Error(ex.Message, ex); throw ex; } } public async Task ReadAsBytes(string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('/'); } var container = GetCloudBlobContainer(_config); // Get the reference to the block blob from the container CloudBlockBlob blockBlob = container.GetBlockBlobReference($"{subPath}{fileName}"); try { using (var rs = blockBlob.OpenRead()) { return rs.GetAllBytes(); } } catch (Exception ex) { Logger.Error(ex.Message, ex); throw ex; } } public async Task Save(Stream source, string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('/'); } await UploadFileToStorage(source, $"{subPath}{fileName}", _config); return AbsoluteAccessPath(_config, $"{subPath}{fileName}"); } public async Task Save(byte[] source, string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('/'); } await UploadFileToStorage(source, $"{subPath}{fileName}", _config); return AbsoluteAccessPath(_config, $"{subPath}{fileName}"); } private static string AbsoluteAccessPath(IAzureBlobFileStorageConfig config, string relativePathAndFileName) { return $"https://{config.AccountName}.blob.{config.EndpointSuffix}/{config.Container}/{relativePathAndFileName}"; } private static async Task UploadFileToStorage(byte[] fileBytes, string fileName, IAzureBlobFileStorageConfig _storageConfig) { var container = GetCloudBlobContainer(_storageConfig); // Get the reference to the block blob from the container CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName); // Upload the file await blockBlob.UploadFromByteArrayAsync(fileBytes, 0, fileBytes.Length); return await Task.FromResult(true); } private static async Task UploadFileToStorage(Stream fileStream, string fileName, IAzureBlobFileStorageConfig _storageConfig) { var container = GetCloudBlobContainer(_storageConfig); // Get the reference to the block blob from the container CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName); // Upload the file await blockBlob.UploadFromStreamAsync(fileStream); return await Task.FromResult(true); } private static CloudBlobContainer GetCloudBlobContainer(IAzureBlobFileStorageConfig storageConfig) { // Create storagecredentials object by reading the values from the configuration (appsettings.json) StorageCredentials storageCredentials = new StorageCredentials(storageConfig.AccountName, storageConfig.AccountKey); // Create cloudstorage account by passing the storagecredentials CloudStorageAccount storageAccount = new CloudStorageAccount(storageCredentials, storageConfig.EndpointSuffix, true); // Create the blob client. CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Get reference to the blob container by passing the name by reading the value from the configuration (appsettings.json) return blobClient.GetContainerReference(storageConfig.Container); } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/AzureBlobFileStorageConfig.cs ================================================ namespace Abp.IO.AzureBlobStorage { public class AzureBlobFileStorageConfig : IAzureBlobFileStorageConfig { private readonly IAzureBlobFileStorageModuleConfig _moduleConfig; public AzureBlobFileStorageConfig(IAzureBlobFileStorageModuleConfig moduleConfig) { _moduleConfig = moduleConfig; } public string AccountName => _moduleConfig.AccountName; public string AccountKey => _moduleConfig.AccountKey; public string Container => _moduleConfig.Container; public string EndpointSuffix => _moduleConfig.EndpointSuffix; } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/AzureBlobFileStorageModule.cs ================================================ using System.Reflection; using Abp.IO.AzureBlobStorage.Configuration; using Abp.Localization; using Abp.Modules; namespace Abp.IO.AzureBlobStorage { /// /// TODO 是否由本模块自行实现相关setting设置接口? /// [DependsOn(typeof(AbpKernelModule))]//依赖SettingManager public class AzureBlobFileStorageModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { var moduleConfig = IocManager.Resolve(); if (moduleConfig.UseSettingManager) { IocManager.Register(); } else { IocManager.Register(); } IocManager.Register(); IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); AzureBlobStorageLocalizationConfigurer.Configure(Configuration.Localization); } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/AzureBlobFileStorageModuleConfig.cs ================================================ namespace Abp.IO.AzureBlobStorage { public class AzureBlobFileStorageModuleConfig : IAzureBlobFileStorageModuleConfig { public AzureBlobFileStorageModuleConfig() { UseSettingManager = false; } #region AzureBlobStorageConfig public string AccountName { get; private set; } public string AccountKey { get; private set; } public string Container { get; private set; } public string EndpointSuffix { get; private set; } #endregion public bool UseSettingManager { get; private set; } public IAzureBlobFileStorageModuleConfig ConfigAzureStorage() { UseSettingManager = false; return this; } public void ConfigAzureStorageUseSettingManager() { UseSettingManager = true; } public IAzureBlobFileStorageModuleConfig SetAccountKey(string accountKey) { AccountKey = accountKey; return this; } public IAzureBlobFileStorageModuleConfig SetAccountName(string accountName) { AccountName = accountName; return this; } public IAzureBlobFileStorageModuleConfig SetContainer(string container) { Container = container; return this; } public IAzureBlobFileStorageModuleConfig UseEndpointSuffix(string endpointSuffix) { EndpointSuffix = endpointSuffix; return this; } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/Configuration/AzureBlobFileStorageSetting.cs ================================================ using Abp.Configuration; namespace Abp.IO.AzureBlobStorage.Configuration { /// /// use SettingManager to config azure blob storage per tenant /// public class AzureBlobFileStorageSetting : IAzureBlobFileStorageConfig { protected SettingManager SettingManager; public AzureBlobFileStorageSetting(SettingManager settingManager) { SettingManager = settingManager; } public string AccountName { get { return SettingManager.GetSettingValue(AzureBlobFileStorageSettingNames.AccountName); } } public string AccountKey { get { return SettingManager.GetSettingValue(AzureBlobFileStorageSettingNames.AccountKey); } } public string Container { get { return SettingManager.GetSettingValue(AzureBlobFileStorageSettingNames.Container); } } public string EndpointSuffix { get { return SettingManager.GetSettingValue(AzureBlobFileStorageSettingNames.EndpointSuffix); } } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/Configuration/AzureBlobFileStorageSettingNames.cs ================================================ namespace Abp.IO.AzureBlobStorage.Configuration { public static class AzureBlobFileStorageSettingNames { public const string AccountName = "Abplus.IO.AzureBlobStorage.AccountName"; public const string AccountKey = "Abplus.IO.AzureBlobStorage.AccountKey"; public const string Container = "Abplus.IO.AzureBlobStorage.Container"; public const string EndpointSuffix = "Abplus.IO.AzureBlobStorage.EndpointSuffix"; // string ThumbnailContainer { get; set; } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/Configuration/AzureBlobFileStorageSettingProvider.cs ================================================ using System.Collections.Generic; using Abp.Configuration; using Abp.Localization; namespace Abp.IO.AzureBlobStorage.Configuration { public class AzureBlobFileStorageSettingProvider : SettingProvider { public override IEnumerable GetSettingDefinitions(SettingDefinitionProviderContext context) { return new List { new SettingDefinition( AzureBlobFileStorageSettingNames.AccountName, "", L("AzureBlobFileStorageAccountName"), scopes: SettingScopes.Application|SettingScopes.Tenant), new SettingDefinition( AzureBlobFileStorageSettingNames.AccountKey, "", L("AzureBlobFileStorageAccountKey"), scopes:SettingScopes.Application|SettingScopes.Tenant), new SettingDefinition( AzureBlobFileStorageSettingNames.Container, "", L("AzureBlobFileStorageContainer"), scopes:SettingScopes.Application|SettingScopes.Tenant), new SettingDefinition( AzureBlobFileStorageSettingNames.EndpointSuffix, "", L("AzureBlobFileStorageEndpointSuffix"), scopes:SettingScopes.Application|SettingScopes.Tenant) }; } private static LocalizableString L(string name) { return new LocalizableString(name, AzureBlobStorageConsts.LocalizationSourceName); } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/IAzureBlobFileStorageConfig.cs ================================================ namespace Abp.IO.AzureBlobStorage { public interface IAzureBlobFileStorageConfig { string AccountName { get; } string AccountKey { get; } string Container { get; } // string ThumbnailContainer { get; } string EndpointSuffix { get; } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorage/IAzureBlobFileStorageModuleConfig.cs ================================================ namespace Abp.IO.AzureBlobStorage { public interface IAzureBlobFileStorageModuleConfig : IAzureBlobFileStorageConfig { bool UseSettingManager { get; } void ConfigAzureStorageUseSettingManager(); IAzureBlobFileStorageModuleConfig ConfigAzureStorage(); IAzureBlobFileStorageModuleConfig SetAccountName(string accountName); IAzureBlobFileStorageModuleConfig SetAccountKey(string accountKey); IAzureBlobFileStorageModuleConfig SetContainer(string container); IAzureBlobFileStorageModuleConfig UseEndpointSuffix(string endpointSuffix); } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/IO/AzureBlobStorageConsts.cs ================================================ namespace Abp.IO { public class AzureBlobStorageConsts { public const string LocalizationSourceName = "AbplusAzureBlobStorage"; } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/Localization/AzureBlobStorageLocalizationConfigurer.cs ================================================ using Abp.Configuration.Startup; using Abp.IO; using Abp.Localization.Dictionaries; using Abp.Localization.Dictionaries.Xml; using Abp.Reflection.Extensions; namespace Abp.Localization { public class AzureBlobStorageLocalizationConfigurer { public static void Configure(ILocalizationConfiguration localizationConfiguration) { localizationConfiguration.Sources.Add( new DictionaryBasedLocalizationSource(AzureBlobStorageConsts.LocalizationSourceName, new XmlEmbeddedFileLocalizationDictionaryProvider( typeof(AzureBlobStorageLocalizationConfigurer).GetAssembly(), "Abp.Localization.SourceFiles" ) ) ); } } } ================================================ FILE: src/Abplus.IO.AzureBlobStorage/Localization/SourceFiles/AbplusAzureBlobStorage-zh-Hans.xml ================================================  ================================================ FILE: src/Abplus.IO.AzureBlobStorage/Localization/SourceFiles/AbplusAzureBlobStorage.xml ================================================  ================================================ FILE: src/Abplus.IO.LocalFileSystem/Abplus.IO.LocalFileSystem.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.IO.LocalFileSystem/IO/LocalFileSystem/ILocalFileSystemStorageConfig.cs ================================================ namespace Abp.IO.LocalFileSystem { public interface ILocalFileSystemStorageConfig { string StoreRootDirectory { get; } string AccessUriRootPath { get; } } } ================================================ FILE: src/Abplus.IO.LocalFileSystem/IO/LocalFileSystem/LocalFileSystemStorage.cs ================================================ using System.IO; using System.Threading.Tasks; using Abp.Extensions; using Abp.IO.Extensions; #pragma warning disable CS1998 namespace Abp.IO.LocalFileSystem { /// /// 本地存储,和部署情况相关,只能针对Application配置 /// 先实现win系统 /// TODO@personball 跨平台兼容 /// public class LocalFileSystemStorage : IFileStorage { private readonly ILocalFileSystemStorageConfig _config; public LocalFileSystemStorage(ILocalFileSystemStorageConfig config) { _config = config; } public async Task Delete(string fileName, string subPath = null) { var filePath = $"{_config.StoreRootDirectory.EnsureEndsWith('\\')}{subPath.EnsureEndsWith('\\')}{fileName}"; if (File.Exists(filePath)) { File.Delete(filePath); } } public async Task ReadAsBytes(string fileName, string subPath = null) { var filePath = $"{_config.StoreRootDirectory.EnsureEndsWith('\\')}{subPath.EnsureEndsWith('\\')}{fileName}"; using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { return fs.GetAllBytes(); } } public async Task Save(Stream source, string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('\\'); } var path = $"{_config.StoreRootDirectory.EnsureEndsWith('\\')}{subPath}"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } using (var fs = new FileStream($"{path}{fileName}", FileMode.Create)) { await source.CopyToAsync(fs); } return AbsoluteAccessUri(_config, subPath.Replace('\\', '/'), fileName); } private string AbsoluteAccessUri(ILocalFileSystemStorageConfig config, string subPath, string fileName) { return $"{config.AccessUriRootPath.EnsureEndsWith('/')}{subPath}{fileName}"; } public async Task Save(byte[] source, string fileName, string subPath = null) { if (!subPath.IsNullOrWhiteSpace()) { subPath = subPath.EnsureEndsWith('\\'); } var path = $"{_config.StoreRootDirectory.EnsureEndsWith('\\')}{subPath}"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } File.WriteAllBytes($"{path}{fileName}", source); return AbsoluteAccessUri(_config, subPath.Replace('\\', '/'), fileName); } } } #pragma warning restore CS1998 ================================================ FILE: src/Abplus.IO.LocalFileSystem/IO/LocalFileSystem/LocalFileSystemStorageConfig.cs ================================================ using Abp.Configuration; namespace Abp.IO.LocalFileSystem { public class LocalFileSystemStorageConfig : ILocalFileSystemStorageConfig { protected readonly ISettingManager SettingManager; public LocalFileSystemStorageConfig(ISettingManager settingManager) { SettingManager = settingManager; } public string StoreRootDirectory { get { return SettingManager.GetSettingValueForApplication( LocalFileSystemStorageSettingNames.StoreRootDirectory); } } public string AccessUriRootPath { get { return SettingManager.GetSettingValueForApplication( LocalFileSystemStorageSettingNames.AccessUriRootPath); } } } } ================================================ FILE: src/Abplus.IO.LocalFileSystem/IO/LocalFileSystem/LocalFileSystemStorageModule.cs ================================================ using System.Reflection; using Abp.Localization; using Abp.Modules; namespace Abp.IO.LocalFileSystem { //TODO 是否由本模块自行实现相关setting设置接口? [DependsOn(typeof(AbpKernelModule))] public class LocalFileSystemStorageModule : AbpModule { public override void Initialize() { //IocManager.Register(); IocManager.Register(); IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); LocalFileSystemLocalizationConfigurer.Configure(Configuration.Localization); } } } ================================================ FILE: src/Abplus.IO.LocalFileSystem/IO/LocalFileSystem/LocalFileSystemStorageSettingNames.cs ================================================ namespace Abp.IO.LocalFileSystem { public static class LocalFileSystemStorageSettingNames { /// /// 存储的根目录,系统目录(注意不同OS的路径表示方式) /// public const string StoreRootDirectory = "Abplus.IO.LocalSystemFileStorage.StoreRootDirectory"; /// /// 读取的URI路径 /// public const string AccessUriRootPath = "Abplus.IO.LocalSystemFileStorage.AccessUriRootPath"; } } ================================================ FILE: src/Abplus.IO.LocalFileSystem/IO/LocalFileSystem/LocalFileSystemStorageSettingProvider.cs ================================================ using System.Collections.Generic; using Abp.Configuration; using Abp.Localization; namespace Abp.IO.LocalFileSystem { public class LocalFileSystemStorageSettingProvider : SettingProvider { public override IEnumerable GetSettingDefinitions(SettingDefinitionProviderContext context) { return new List { new SettingDefinition( LocalFileSystemStorageSettingNames.StoreRootDirectory, "", L("StoreRootDirectory"), scopes: SettingScopes.Application), new SettingDefinition( LocalFileSystemStorageSettingNames.AccessUriRootPath, "", L("AccessUriRootPath"), scopes:SettingScopes.Application) }; } private static LocalizableString L(string name) { return new LocalizableString(name, LocalFileSystemConsts.LocalizationSourceName); } } } ================================================ FILE: src/Abplus.IO.LocalFileSystem/IO/LocalFileSystemConsts.cs ================================================ namespace Abp.IO { public class LocalFileSystemConsts { public const string LocalizationSourceName = "AbplusLocalFileSystem"; } } ================================================ FILE: src/Abplus.IO.LocalFileSystem/Localization/LocalFileSystemLocalizationConfigurer.cs ================================================ using Abp.Configuration.Startup; using Abp.IO; using Abp.Localization.Dictionaries; using Abp.Localization.Dictionaries.Xml; using Abp.Reflection.Extensions; namespace Abp.Localization { public class LocalFileSystemLocalizationConfigurer { public static void Configure(ILocalizationConfiguration localizationConfiguration) { localizationConfiguration.Sources.Add( new DictionaryBasedLocalizationSource(LocalFileSystemConsts.LocalizationSourceName, new XmlEmbeddedFileLocalizationDictionaryProvider( typeof(LocalFileSystemLocalizationConfigurer).GetAssembly(), "Abp.Localization.SourceFiles" ) ) ); } } } ================================================ FILE: src/Abplus.IO.LocalFileSystem/Localization/SourceFiles/AbplusLocalFileSystem-zh-Hans.xml ================================================  ================================================ FILE: src/Abplus.IO.LocalFileSystem/Localization/SourceFiles/AbplusLocalFileSystem.xml ================================================  ================================================ FILE: src/Abplus.MqMessages/Abplus.MqMessages.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.MqMessages/Abplus.MqMessages.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.MqMessages/Configuration/Startup/ExceptionLogInterceptorRegistrar.cs ================================================ using Abp.Dependency; using Abp.MqMessages.MqHandlers; using Abp.MqMessages.MqHandlers.ExceptionLogging; using Castle.Core; using Castle.MicroKernel; namespace Abp.Configuration.Startup { public static class ExceptionLogInterceptorRegistrar { public static void Initialize(IIocManager iocManager) { iocManager.Register(); iocManager.Register(); iocManager.IocContainer.Kernel.ComponentRegistered += Kernel_ComponentRegistered; } private static void Kernel_ComponentRegistered(string key, IHandler handler) { if (typeof(AbpMqHandlerBase).IsAssignableFrom(handler.ComponentModel.Implementation)) { handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(ExceptionLogInterceptor))); } } } } ================================================ FILE: src/Abplus.MqMessages/MqMessages/AuditingStores/AuditInfoMqMessage.cs ================================================ using System; namespace Abp.MqMessages.AuditingStores { public class AuditInfoMqMessage { /// /// TenantId. /// public int? TenantId { get; set; } /// /// UserId. /// public long? UserId { get; set; } /// /// ImpersonatorUserId. /// public long? ImpersonatorUserId { get; set; } /// /// ImpersonatorTenantId. /// public int? ImpersonatorTenantId { get; set; } /// /// Service (class/interface) name. /// public string ServiceName { get; set; } /// /// Executed method name. /// public string MethodName { get; set; } /// /// Calling parameters. /// public string Parameters { get; set; } /// /// Start time of the method execution. /// public DateTime ExecutionTime { get; set; } /// /// Total duration of the method call. /// public int ExecutionDuration { get; set; } /// /// IP address of the client. /// public string ClientIpAddress { get; set; } /// /// Name (generally computer name) of the client. /// public string ClientName { get; set; } /// /// Browser information if this method is called in a web request. /// public string BrowserInfo { get; set; } /// /// Optional custom data that can be filled and used. /// public string CustomData { get; set; } /// /// /// public string Exception { get; set; } } } ================================================ FILE: src/Abplus.MqMessages/MqMessages/AutoGeneration/DontGenerateMqMessage.cs ================================================ using System; namespace Abp.MqMessages.AutoGeneration { /// /// 标记指定EventData不参与自动生成MqMessage /// [AttributeUsage(AttributeTargets.Class, Inherited = false)] public class DontGenerateMqMessage : Attribute { } } ================================================ FILE: src/Abplus.MqMessages/MqMessages/AutoMapper/AutoEventsMapToMqMessagesHelper.cs ================================================ using System.Linq; using System.Reflection; using Abp.MqMessages.Handlers; using AutoMapper; namespace Abp.MqMessages.AutoMapper { public static class AutoEventsMapToMqMessagesHelper { public static void CreateEventsToMqMessagesMappings(this IMapperConfigurationExpression mapper, Assembly assembly) { var typesToRegister = assembly.GetTypes() .Where(type => !string.IsNullOrEmpty(type.Namespace)) .Where(type => type.BaseType != null && type.BaseType.IsGenericType && (type.BaseType.GetGenericTypeDefinition() == typeof(EventDataPublishHandlerBase<,>))); foreach (var type in typesToRegister) { var genericArgs = type.BaseType.GetGenericArguments(); if (genericArgs.Length > 1 && !genericArgs[0].BaseType.IsGenericType) { mapper.CreateMap(genericArgs[0], genericArgs[1]); } } } } } ================================================ FILE: src/Abplus.MqMessages/MqMessages/Handlers/EventDataPublishHandlerBase.cs ================================================ using Abp.AutoMapper; using Abp.Dependency; using Abp.Domain.Uow; using Abp.Events.Bus; using Abp.Events.Bus.Handlers; using Castle.Core.Logging; namespace Abp.MqMessages.Handlers { /// /// 订阅EventData并发布消息到消息队列的抽象基类 /// /// Abp事件 /// 支持序列化的消息体(类DTO对象) public abstract class EventDataPublishHandlerBase : IEventHandler, ITransientDependency where TEventData : EventData where TMqMessage : class { protected readonly IUnitOfWorkManager UnitOfWorkManager; public ILogger Logger { get; set; } public IMqMessagePublisher MqMessagePublisher { get; set; } public EventDataPublishHandlerBase(IUnitOfWorkManager unitOfWorkManager) { UnitOfWorkManager = unitOfWorkManager; Logger = NullLogger.Instance; MqMessagePublisher = NullMqMessagePublisher.Instance; } public virtual void HandleEvent(TEventData eventData) { if (UnitOfWorkManager.Current == null) { MqMessagePublisher.Publish(ConvertEventDataToMqMessage(eventData)); } else { UnitOfWorkManager.Current.Completed += (sender, e) => MqMessagePublisher.Publish(ConvertEventDataToMqMessage(eventData)); } } /// /// 转换EventData为MqMessage,默认采用eventData.MapTo() /// /// /// public virtual TMqMessage ConvertEventDataToMqMessage(TEventData eventData) { return eventData.MapTo(); } } } ================================================ FILE: src/Abplus.MqMessages/MqMessages/MqHandlers/AbpMqHandlerBase.cs ================================================ using System; using System.Threading.Tasks; using Abp.Dependency; using Abp.MqMessages.MessageTrackers; namespace Abp.MqMessages.MqHandlers { public abstract class AbpMqHandlerBase : AbpServiceBase, ITransientDependency { public IMessageTracker MessageTracker { get; set; } public AbpMqHandlerBase(string localizationSourceName) { LocalizationSourceName = localizationSourceName; MessageTracker = DefaultInMemoryMessageTracker.Instance; } protected async Task IsTrueSetting(string settingKey) { return string.Equals("true", await SettingManager.GetSettingValueForApplicationAsync(settingKey), StringComparison.CurrentCultureIgnoreCase); } } } ================================================ FILE: src/Abplus.MqMessages/MqMessages/MqHandlers/ExceptionLoggling/ExceptionLogAttribute.cs ================================================ using System; using Abp.Logging; namespace Abp.MqMessages.MqHandlers.ExceptionLogging { public class ExceptionLogAttribute : Attribute { /// /// 需拦截的异常 /// public Type[] ExceptionTypes { get; set; } /// /// 是否记录日志,默认true /// public bool Logged { get; set; } /// /// 日志级别,默认Warn /// public LogSeverity LogLevel { get; set; } /// /// 是否吃掉异常,默认false /// public bool NotThrow { get; set; } /// /// /// /// public ExceptionLogAttribute(params Type[] exceptionTypes) : this(true, LogSeverity.Warn, false, exceptionTypes) { } /// /// /// /// /// public ExceptionLogAttribute(bool notThrow, params Type[] exceptionTypes) : this(true, LogSeverity.Warn, notThrow, exceptionTypes) { } /// /// /// /// /// /// public ExceptionLogAttribute(bool logged, LogSeverity logLevel, params Type[] exceptionTypes) : this(logged, logLevel, false, exceptionTypes) { } /// /// /// /// 记录日志(警告级别),默认true /// 日志等级 /// 是否吃掉异常 /// 需拦截的异常 public ExceptionLogAttribute(bool logged, LogSeverity logLevel, bool notThrow, params Type[] exceptionTypes) { Logged = logged; LogLevel = logLevel; NotThrow = notThrow; ExceptionTypes = exceptionTypes; } } } ================================================ FILE: src/Abplus.MqMessages/MqMessages/MqHandlers/ExceptionLoggling/ExceptionLogHandler.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Abp.Extensions; using Abp.Interceptors; using Castle.Core.Logging; using Castle.DynamicProxy; namespace Abp.MqMessages.MqHandlers.ExceptionLogging { public class ExceptionLogHandler : IAsyncInterceptorHandler { public ILogger Logger { get; set; } public ExceptionLogHandler() { Logger = NullLogger.Instance; } public void Handle(IInvocation invocation) { var handleExceptionAttributes = GetAttributesOfMemberAndDeclaringType( invocation.MethodInvocationTarget); if (handleExceptionAttributes.Count <= 0) { invocation.Proceed(); return; } else { try { invocation.Proceed(); } catch (Exception ex) { var exType = ex.GetType(); var attribute = handleExceptionAttributes.FirstOrDefault(h => h.ExceptionTypes.Contains(exType)); if (attribute == null) { ex.ReThrow(); } LogException(attribute, ex, invocation.MethodInvocationTarget); if (!attribute.NotThrow) { ex.ReThrow(); } } } } public async Task HandleAsync(IInvocation invocation) { var handleExceptionAttributes = GetAttributesOfMemberAndDeclaringType( invocation.MethodInvocationTarget); if (handleExceptionAttributes.Count <= 0) { invocation.Proceed(); await (Task)invocation.ReturnValue; } else { try { invocation.Proceed(); await (Task)invocation.ReturnValue; } catch (Exception ex) { var exType = ex.GetType(); var attribute = handleExceptionAttributes.FirstOrDefault(h => h.ExceptionTypes.Contains(exType)); if (attribute == null) { ex.ReThrow(); } LogException(attribute, ex, invocation.MethodInvocationTarget); if (!attribute.NotThrow) { ex.ReThrow(); } } } } public async Task HandleAsync(IInvocation invocation) { var handleExceptionAttributes = GetAttributesOfMemberAndDeclaringType( invocation.MethodInvocationTarget); if (handleExceptionAttributes.Count <= 0) { invocation.Proceed(); return await (Task)invocation.ReturnValue; } else { try { invocation.Proceed(); return await (Task)invocation.ReturnValue; } catch (Exception ex) { var exType = ex.GetType(); var attribute = handleExceptionAttributes.FirstOrDefault(h => h.ExceptionTypes.Contains(exType)); if (attribute == null) { ex.ReThrow(); } LogException(attribute, ex, invocation.MethodInvocationTarget); if (!attribute.NotThrow) { ex.ReThrow(); } return default(T); } } } private static List GetAttributesOfMemberAndDeclaringType(MemberInfo memberInfo) where TAttribute : Attribute { var attributeList = new List(); //Add attributes on the member if (memberInfo.IsDefined(typeof(TAttribute), true)) { attributeList.AddRange(memberInfo.GetCustomAttributes(typeof(TAttribute), true).Cast()); } //Add attributes on the class if (memberInfo.DeclaringType != null && memberInfo.DeclaringType.IsDefined(typeof(TAttribute), true)) { attributeList.AddRange(memberInfo.DeclaringType.GetCustomAttributes(typeof(TAttribute), true).Cast()); } return attributeList; } private void LogException(ExceptionLogAttribute attribute, Exception ex, MethodInfo methodInfo) { if (attribute.Logged) { var msg = $"{methodInfo.DeclaringType.FullName}.{$".{methodInfo.Name}"} Fail:{ex.Message}"; switch (attribute.LogLevel) { case Abp.Logging.LogSeverity.Debug: Logger.Debug(msg, ex); return; case Abp.Logging.LogSeverity.Info: Logger.Info(msg, ex); return; case Abp.Logging.LogSeverity.Warn: Logger.Warn(msg, ex); return; case Abp.Logging.LogSeverity.Error: Logger.Error(msg, ex); return; case Abp.Logging.LogSeverity.Fatal: Logger.Fatal(msg, ex); return; default: Logger.Warn(msg, ex); return; } } } } } ================================================ FILE: src/Abplus.MqMessages/MqMessages/MqHandlers/ExceptionLoggling/ExceptionLogInterceptor.cs ================================================ using Abp.Interceptors; namespace Abp.MqMessages.MqHandlers.ExceptionLogging { public class ExceptionLogInterceptor : AsyncHandlingInterceptor { public ExceptionLogInterceptor(ExceptionLogHandler handler) : base(handler) { } } } ================================================ FILE: src/Abplus.MqMessages.AuditingConsumerHandler/Abplus.MqMessages.AuditingConsumerHandler.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.MqMessages.AuditingConsumerHandler/Abplus.MqMessages.AuditingConsumerHandler.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.MqMessages.AuditingConsumerHandler/Auditing/AuditingStore/AuditingConsumerRebusHandlerModule.cs ================================================ using Abp.Modules; using System.Reflection; namespace Abp.Auditing.AuditingStore { public class AuditingConsumerRebusHandlerModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { MqMessageAuditingStoreRebusHandler.Timer.Start(); } public override void Shutdown() { MqMessageAuditingStoreRebusHandler.Timer.Stop(); } } } ================================================ FILE: src/Abplus.MqMessages.AuditingConsumerHandler/Auditing/AuditingStore/AuditingConsumerRebusHandlerModuleConfig.cs ================================================ using Abp.MqMessages.AuditingStores; using System; using System.Collections.Generic; namespace Abp.Auditing.AuditingStore { public class AuditingConsumerRebusHandlerModuleConfig : IAuditingConsumerRebusHandlerModuleConfig { public AuditingConsumerRebusHandlerModuleConfig() { BatchSize = 100; Period = TimeSpan.FromSeconds(1); BatchStoreAction = (msgList) => { }; } public int BatchSize { get; private set; } public Action> BatchStoreAction { get; private set; } public TimeSpan Period { get; private set; } public IAuditingConsumerRebusHandlerModuleConfig Batch(int batchSize) { BatchSize = batchSize; return this; } public IAuditingConsumerRebusHandlerModuleConfig Do(Action> storeAction) { BatchStoreAction = storeAction; return this; } public IAuditingConsumerRebusHandlerModuleConfig EveryPeriodIn(TimeSpan period) { Period = period; return this; } } } ================================================ FILE: src/Abplus.MqMessages.AuditingConsumerHandler/Auditing/AuditingStore/IAuditingConsumerRebusHandlerModuleConfig.cs ================================================ using Abp.MqMessages.AuditingStores; using System; using System.Collections.Generic; namespace Abp.Auditing.AuditingStore { public interface IAuditingConsumerRebusHandlerModuleConfig { /// /// 每批大小 /// int BatchSize { get; } /// /// 执行间隔(单位:秒) /// TimeSpan Period { get; } /// /// 批量存储的委托 /// Action> BatchStoreAction { get; } /// /// 设置执行间隔(单位:秒) /// /// /// IAuditingConsumerRebusHandlerModuleConfig EveryPeriodIn(TimeSpan period); /// /// 设置每批大小 /// /// /// IAuditingConsumerRebusHandlerModuleConfig Batch(int batchSize); /// /// 批量存储逻辑,如何处理消息 /// /// /// IAuditingConsumerRebusHandlerModuleConfig Do(Action> storeAction); } } ================================================ FILE: src/Abplus.MqMessages.AuditingConsumerHandler/Auditing/AuditingStore/MqMessageAuditingStoreRebusHandler.cs ================================================ using Abp.Dependency; using Abp.MqMessages.AuditingStores; using Abp.Threading.Timers; using Rebus.Handlers; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Abp.Auditing.AuditingStore { public class MqMessageAuditingStoreRebusHandler : IHandleMessages , ITransientDependency { private static ConcurrentQueue InMemoryAuditInfoQueue; public static AbpTimer Timer; static MqMessageAuditingStoreRebusHandler() { InMemoryAuditInfoQueue = new ConcurrentQueue(); var config = IocManager.Instance.Resolve(); Timer = new AbpTimer((int)config.Period.TotalMilliseconds, true); Timer.Elapsed += (s, e) => { var tmpMsg = new List(); for (int i = 0; i < config.BatchSize; i++) { AuditInfoMqMessage msg; if (InMemoryAuditInfoQueue.TryDequeue(out msg)) { tmpMsg.Add(msg); } else { break; } } if (tmpMsg.Any()) { config.BatchStoreAction(tmpMsg); } }; } public async Task Handle(AuditInfoMqMessage message) { InMemoryAuditInfoQueue.Enqueue(message); } } } ================================================ FILE: src/Abplus.MqMessages.AuditingConsumerHandler/Configuration/Startup/AuditingConsumerRebusHandlerConfigurationExtensions.cs ================================================ using Abp.Auditing.AuditingStore; namespace Abp.Configuration.Startup { public static class AuditingConsumerRebusHandlerConfigurationExtensions { public static IAuditingConsumerRebusHandlerModuleConfig AuditingConsumer(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abplus.AuditingConsumer", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src/Abplus.MqMessages.AuditingStore/Abplus.MqMessages.AuditingStore.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.MqMessages.AuditingStore/Abplus.MqMessages.AuditingStore.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.MqMessages.AuditingStore/Auditing/AuditingStores/MqMessageAuditingStore.cs ================================================ using Abp.Dependency; using Abp.MqMessages; using Abp.MqMessages.AuditingStores; using Abp.Threading; using System; using System.Threading.Tasks; namespace Abp.Auditing.AuditingStores { public class MqMessageAuditingStore : IAuditingStore, ITransientDependency { private readonly Lazy MqMessagePublisher;//why this need Lazy<>? public MqMessageAuditingStore() { MqMessagePublisher = new Lazy(() => { return IocManager.Instance.Resolve(); }); } public void Save(AuditInfo auditInfo) { AsyncHelper.RunSync(() => SaveAsync(auditInfo)); } public async Task SaveAsync(AuditInfo auditInfo) { var mqMsgAuditInfo = new AuditInfoMqMessage { BrowserInfo = auditInfo.BrowserInfo, ClientIpAddress = auditInfo.ClientIpAddress, ClientName = auditInfo.ClientName, CustomData = auditInfo.CustomData, ExecutionDuration = auditInfo.ExecutionDuration, ImpersonatorTenantId = auditInfo.ImpersonatorTenantId, ImpersonatorUserId = auditInfo.ImpersonatorUserId, MethodName = auditInfo.MethodName, Parameters = auditInfo.Parameters, ServiceName = auditInfo.ServiceName, UserId = auditInfo.UserId, ExecutionTime = auditInfo.ExecutionTime, TenantId = auditInfo.TenantId }; if (auditInfo.Exception != null) { mqMsgAuditInfo.CustomData += $" {auditInfo.Exception.Message}"; mqMsgAuditInfo.Exception = auditInfo.Exception.StackTrace; if (auditInfo.Exception.InnerException != null) { mqMsgAuditInfo.CustomData += $" {auditInfo.Exception.InnerException.Message}"; mqMsgAuditInfo.Exception = auditInfo.Exception.InnerException.StackTrace; } } await MqMessagePublisher.Value.PublishAsync(mqMsgAuditInfo); } } } ================================================ FILE: src/Abplus.MqMessages.AuditingStore/Auditing/AuditingStores/MqMessageAuditingStoreModule.cs ================================================ using Abp.Modules; using Abp.MqMessages.Publishers; namespace Abp.Auditing.AuditingStores { [DependsOn(typeof(RebusRabbitMqPublisherCoreModule))] public class MqMessageAuditingStoreModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } } } ================================================ FILE: src/Abplus.MqMessages.IndexToES/Abplus.MqMessages.IndexToES.csproj ================================================  net5.0 Abp TextTemplatingFileGenerator MqMessageIndexToESHandlerBuilder.cs True True MqMessageIndexToESHandlerBuilder.tt ================================================ FILE: src/Abplus.MqMessages.IndexToES/Abplus.MqMessages.IndexToES.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.MqMessages.IndexToES/DateTimeExtensions.cs ================================================ using System; namespace Abp { public static class DateTimeExtensions { public static string GetESIndexName(this DateTime now, string defaultIndexName, IndexFreq freqSetting) { Check.NotNullOrWhiteSpace(defaultIndexName, nameof(defaultIndexName)); if (freqSetting == IndexFreq.PerDay) { return $"{defaultIndexName}-{DateTime.Now.Date.ToString("yyyy.MM.dd")}"; } else if (freqSetting == IndexFreq.PerMonth) { return $"{defaultIndexName}-{DateTime.Now.Date.ToString("yyyy.MM")}"; } else if (freqSetting == IndexFreq.PerYear) { return $"{defaultIndexName}-{DateTime.Now.Date.ToString("yyyy")}"; } else { return defaultIndexName; } } } } ================================================ FILE: src/Abplus.MqMessages.IndexToES/IndexFreq.cs ================================================ namespace Abp { /// /// 定义创建索引的频率 /// public enum IndexFreq { /// /// 每天一个索引 /// PerDay = 0, /// /// 每月一个索引 /// PerMonth = 1, /// /// 每年一个索引 /// PerYear = 2, /// /// 仅一个索引,索引名不加日期后缀 /// None = 3 } } ================================================ FILE: src/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/MqMessageIndexToESHandlerBase.cs ================================================ using System; using System.Threading.Tasks; using Abp.Dependency; using Nest; using Rebus.Handlers; namespace Abp.MqMessages.MqHandlers { public abstract class MqMessageIndexToESHandlerBase : AbpMqHandlerBase , IHandleMessages , ITransientDependency where TMqMessage : class { protected string DefaultIndexName { get; set; } protected IndexFreq IndexFreq { get; set; } public IElasticClient ElasticClient { get; set; } public MqMessageIndexToESHandlerBase(string defaultIndexName, IndexFreq indexFreq, string localizationSourceName) : base(localizationSourceName) { DefaultIndexName = defaultIndexName; IndexFreq = indexFreq; } public async Task Handle(TMqMessage message) { var indexName = CustomIndexName(); var indexFreq = CustomIndexFreq(); await ElasticClient.IndexAsync(message, i => i.Index(DateTime.Now.GetESIndexName(indexName, indexFreq))); } public virtual string CustomIndexName() { return DefaultIndexName; } public virtual IndexFreq CustomIndexFreq() { return IndexFreq; } } } ================================================ FILE: src/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/MqMessageIndexToESHandlerBuilder.cs ================================================  ================================================ FILE: src/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/MqMessageIndexToESHandlerBuilder.tt ================================================ <#@ template debug="false" hostspecific="true" language="C#" #> <#@ include file="T4MultipleOutputManager.ttinclude" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.IO" #> <#@ assembly name="$(SolutionDir)packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll" #> <#@ assembly name="$(ProjectDir)bin\$(ConfigurationName)\$(ProjectName).exe" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="Newtonsoft.Json" #> <#@ import namespace="Newtonsoft.Json.Linq" #> <#@ import namespace="System.Globalization" #> <#@ import namespace="Abp.MqMessages.MqHandlers" #> <#@ output extension=".cs" #> <# var tempateManager = Manager.Create(Host,GenerationEnvironment); string projectName = Host.ResolveAssemblyReference("$(ProjectName)"); var types=MqMessagesT4Register.MqMessageTypes; foreach(var type in types) { tempateManager.StartNewFile(type.Name+"IndexToESHandler.cs"); #> using Abp; using Abp.MqMessages.MqHandlers; using <#=type.Namespace#>; namespace <#=projectName#>.MqMessages.MqHandlers { public class <#=type.Name#>IndexToESHandler : MqMessageIndexToESHandlerBase<<#=type.Name#>> { public <#=type.Name#>IndexToESHandler() : base(【DefaultIndexName】, IndexFreq.PerMonth, 【Consts.LocalizationSourceName】) { } } } <# }//foreach-end tempateManager.EndBlock(); tempateManager.Process(true); #> ================================================ FILE: src/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/MqMessagesT4Register.cs ================================================ using System; namespace Abp.MqMessages.MqHandlers { public static class MqMessagesT4Register { public static Type[] MqMessageTypes = new Type[] { //typeof(SampleMqMessage) }; } } ================================================ FILE: src/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/T4MultipleOutputManager.ttinclude ================================================ <#@ assembly name="System.Core" #><#@ assembly name="System.Data.Linq" #><#@ assembly name="EnvDTE" #><#@ assembly name="System.Xml" #><#@ assembly name="System.Xml.Linq" #><#@ import namespace="System.Collections.Generic" #><#@ import namespace="System.IO" #><#@ import namespace="System.Text" #><#@ import namespace="Microsoft.VisualStudio.TextTemplating" #><#+ // https://raw.github.com/damieng/DamienGKit // http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited // Manager class records the various blocks so it can split them up class Manager { private class Block { public String Name; public int Start, Length; public bool IncludeInDefault; } private Block currentBlock; private readonly List files = new List(); private readonly Block footer = new Block(); private readonly Block header = new Block(); private readonly ITextTemplatingEngineHost host; private readonly StringBuilder template; protected readonly List generatedFileNames = new List(); public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) { return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template); } public void StartNewFile(String name) { if (name == null) throw new ArgumentNullException("name"); CurrentBlock = new Block { Name = name }; } public void StartFooter(bool includeInDefault=true) { CurrentBlock = footer; footer.IncludeInDefault = includeInDefault; } public void StartHeader(bool includeInDefault=true) { CurrentBlock = header; header.IncludeInDefault = includeInDefault; } public void EndBlock() { if (CurrentBlock == null) return; CurrentBlock.Length = template.Length - CurrentBlock.Start; if (CurrentBlock != header && CurrentBlock != footer) files.Add(CurrentBlock); currentBlock = null; } public virtual void Process(bool split, bool sync =true) { if (split) { EndBlock(); String headerText = template.ToString(header.Start, header.Length); String footerText = template.ToString(footer.Start, footer.Length); String outputPath = Path.GetDirectoryName(host.TemplateFile); files.Reverse(); if (!footer.IncludeInDefault) template.Remove(footer.Start, footer.Length); foreach(Block block in files) { String fileName = Path.Combine(outputPath, block.Name); String content = headerText + template.ToString(block.Start, block.Length) + footerText; generatedFileNames.Add(fileName); CreateFile(fileName, content); template.Remove(block.Start, block.Length); } if (!header.IncludeInDefault) template.Remove(header.Start, header.Length); } } protected virtual void CreateFile(String fileName, String content) { if (IsFileContentDifferent(fileName, content)) File.WriteAllText(fileName, content); } public virtual String GetCustomToolNamespace(String fileName) { return null; } public virtual String DefaultProjectNamespace { get { return null; } } protected bool IsFileContentDifferent(String fileName, String newContent) { return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); } private Manager(ITextTemplatingEngineHost host, StringBuilder template) { this.host = host; this.template = template; } private Block CurrentBlock { get { return currentBlock; } set { if (CurrentBlock != null) EndBlock(); if (value != null) value.Start = template.Length; currentBlock = value; } } private class VSManager: Manager { private readonly EnvDTE.ProjectItem templateProjectItem; private readonly EnvDTE.DTE dte; private readonly Action checkOutAction; private readonly Action> projectSyncAction; public override String DefaultProjectNamespace { get { return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString(); } } public override String GetCustomToolNamespace(string fileName) { return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString(); } public override void Process(bool split, bool sync) { if (templateProjectItem.ProjectItems == null) return; base.Process(split, sync); if (sync) projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); } protected override void CreateFile(String fileName, String content) { if (IsFileContentDifferent(fileName, content)) { CheckoutFileIfRequired(fileName); File.WriteAllText(fileName, content); } } internal VSManager(ITextTemplatingEngineHost host, StringBuilder template) : base(host, template) { var hostServiceProvider = (IServiceProvider)host; if (hostServiceProvider == null) throw new ArgumentNullException("Could not obtain IServiceProvider"); dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); if (dte == null) throw new ArgumentNullException("Could not obtain DTE from host"); templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile); checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); } private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, List keepFileNames) { var keepFileNameSet = new HashSet(keepFileNames); var projectFiles = new Dictionary(); var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]) + "."; foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) projectFiles.Add(projectItem.FileNames[0], projectItem); // Remove unused items from the project foreach (var pair in projectFiles) if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix)) pair.Value.Delete(); // Add missing files to the project foreach(String fileName in keepFileNameSet) if (!projectFiles.ContainsKey(fileName)) templateProjectItem.ProjectItems.AddFromFile(fileName); } private void CheckoutFileIfRequired(String fileName) { var sc = dte.SourceControl; if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName)) checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); } } } #> ================================================ FILE: src/Abplus.MqMessages.RebusCore/Abplus.MqMessages.RebusCore.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.MqMessages.RebusCore/Abplus.MqMessages.RebusCore.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.MqMessages.RebusCore/MqMessages/Publishers/RebusRabbitMqPublisher.cs ================================================ using System.Threading.Tasks; using Abp.Json; using Abp.Runtime.Session; using Abp.Threading; using Castle.Core.Logging; using Rebus.Bus; namespace Abp.MqMessages.Publishers { public class RebusRabbitMqPublisher : IMqMessagePublisher { private readonly IBus _bus; public ILogger Logger { get; set; } public IAbpSession AbpSession { get; set; } public RebusRabbitMqPublisher(IBus bus) { _bus = bus; Logger = NullLogger.Instance; AbpSession = NullAbpSession.Instance; } public void Publish(object mqMessages) { TryFillSessionInfo(mqMessages); Logger.Debug(mqMessages.GetType().FullName + ":" + mqMessages.ToJsonString()); AsyncHelper.RunSync(() => _bus.Publish(mqMessages)); } private void TryFillSessionInfo(object mqMessages) { if (AbpSession.UserId.HasValue) { var operatorUserIdProperty = mqMessages.GetType().GetProperty("OperatorUserId"); if (operatorUserIdProperty != null && (operatorUserIdProperty.PropertyType == typeof(long?))) { operatorUserIdProperty.SetValue(mqMessages, AbpSession.UserId); } } if (AbpSession.TenantId.HasValue) { var tenantIdProperty = mqMessages.GetType().GetProperty("TenantId"); if (tenantIdProperty != null && (tenantIdProperty.PropertyType == typeof(int?))) { tenantIdProperty.SetValue(mqMessages, AbpSession.TenantId); } } } public async Task PublishAsync(object mqMessages) { TryFillSessionInfo(mqMessages); Logger.Debug(mqMessages.GetType().FullName + ":" + mqMessages.ToJsonString()); await _bus.Publish(mqMessages); } } } ================================================ FILE: src/Abplus.MqMessages.RebusCore/MqMessages/Publishers/RebusRabbitMqPublisherCoreModule.cs ================================================ using Abp.Modules; namespace Abp.MqMessages.Publishers { public class RebusRabbitMqPublisherCoreModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } } } ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqConsumer/Abplus.MqMessages.RebusRabbitMqConsumer.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqConsumer/Abplus.MqMessages.RebusRabbitMqConsumer.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqConsumer/Configuration/Startup/RebusRabbitMqConsumerConfigurationExtensions.cs ================================================ using Abp.MqMessages.Consumers; namespace Abp.Configuration.Startup { public static class RebusRabbitMqConsumerConfigurationExtensions { public static IRebusRabbitMqConsumerModuleConfig UseAbplusRebusRabbitMqConsumer(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abp.RebusRabbitMqConsumer", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqConsumer/MqMessages/Consumers/IRebusRabbitMqConsumerModuleConfig.cs ================================================ using System; using System.Reflection; using Rebus.Config; using Rebus.Serialization; namespace Abp.MqMessages.Consumers { public interface IRebusRabbitMqConsumerModuleConfig { /// /// 是否启用,默认启用 /// bool Enabled { get; } /// /// RabbitMq连接字符串 /// string ConnectString { get; } /// /// 队列名 /// string QueueName { get; } /// /// 最大并行数 /// int MaxParallelism { get; } /// /// 最大Worker数 /// int NumberOfWorkers { get; } /// /// 消费时每次拉取的消息个数 /// int PrefetchCount { get; } /// /// 消息审计是否开启,默认不开启 /// bool MessageAuditingEnabled { get; } /// /// 消息审计队列名,默认不启用 /// string MessageAuditingQueueName { get; } /// /// 包含RebusMqMessageHandler的程序集(自动订阅消息和自动注册handler) /// Assembly[] AssemblysIncludeRebusMqMessageHandlers { get; } /// /// 配置日志组件 /// Action LoggingConfigurer { get; } /// /// 其他选项配置 /// Action OptionsConfigurer { get; } /// /// 序列化组件配置 /// Action> SerializerConfigurer { get; } /// /// /// /// 是否启用,默认启用 /// IRebusRabbitMqConsumerModuleConfig Enable(bool enabled); /// /// /// /// RabbitMq连接字符串 /// IRebusRabbitMqConsumerModuleConfig ConnectTo(string connectString); /// /// /// /// 使用队列名 /// IRebusRabbitMqConsumerModuleConfig UseQueue(string queueName); /// /// /// /// 最大并行数 /// IRebusRabbitMqConsumerModuleConfig SetMaxParallelism(int maxParallelism); /// /// 设置最大工作线程数 /// /// 最大Worker数 /// IRebusRabbitMqConsumerModuleConfig SetNumberOfWorkers(int numberOfWorkers); /// /// 设置每次拉取消息数量,默认50 /// /// /// IRebusRabbitMqConsumerModuleConfig Prefetch(int count); /// /// 启用消息审计 /// /// 消息审计队列名 /// IRebusRabbitMqConsumerModuleConfig EnableMessageAuditing(string messageAuditingQueueName); /// /// 注册Rebus Handlers /// /// 包含Rebus Handlers的程序集 /// IRebusRabbitMqConsumerModuleConfig RegisterHandlerInAssemblys(params Assembly[] assemblys); /// /// 配置日志组件 /// /// /// IRebusRabbitMqConsumerModuleConfig UseLogging(Action loggingConfigurer); /// /// 配置其他选项 /// /// /// IRebusRabbitMqConsumerModuleConfig UseOptions(Action optionsConfigurer); /// /// 自定义序列化机制 /// /// /// IRebusRabbitMqConsumerModuleConfig UseSerializer(Action> serializerConfigurer); } } ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqConsumer/MqMessages/Consumers/RebusRabbitMqConsumerModule.cs ================================================ using Abp.Modules; using Abp.MqMessages.Publishers; using Rebus.Auditing.Messages; using Rebus.Bus; using Rebus.CastleWindsor; using Rebus.Config; using Rebus.Handlers; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Abp.MqMessages.Consumers { [DependsOn(typeof(RebusRabbitMqPublisherCoreModule))] public class RebusRabbitMqConsumerModule : AbpModule { private IBus _bus; public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { var moduleConfig = IocManager.Resolve(); if (moduleConfig.Enabled) { var rebusConfig = Configure.With(new CastleWindsorContainerAdapter(IocManager.IocContainer)); if (moduleConfig.LoggingConfigurer != null) { rebusConfig.Logging(moduleConfig.LoggingConfigurer); } if (moduleConfig.SerializerConfigurer != null) { rebusConfig.Serialization(moduleConfig.SerializerConfigurer); } if (moduleConfig.OptionsConfigurer != null) { rebusConfig.Options(moduleConfig.OptionsConfigurer); } rebusConfig.Options(c => { c.SetMaxParallelism(moduleConfig.MaxParallelism); c.SetNumberOfWorkers(moduleConfig.NumberOfWorkers); }); if (moduleConfig.MessageAuditingEnabled) { rebusConfig.Options(o => o.EnableMessageAuditing(moduleConfig.MessageAuditingQueueName)); } var mqMessageTypes = new List(); //Register handlers first! foreach (var assembly in moduleConfig.AssemblysIncludeRebusMqMessageHandlers) { IocManager.IocContainer.AutoRegisterHandlersFromAssembly(assembly); mqMessageTypes.AddRange(assembly.GetTypes() .Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandleMessages<>))) .SelectMany(t => t.GetInterfaces()) .Distinct() .SelectMany(t => t.GetGenericArguments()) .Distinct()); } //https://github.com/rebus-org/Rebus.RabbitMq/tree/master/Rebus.RabbitMq/Config more option about RabbitMqOptionsBuilder _bus = rebusConfig.Transport(c => c.UseRabbitMq(moduleConfig.ConnectString, moduleConfig.QueueName).Prefetch(moduleConfig.PrefetchCount)) .Start(); //Subscribe messages mqMessageTypes = mqMessageTypes.Distinct().ToList(); foreach (var mqMessageType in mqMessageTypes) { _bus.Subscribe(mqMessageType); } } } public override void Shutdown() { if (_bus != null) { _bus.Dispose(); } } } } ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqConsumer/MqMessages/Consumers/RebusRabbitMqConsumerModuleConfig.cs ================================================ using System; using System.Reflection; using Newtonsoft.Json; using Rebus.Config; //using Rebus.NewtonsoftJson;//nupkg不兼容 using Rebus.Serialization; namespace Abp.MqMessages.Consumers { public class RebusRabbitMqConsumerModuleConfig : IRebusRabbitMqConsumerModuleConfig { public RebusRabbitMqConsumerModuleConfig() { Enabled = true; MessageAuditingEnabled = false; MaxParallelism = 1; NumberOfWorkers = 1; PrefetchCount = 50; // SerializerConfigurer = c => c.UseNewtonsoftJson(new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });//不兼容,以及core运行时下,用完整类型名称限定太死 https://github.com/rebus-org/Rebus/issues/672 } public Assembly[] AssemblysIncludeRebusMqMessageHandlers { get; private set; } public string ConnectString { get; private set; } public bool Enabled { get; private set; } public Action LoggingConfigurer { get; private set; } public int MaxParallelism { get; private set; } public bool MessageAuditingEnabled { get; private set; } public string MessageAuditingQueueName { get; private set; } public int NumberOfWorkers { get; private set; } public Action OptionsConfigurer { get; private set; } public string QueueName { get; private set; } public Action> SerializerConfigurer { get; private set; } public int PrefetchCount { get; private set; } public IRebusRabbitMqConsumerModuleConfig ConnectTo(string connectString) { ConnectString = connectString; return this; } public IRebusRabbitMqConsumerModuleConfig Enable(bool enabled) { Enabled = enabled; return this; } public IRebusRabbitMqConsumerModuleConfig EnableMessageAuditing(string messageAuditingQueueName) { MessageAuditingEnabled = true; MessageAuditingQueueName = messageAuditingQueueName; return this; } public IRebusRabbitMqConsumerModuleConfig Prefetch(int count) { PrefetchCount = count; return this; } public IRebusRabbitMqConsumerModuleConfig RegisterHandlerInAssemblys(params Assembly[] assemblys) { AssemblysIncludeRebusMqMessageHandlers = assemblys; return this; } public IRebusRabbitMqConsumerModuleConfig SetMaxParallelism(int maxParallelism) { MaxParallelism = maxParallelism; return this; } public IRebusRabbitMqConsumerModuleConfig SetNumberOfWorkers(int numberOfWorkers) { NumberOfWorkers = numberOfWorkers; return this; } public IRebusRabbitMqConsumerModuleConfig UseLogging(Action loggingConfigurer) { LoggingConfigurer = loggingConfigurer; return this; } public IRebusRabbitMqConsumerModuleConfig UseOptions(Action optionsConfigurer) { OptionsConfigurer = optionsConfigurer; return this; } public IRebusRabbitMqConsumerModuleConfig UseQueue(string queueName) { QueueName = queueName; return this; } public IRebusRabbitMqConsumerModuleConfig UseSerializer(Action> serializerConfigurer) { SerializerConfigurer = serializerConfigurer; return this; } } } ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqPublisher/Abplus.MqMessages.RebusRabbitMqPublisher.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqPublisher/Abplus.MqMessages.RebusRabbitMqPublisher.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqPublisher/Configuration/Startup/RebusRabbitMqPublisherConfigurationExtensions.cs ================================================ using Abp.MqMessages.Publishers; namespace Abp.Configuration.Startup { public static class RebusRabbitMqPublisherConfigurationExtensions { public static IRebusRabbitMqPublisherModuleConfig UseAbplusRebusRabbitMqPublisher(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abp.RebusRabbitMqPublisher", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqPublisher/MqMessages/Publishers/IRebusRabbitMqPublisherModuleConfig.cs ================================================ using System; using Rebus.Config; namespace Abp.MqMessages.Publishers { public interface IRebusRabbitMqPublisherModuleConfig { /// /// 是否启用,默认启用 /// bool Enabled { get; } /// /// 日志配置委托 /// Action LoggingConfigurer { get; } /// /// RabbitMq连接字符串 /// string ConnectionString { get; } /// /// 消息审计是否开启,默认不开启 /// bool MessageAuditingEnabled { get; } /// /// 消息审计队列名,默认不启用 /// string MessageAuditingQueueName { get; } /// /// 是否启用,默认启用 /// /// /// IRebusRabbitMqPublisherModuleConfig Enable(bool enabled); /// /// 设置RabbitMq连接字符串 /// /// /// IRebusRabbitMqPublisherModuleConfig ConnectTo(string connectionString); /// /// 配置日志组件 /// /// /// IRebusRabbitMqPublisherModuleConfig UseLogging(Action loggingConfigurer); /// /// 是否启用消息审计,默认不启用 /// /// 审计队列名 /// IRebusRabbitMqPublisherModuleConfig EnableMessageAuditing(string messageAuditingQueueName); } } ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqPublisher/MqMessages/Publishers/RebusRabbitMqPublisherModule.cs ================================================ using System.Reflection; using Abp.Modules; using Rebus.Auditing.Messages; using Rebus.Bus; using Rebus.Config; namespace Abp.MqMessages.Publishers { [DependsOn(typeof(RebusRabbitMqPublisherCoreModule))] public class RebusRabbitMqPublisherModule : AbpModule { private IBus _bus; public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { var moduleConfig = IocManager.Resolve(); if (moduleConfig.Enabled) { var rebusConfig = Configure.With(new CastleWindsorContainerAdapter(IocManager.IocContainer)); if (moduleConfig.MessageAuditingEnabled) { rebusConfig.Options(o => o.EnableMessageAuditing(moduleConfig.MessageAuditingQueueName)); } if (moduleConfig.LoggingConfigurer != null) { rebusConfig.Logging(moduleConfig.LoggingConfigurer); } //https://github.com/rebus-org/Rebus.RabbitMq/tree/master/Rebus.RabbitMq/Config more option about RabbitMqOptionsBuilder _bus = rebusConfig.Transport(t => t.UseRabbitMqAsOneWayClient(moduleConfig.ConnectionString)) .Start(); } } public override void Shutdown() { if (_bus != null) { _bus.Dispose(); } } } } ================================================ FILE: src/Abplus.MqMessages.RebusRabbitMqPublisher/MqMessages/Publishers/RebusRabbitMqPublisherModuleConfig.cs ================================================ using System; using Rebus.Config; namespace Abp.MqMessages.Publishers { public class RebusRabbitMqPublisherModuleConfig : IRebusRabbitMqPublisherModuleConfig { public RebusRabbitMqPublisherModuleConfig() { Enabled = true; MessageAuditingEnabled = false; } public string ConnectionString { get; private set; } public bool Enabled { get; private set; } public Action LoggingConfigurer { get; private set; } public bool MessageAuditingEnabled { get; private set; } public string MessageAuditingQueueName { get; private set; } public IRebusRabbitMqPublisherModuleConfig ConnectTo(string connectionString) { ConnectionString = connectionString; return this; } public IRebusRabbitMqPublisherModuleConfig Enable(bool enabled) { Enabled = enabled; return this; } public IRebusRabbitMqPublisherModuleConfig EnableMessageAuditing(string messageAuditingQueueName) { MessageAuditingEnabled = true; MessageAuditingQueueName = messageAuditingQueueName; return this; } public IRebusRabbitMqPublisherModuleConfig UseLogging(Action loggingConfigurer) { LoggingConfigurer = loggingConfigurer; return this; } } } ================================================ FILE: src/Abplus.MqMessages.RedisStoreMessageTracker/Abplus.MqMessages.RedisStoreMessageTracker.csproj ================================================  net5.0 Abp ================================================ FILE: src/Abplus.MqMessages.RedisStoreMessageTracker/Abplus.MqMessages.RedisStoreMessageTracker.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.MqMessages.RedisStoreMessageTracker/MqMessages/MessageTrackers/RedisStoreMessageTracker.cs ================================================ using System; using System.Threading.Tasks; using Abp.Extensions; using Abp.Runtime.Caching; namespace Abp.MqMessages.MessageTrackers { public class RedisStoreMessageTracker : IMessageTracker { private const string CacheKey = "Abplus.MqMessages.MessageTrackers.RedisStoreMessageTracker"; private readonly ICacheManager _cacheManager; public RedisStoreMessageTracker(ICacheManager cacheManager) { _cacheManager = cacheManager; } public async Task HasProcessed(string processId) { var value = await _cacheManager.GetCache(CacheKey).GetOrDefaultAsync(processId); return !value.IsNullOrWhiteSpace(); } public async Task MarkAsProcessed(string processId) { await _cacheManager.GetCache(CacheKey).SetAsync(processId, "1", TimeSpan.FromDays(30)); } } } ================================================ FILE: src/Abplus.MqMessages.RedisStoreMessageTracker/MqMessages/MessageTrackers/RedisStoreMessageTrackerModule.cs ================================================ using Abp.Modules; using Abp.Runtime.Caching.Redis; namespace Abp.MqMessages.MessageTrackers { [DependsOn(typeof(AbpRedisCacheModule))] public class RedisStoreMessageTrackerModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { //IocManager.RegisterIfNot(DependencyLifeStyle.Singleton); //IocManager.RegisterIfNot(DependencyLifeStyle.Singleton); } } } ================================================ FILE: src/Abplus.T4.PermissionsFromJson/Abplus.T4.PermissionsFromJson.csproj ================================================  net5.0 Abp TextTemplatingFileGenerator ================================================ FILE: src/Abplus.T4.PermissionsFromJson/Abplus.T4.PermissionsFromJson.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2018 ================================================ FILE: src/Abplus.T4.PermissionsFromJson/Authorization/Builders/BuilderUtils.cs ================================================ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Dynamic; using System.Reflection; using Abp.Authorization; using Abp.Localization; using Abp.MultiTenancy; using Newtonsoft.Json; namespace 【YourCompany.YourProject】.Authorization { public static class BuilderUtils { public static void Build(IPermissionDefinitionContext context, string name) { var asm = Assembly.GetExecutingAssembly();//读取嵌入式资源 var sm = asm.GetManifestResourceStream("【YourCompany.YourProject】.Authorization.Builders.Permissions." + name + ".json"); var list = GetPermissionJson(sm); foreach (var item in list) { var module = context.CreatePermission( item.Name, new FixedLocalizableString(item.DisplayName), multiTenancySides: item.GetMultiTenancySides()); var children = item.GetChildren(); BuildChildrenPermission(children, module, item.Name); } } //供t4调用 public static Dictionary> GeneratePermission() { var dic = new Dictionary>(); var asm = Assembly.GetExecutingAssembly();//读取嵌入式资源 var jsons = asm.GetManifestResourceNames() .Where(c => c.StartsWith("【YourCompany.YourProject】.Authorization.Builders.Permissions") && c.EndsWith(".json")); foreach (var item in jsons) { var name = item.Replace("【YourCompany.YourProject】.Authorization.Builders.Permissions.", "") .Replace(".json", ""); var sm = asm.GetManifestResourceStream(item); var list = BuildPermissionConst(GetPermissionJson(sm)); dic.Add(name, list); } return dic; } private static List GetPermissionJson(Stream sm) { using (var reader = new StreamReader(sm)) { string text = reader.ReadToEnd(); var json = JsonConvert.DeserializeObject>(text).OrderBy(c => c.Order).ToList(); return json; } } private static void BuildChildrenPermission(List children, Permission module, string parentName) { foreach (var item in children) { var name = $"{parentName}.{item.Name}"; var itemModule = module.CreateChildPermission(name, new FixedLocalizableString(item.DisplayName), multiTenancySides: item.GetMultiTenancySides()); var itemchildren = item.GetChildren(); if (itemchildren.Any()) { BuildChildrenPermission(itemchildren, itemModule, name); } } } private static List BuildPermissionConst(List permissionJsons, string name = null, string value = null, string summary = null, List permissionConsts = null) { permissionConsts = permissionConsts ?? new List(); foreach (var item in permissionJsons) { var permissionConst = new PermissionConst { Summary = $"{summary}_{item.DisplayName}".Trim('_'), Name = $"{name}_{item.Name}".Trim('_').Replace('.', '_'), Value = $"{value}.{item.Name}".Trim('.').Replace('_', '.') }; permissionConsts.Add(permissionConst); var children = item.GetChildren(); if (children.Any()) { BuildPermissionConst(children, permissionConst.Name, permissionConst.Value, permissionConst.Summary, permissionConsts); } } return permissionConsts; } } public class PermissionJson { public PermissionJson() { Order = 100; } public string Name { get; set; } public string DisplayName { get; set; } public string Description { get; set; } [JsonProperty(PropertyName = "multiTenancySides")] public MultiTenancySides? MultiTenancySide { private get; set; } public bool DefaultPermission { private get; set; } public List Children { private get; set; } public int Order { get; set; } public List DisableOrder { get; set; } public List GetChildren() { Children = Children ?? new List(); DisableOrder = DisableOrder ?? new List(); if (DefaultPermission) { Children.Add(new PermissionJson { Name = "Create", DisplayName = "新增", Order = 10, DefaultPermission = false }); Children.Add(new PermissionJson { Name = "Edit", DisplayName = "编辑", Order = 20, DefaultPermission = false }); Children.Add(new PermissionJson { Name = "Delete", DisplayName = "删除", Order = 30, DefaultPermission = false }); } if (MultiTenancySide.HasValue) { Children.ForEach(c => { c.MultiTenancySide = MultiTenancySide.Value; }); } return Children.OrderBy(c => c.Order).Where(c => !DisableOrder.Contains(c.Order)).ToList(); } public MultiTenancySides GetMultiTenancySides() { if (MultiTenancySide.HasValue) { return MultiTenancySide.Value; } return MultiTenancySides.Tenant | MultiTenancySides.Host; } } public class PermissionConst { public string Summary { get; set; } public string Name { get; set; } public string Value { get; set; } } } ================================================ FILE: src/Abplus.T4.PermissionsFromJson/Authorization/Builders/PermissionBuilder.cs ================================================ ================================================ FILE: src/Abplus.T4.PermissionsFromJson/Authorization/Builders/PermissionBuilder.tt ================================================ <#@ template debug="false" hostspecific="true" language="C#" #> <#@ include file="T4MultipleOutputManager.ttinclude" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.IO" #> <#@ assembly name="$(SolutionDir)packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll" #> <#@ assembly name="$(ProjectDir)bin\$(ConfigurationName)\【YourCompany.YourProject】.Core.dll" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="Newtonsoft.Json" #> <#@ import namespace="Newtonsoft.Json.Linq" #> <#@ import namespace="System.Globalization" #> <#@ import namespace="【YourCompany.YourProject】.Authorization" #> <#@ output extension=".cs" #> <# var tempateManager = Manager.Create(Host,GenerationEnvironment); string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)"); string projectPath = Host.ResolveAssemblyReference("$(ProjectDir)"); var dic = BuilderUtils.GeneratePermission(); foreach(var item in dic) { var list= item.Value; tempateManager.StartNewFile(item.Key+"Permissions.cs"); #> namespace 【YourCompany.YourProject】.Authorization { /// /// Permissions definition /// public static class <#=item.Key #>Permissions { <# foreach(var item1 in list){ #> /// /// <#=item1.Summary #> /// public const string <#=item1.Name #> = "<#=item1.Value #>"; <# } #> } } <# } tempateManager.EndBlock(); tempateManager.Process(true); #> ================================================ FILE: src/Abplus.T4.PermissionsFromJson/Authorization/Builders/Permissions/Sample.json ================================================ [ { "name": "User", "displayName": "用户中心", "children": [ { "name": "UserInfo", "displayName": "用户管理", "defaultPermission": false }, { "name": "UserIdCard", "displayName": "身份信息管理", "defaultPermission": false, "children": [ { "name": "Reviewed", "displayName": "审核/编辑" } ] } ] } ] ================================================ FILE: src/Abplus.T4.PermissionsFromJson/Authorization/Builders/T4MultipleOutputManager.ttinclude ================================================ <#@ assembly name="System.Core" #><#@ assembly name="System.Data.Linq" #><#@ assembly name="EnvDTE" #><#@ assembly name="System.Xml" #><#@ assembly name="System.Xml.Linq" #><#@ import namespace="System.Collections.Generic" #><#@ import namespace="System.IO" #><#@ import namespace="System.Text" #><#@ import namespace="Microsoft.VisualStudio.TextTemplating" #><#+ // https://raw.github.com/damieng/DamienGKit // http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited // Manager class records the various blocks so it can split them up class Manager { private class Block { public String Name; public int Start, Length; public bool IncludeInDefault; } private Block currentBlock; private readonly List files = new List(); private readonly Block footer = new Block(); private readonly Block header = new Block(); private readonly ITextTemplatingEngineHost host; private readonly StringBuilder template; protected readonly List generatedFileNames = new List(); public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) { return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template); } public void StartNewFile(String name) { if (name == null) throw new ArgumentNullException("name"); CurrentBlock = new Block { Name = name }; } public void StartFooter(bool includeInDefault=true) { CurrentBlock = footer; footer.IncludeInDefault = includeInDefault; } public void StartHeader(bool includeInDefault=true) { CurrentBlock = header; header.IncludeInDefault = includeInDefault; } public void EndBlock() { if (CurrentBlock == null) return; CurrentBlock.Length = template.Length - CurrentBlock.Start; if (CurrentBlock != header && CurrentBlock != footer) files.Add(CurrentBlock); currentBlock = null; } public virtual void Process(bool split, bool sync =true) { if (split) { EndBlock(); String headerText = template.ToString(header.Start, header.Length); String footerText = template.ToString(footer.Start, footer.Length); String outputPath = Path.GetDirectoryName(host.TemplateFile); files.Reverse(); if (!footer.IncludeInDefault) template.Remove(footer.Start, footer.Length); foreach(Block block in files) { String fileName = Path.Combine(outputPath, block.Name); String content = headerText + template.ToString(block.Start, block.Length) + footerText; generatedFileNames.Add(fileName); CreateFile(fileName, content); template.Remove(block.Start, block.Length); } if (!header.IncludeInDefault) template.Remove(header.Start, header.Length); } } protected virtual void CreateFile(String fileName, String content) { if (IsFileContentDifferent(fileName, content)) File.WriteAllText(fileName, content); } public virtual String GetCustomToolNamespace(String fileName) { return null; } public virtual String DefaultProjectNamespace { get { return null; } } protected bool IsFileContentDifferent(String fileName, String newContent) { return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); } private Manager(ITextTemplatingEngineHost host, StringBuilder template) { this.host = host; this.template = template; } private Block CurrentBlock { get { return currentBlock; } set { if (CurrentBlock != null) EndBlock(); if (value != null) value.Start = template.Length; currentBlock = value; } } private class VSManager: Manager { private readonly EnvDTE.ProjectItem templateProjectItem; private readonly EnvDTE.DTE dte; private readonly Action checkOutAction; private readonly Action> projectSyncAction; public override String DefaultProjectNamespace { get { return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString(); } } public override String GetCustomToolNamespace(string fileName) { return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString(); } public override void Process(bool split, bool sync) { if (templateProjectItem.ProjectItems == null) return; base.Process(split, sync); if (sync) projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); } protected override void CreateFile(String fileName, String content) { if (IsFileContentDifferent(fileName, content)) { CheckoutFileIfRequired(fileName); File.WriteAllText(fileName, content); } } internal VSManager(ITextTemplatingEngineHost host, StringBuilder template) : base(host, template) { var hostServiceProvider = (IServiceProvider)host; if (hostServiceProvider == null) throw new ArgumentNullException("Could not obtain IServiceProvider"); dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); if (dte == null) throw new ArgumentNullException("Could not obtain DTE from host"); templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile); checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); } private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, List keepFileNames) { var keepFileNameSet = new HashSet(keepFileNames); var projectFiles = new Dictionary(); var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]) + "."; foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) projectFiles.Add(projectItem.FileNames[0], projectItem); // Remove unused items from the project foreach (var pair in projectFiles) if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix)) pair.Value.Delete(); // Add missing files to the project foreach(String fileName in keepFileNameSet) if (!projectFiles.ContainsKey(fileName)) templateProjectItem.ProjectItems.AddFromFile(fileName); } private void CheckoutFileIfRequired(String fileName) { var sc = dte.SourceControl; if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName)) checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); } } } #> ================================================ FILE: src/Samples/AuditingConsumer/Sample.AuditingConsumerHandler/Program.cs ================================================ using System; namespace Sample.AuditingConsumerHandler { class Program { static void Main(string[] args) { var bs = new SampleAuditingConsumerHandlerBootstrap(); bs.Start(); Console.ReadLine(); } } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.AuditingConsumerHandler/Sample.AuditingConsumerHandler.csproj ================================================ Exe net5.0 ================================================ FILE: src/Samples/AuditingConsumer/Sample.AuditingConsumerHandler/SampleAuditingConsumerHandlerBootstrap.cs ================================================ using Abp; namespace Sample.AuditingConsumerHandler { public class SampleAuditingConsumerHandlerBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.AuditingConsumerHandler/SampleAuditingConsumerHandlerModule.cs ================================================ using Abp.Auditing.AuditingStore; using Abp.Configuration.Startup; using Abp.Json; using Abp.Modules; using Abp.MqMessages.Consumers; using System; using System.Collections.Generic; using System.IO; using System.Reflection; namespace Sample.AuditingConsumerHandler { [DependsOn( typeof(RebusRabbitMqConsumerModule) , typeof(AuditingConsumerRebusHandlerModule))] public class SampleAuditingConsumerHandlerModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAbplusRebusRabbitMqConsumer() .UseLogging(c => c.ColoredConsole()) .ConnectTo("amqp://dev:dev@rabbitmq.local.abplus.cn/")//set your own connection string of rabbitmq .UseQueue(Assembly.GetExecutingAssembly().GetName().Name)//TODO@personball 需要开放更多队列选项,比如审计日志队列对可靠性要求不用很高,通过禁用队列持久化以提升消息发布速度 .Prefetch(100)//用于控制每次拉取的资源消耗(内存,带宽),消费速度还要看消费端自己的消息处理速度 .RegisterHandlerInAssemblys(Assembly.GetAssembly(typeof(AuditingConsumerRebusHandlerModule)));//注册AuditingConsumerRebusHandler Configuration.Modules.AuditingConsumer() .EveryPeriodIn(TimeSpan.FromMilliseconds(100))//每隔多久调用一次Do .Batch(100)//请实际测试审计消息的产生速度和消费速度,适当调节Prefetch、EveryPeriodIn以及Batch,以免消费端发生消息堆积导致内存溢出 .Do(async (messageList) => { var lines = new List(); foreach (var message in messageList) { lines.Add(message.ToJsonString()); } await File.AppendAllLinesAsync(AppDomain.CurrentDomain.BaseDirectory + "\\messages.txt", lines); }); } public override void Initialize() { base.Initialize(); } public override void PostInitialize() { //Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); } } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.MqMessageAuditingStore/Application/ITestAuditingStoreAppService.cs ================================================ using Abp.Application.Services; using System.Threading.Tasks; namespace Sample.MqMessageAuditingStore.Application { public interface ITestAuditingStoreAppService : IApplicationService { Task TestAuditing(TestAuditingInput input); } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.MqMessageAuditingStore/Application/TestAuditingInput.cs ================================================ namespace Sample.MqMessageAuditingStore.Application { public class TestAuditingInput { public string Name { get; set; } public string Value { get; set; } } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.MqMessageAuditingStore/Application/TestAuditingStoreAppService.cs ================================================ using System; using System.Threading.Tasks; using Abp.Json; namespace Sample.MqMessageAuditingStore.Application { public class TestAuditingStoreAppService : ITestAuditingStoreAppService { public Task TestAuditing(TestAuditingInput input) { Console.WriteLine(input.ToJsonString()); return Task.FromResult(0); } } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.MqMessageAuditingStore/BackgroudWorker/TestWorker.cs ================================================ using Abp.Dependency; using Abp.Threading; using Abp.Threading.BackgroundWorkers; using Abp.Threading.Timers; using Sample.MqMessageAuditingStore.Application; using System; namespace Sample.MqMessageAuditingStore.BackgroudWorker { public class TestWorker : PeriodicBackgroundWorkerBase, ISingletonDependency { private readonly ITestAuditingStoreAppService _testApp; public TestWorker(AbpTimer timer, ITestAuditingStoreAppService testAuditingStoreAppService) : base(timer) { _testApp = testAuditingStoreAppService; Timer.Period = 1 * 1000;//1 seconds Timer.RunOnStart = true; } protected override void DoWork() { AsyncHelper.RunSync(() => _testApp.TestAuditing(new TestAuditingInput { Name = "Invoke Time", Value = DateTime.Now.ToLongTimeString() })); } } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.MqMessageAuditingStore/Program.cs ================================================ using System; namespace Sample.MqMessageAuditingStore { class Program { static void Main(string[] args) { var bs = new SampleMqMessageAuditingStoreBootstrap(); bs.Start(); Console.ReadLine(); } } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.MqMessageAuditingStore/Sample.MqMessageAuditingStore.csproj ================================================ Exe net5.0 ================================================ FILE: src/Samples/AuditingConsumer/Sample.MqMessageAuditingStore/SampleMqMessageAuditingStoreBootstrap.cs ================================================ using Abp; namespace Sample.MqMessageAuditingStore { public class SampleMqMessageAuditingStoreBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/AuditingConsumer/Sample.MqMessageAuditingStore/SampleMqMessageAuditingStoreModule.cs ================================================ using Abp.Auditing.AuditingStores; using Abp.Configuration.Startup; using Abp.Modules; using Abp.MqMessages.Publishers; using Abp.Threading.BackgroundWorkers; using Sample.MqMessageAuditingStore.BackgroudWorker; using System.Reflection; namespace Sample.MqMessageAuditingStore { [DependsOn( typeof(RebusRabbitMqPublisherModule)//依赖消息发布机制 , typeof(MqMessageAuditingStoreModule))]//加上模块依赖即可替换默认的审计日志存储机制 public class SampleMqMessageAuditingStoreModule : AbpModule { public override void PreInitialize() { //消息发布配置 Configuration.Modules.UseAbplusRebusRabbitMqPublisher() .UseLogging(c => c.ColoredConsole()) .ConnectTo("amqp://dev:dev@rabbitmq.local.abplus.cn/");//set your own connection string of rabbitmq Configuration.BackgroundJobs.IsJobExecutionEnabled = true; Configuration.Auditing.IsEnabled = true; Configuration.Auditing.IsEnabledForAnonymousUsers = true;//开启匿名审计,TestAuditingStoreAppService没有要求用户认证 } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { //Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); var workManager = IocManager.Resolve(); workManager.Add(IocManager.Resolve());//为了demo项目足够小,都用console中的worker进行演示,在mvc项目中使用ApplicationService效果相同 } } } ================================================ FILE: src/Samples/FileStorage/Sample.AliyunOSSStorage/BackgroundWorker/TestWorker.cs ================================================ using System; using System.IO; using Abp.Dependency; using Abp.IO; using Abp.Threading; using Abp.Threading.BackgroundWorkers; using Abp.Threading.Timers; namespace Sample.AliyunOSSStorage.BackgroundWorker { public class TestWorker : PeriodicBackgroundWorkerBase, ISingletonDependency { private readonly IFileStorage _fileStorage; public TestWorker(AbpTimer timer, IFileStorage fileStorage) : base(timer) { _fileStorage = fileStorage; Timer.Period = 3000;//300 seconds Timer.RunOnStart = true; } protected override void DoWork() { var file = File.ReadAllBytes("plane.jpg"); var newName = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg"; var url = AsyncHelper.RunSync(() => _fileStorage.Save(file, newName, "canteen/product")); Console.WriteLine(url); var bytesFromAzure = AsyncHelper.RunSync(() => _fileStorage.ReadAsBytes(newName, "canteen/product")); File.WriteAllBytes(newName, bytesFromAzure); AsyncHelper.RunSync(() => _fileStorage.Delete(newName, "canteen/product")); using (var fs = new FileStream("plane.jpg", FileMode.Open)) { var sName = $"{newName}-as-stream.jpg"; var url2 = AsyncHelper.RunSync(() => _fileStorage.Save(fs, sName, "canteen/product")); } } } } ================================================ FILE: src/Samples/FileStorage/Sample.AliyunOSSStorage/Program.cs ================================================ using System; namespace Sample.AliyunOSSStorage { class Program { static void Main(string[] args) { //As Topshelf not support dotnet core yet, just simple run below code for a sample. var bs = new SampleAliyunOSSStorageBootstrap(); bs.Start(); Console.ReadLine(); } } } ================================================ FILE: src/Samples/FileStorage/Sample.AliyunOSSStorage/Sample.AliyunOSSStorageConsole.csproj ================================================  Exe net5.0 Sample.AliyunOSSStorage PreserveNewest ================================================ FILE: src/Samples/FileStorage/Sample.AliyunOSSStorage/SampleAliyunOSSStorageBootstrap.cs ================================================ using Abp; namespace Sample.AliyunOSSStorage { internal class SampleAliyunOSSStorageBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/FileStorage/Sample.AliyunOSSStorage/SampleAliyunOSSStorageModule.cs ================================================ using System.Reflection; using Abp.IO.AliyunOSSStorage; using Abp.Modules; using Abp.Configuration.Startup; using Abp.Threading.BackgroundWorkers; using Sample.AliyunOSSStorage.BackgroundWorker; namespace Sample.AliyunOSSStorage { [DependsOn(typeof(AliyunOSSStorageModule))] public class SampleAliyunOSSStorageModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAliyunOSSStorage() .SetAccessKeyId("") .SetAccessKeySecret("") .SetBucketName("xxxxx") .SetEndpoint("oss-cn-hangzhou.aliyuncs.com") .WithUriPrefix("https://xxxxx.oss-cn-hangzhou.aliyuncs.com"); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { //Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); var workManager = IocManager.Resolve(); workManager.Add(IocManager.Resolve()); } } } ================================================ FILE: src/Samples/FileStorage/Sample.AzureBlobStorage/BackgroundWorker/TestWorker.cs ================================================ using System; using System.IO; using Abp.Dependency; using Abp.IO; using Abp.Threading; using Abp.Threading.BackgroundWorkers; using Abp.Threading.Timers; namespace Sample.AzureBlobStorage.BackgroundWorker { public class TestWorker : PeriodicBackgroundWorkerBase, ISingletonDependency { private readonly IFileStorage _fileStorage; public TestWorker(AbpTimer timer, IFileStorage fileStorage) : base(timer) { _fileStorage = fileStorage; Timer.Period = 300 * 1000;//300 seconds Timer.RunOnStart = true; } protected override void DoWork() { var file = File.ReadAllBytes("plane.jpg"); var newName = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg"; var url = AsyncHelper.RunSync(() => _fileStorage.Save(file, newName, "test")); Console.WriteLine(url); var bytesFromAzure = AsyncHelper.RunSync(() => _fileStorage.ReadAsBytes(newName, "test")); File.WriteAllBytes(newName, bytesFromAzure); AsyncHelper.RunSync(() => _fileStorage.Delete(newName, "test")); using (var fs = new FileStream("plane.jpg", FileMode.Open)) { var sName = $"{newName}-as-stream.jpg"; var url2 = AsyncHelper.RunSync(() => _fileStorage.Save(fs, sName, "test")); } } } } ================================================ FILE: src/Samples/FileStorage/Sample.AzureBlobStorage/Program.cs ================================================ using System; namespace Sample.AzureBlobStorage { class Program { static void Main(string[] args) { //As Topshelf not support dotnet core yet, just simple run below code for a sample. var bs = new SampleAzureBlobStorageBootstrap(); bs.Start(); Console.ReadLine(); } } } ================================================ FILE: src/Samples/FileStorage/Sample.AzureBlobStorage/Sample.AzureBlobStorageConsole.csproj ================================================ Exe net5.0 Sample.AzureBlobStorage PreserveNewest ================================================ FILE: src/Samples/FileStorage/Sample.AzureBlobStorage/SampleAzureBlobStorageBootstrap.cs ================================================ using Abp; namespace Sample.AzureBlobStorage { internal class SampleAzureBlobStorageBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/FileStorage/Sample.AzureBlobStorage/SampleAzureBlobStorageModule.cs ================================================ using System.Reflection; using Abp.Configuration.Startup; using Abp.IO.AzureBlobStorage; using Abp.Modules; using Abp.Threading.BackgroundWorkers; using Sample.AzureBlobStorage.BackgroundWorker; namespace Sample.AzureBlobStorage { [DependsOn(typeof(AzureBlobFileStorageModule))] public class SampleAzureBlobStorageModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAzureBlobFileStorage() .ConfigAzureStorage() .SetAccountName("") .SetAccountKey("") .SetContainer("images") .UseEndpointSuffix("core.chinacloudapi.cn"); //Configuration.Modules.UseAzureBlobFileStorage() // .ConfigAzureStorageUseSettingManager(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { //Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); var workManager = IocManager.Resolve(); workManager.Add(IocManager.Resolve()); } } } ================================================ FILE: src/Samples/FileStorage/Sample.LocalFileSystem/Program.cs ================================================ using System; namespace Sample.LocalFileSystem { class Program { static void Main(string[] args) { //As Topshelf not support dotnet core yet, just simple run below code for a sample. var bs = new SampleLocalFileSystemBootstrap(); bs.Start(); Console.ReadLine(); } } } ================================================ FILE: src/Samples/FileStorage/Sample.LocalFileSystem/Sample.LocalFileSystemConsole.csproj ================================================ Exe net5.0 Sample.LocalFileSystem ================================================ FILE: src/Samples/FileStorage/Sample.LocalFileSystem/SampleLocalFileSystemBootstrap.cs ================================================ using Abp; namespace Sample.LocalFileSystem { internal class SampleLocalFileSystemBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/FileStorage/Sample.LocalFileSystem/SampleLocalFileSystemModule.cs ================================================ using System.Reflection; using Abp.IO.LocalFileSystem; using Abp.Modules; namespace Sample.LocalFileSystem { [DependsOn(typeof(LocalFileSystemStorageModule))] internal class SampleLocalFileSystemModule : AbpModule { public override void PreInitialize() { } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { //Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); //var workManager = IocManager.Resolve(); //workManager.Add(IocManager.Resolve()); } } } ================================================ FILE: src/Samples/Sample.DotNetCoreConsumerHost/Handlers/TestHandler.cs ================================================ using Abp.MqMessages; using Castle.Core.Logging; using Rebus.Handlers; using System.Threading.Tasks; namespace Sample.DotNetCoreConsumerHost.Handlers { public class TestHandler : IHandleMessages { public ILogger Logger { get; set; } public IMqMessagePublisher Publisher { get; set; } public TestHandler() { Publisher = NullMqMessagePublisher.Instance; Logger = NullLogger.Instance; } public async Task Handle(TestMessage message) { var msg = $"{Logger.GetType()}:{message.Value},{message.Time}"; Logger.Debug(msg); //await Publisher.PublishAsync(msg);//send it again! } } } ================================================ FILE: src/Samples/Sample.DotNetCoreConsumerHost/Program.cs ================================================ using System; namespace Sample.DotNetCoreConsumerHost { class Program { static void Main(string[] args) { var bs = new SampleConsumerHostBootstrap(); bs.Start(); Console.ReadLine(); } } } ================================================ FILE: src/Samples/Sample.DotNetCoreConsumerHost/Sample.DotNetCoreConsumerHost.csproj ================================================ Exe net5.0 ================================================ FILE: src/Samples/Sample.DotNetCoreConsumerHost/SampleConsumerHostBootstrap.cs ================================================ using Abp; namespace Sample.DotNetCoreConsumerHost { public class SampleConsumerHostBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/Sample.DotNetCoreConsumerHost/SampleConsumerHostModule.cs ================================================ using Abp.Configuration.Startup; using Abp.Modules; using Abp.MqMessages.Consumers; using System.Reflection; namespace Sample.DotNetCoreConsumerHost { [DependsOn(typeof(RebusRabbitMqConsumerModule))] public class SampleConsumerHostModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAbplusRebusRabbitMqConsumer() .UseLogging(c => c.ColoredConsole()) .ConnectTo("amqp://dev:dev@rabbitmq.local.abplus.cn/")//set your own connection string of rabbitmq .UseQueue(Assembly.GetExecutingAssembly().GetName().Name) .Prefetch(100)//用于控制每次拉取的资源消耗(内存,带宽),消费速度还要看消费端自己的消息处理速度 .RegisterHandlerInAssemblys(Assembly.GetExecutingAssembly()); } public override void Initialize() { base.Initialize(); } public override void PostInitialize() { //Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); } } } ================================================ FILE: src/Samples/Sample.DotNetCorePublisherHost/BackgroundWorker/TestWorker.cs ================================================ using Abp.Dependency; using Abp.MqMessages; using Abp.Threading.BackgroundWorkers; using Abp.Threading.Timers; using System; namespace Sample.DotNetCorePublisherHost.BackgroundWorker { public class TestWorker : PeriodicBackgroundWorkerBase, ISingletonDependency { private readonly IMqMessagePublisher _publisher; public TestWorker(AbpTimer timer, IMqMessagePublisher publisher) : base(timer) { _publisher = publisher; Timer.Period = 1 * 1000;//3 seconds Timer.RunOnStart = true; } protected override void DoWork() { Logger.Info($"TestWork Done! Time:{DateTime.Now}"); _publisher.Publish(new TestMessage { Value = "TestWork from DotNetCoreHost:BlaBlaBlaBlaBlaBla", Time = DateTime.Now }); } } } ================================================ FILE: src/Samples/Sample.DotNetCorePublisherHost/Program.cs ================================================ using System; namespace Sample.DotNetCorePublisherHost { class Program { static void Main() { //As Topshelf not support dotnet core yet, just simple run below code for a sample. var bs = new SamplePublisherHostBootstrap(); bs.Start(); Console.ReadLine(); } } } ================================================ FILE: src/Samples/Sample.DotNetCorePublisherHost/Sample.DotNetCorePublisherHost.csproj ================================================  Exe net5.0 ================================================ FILE: src/Samples/Sample.DotNetCorePublisherHost/SamplePublisherHostBootstrap.cs ================================================ using Abp; namespace Sample.DotNetCorePublisherHost { public class SamplePublisherHostBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/Sample.DotNetCorePublisherHost/SamplePublisherHostModule.cs ================================================ using Abp.Configuration.Startup; using Abp.Modules; using Abp.MqMessages.Publishers; using Abp.Threading.BackgroundWorkers; using Sample.DotNetCorePublisherHost.BackgroundWorker; using System.Reflection; namespace Sample.DotNetCorePublisherHost { [DependsOn(typeof(RebusRabbitMqPublisherModule))] public class SamplePublisherHostModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAbplusRebusRabbitMqPublisher() .UseLogging(c => c.ColoredConsole()) .ConnectTo("amqp://dev:dev@rabbitmq.local.abplus.cn/");//set your own connection string of rabbitmq Configuration.BackgroundJobs.IsJobExecutionEnabled = true; } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { //Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); var workManager = IocManager.Resolve(); workManager.Add(IocManager.Resolve()); } } } ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/App.config ================================================  ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/DotNetFxConsumerHostBootstrap.cs ================================================ using Abp; namespace Sample.DotNetFxConsumerHost { public class DotNetFxConsumerHostBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/DotNetFxConsumerHostModule.cs ================================================ using Abp.Configuration.Startup; using Abp.Modules; using Abp.MqMessages.Consumers; using Castle.Facilities.Logging; using Castle.Services.Logging.NLogIntegration; using System.Reflection; namespace Sample.DotNetFxConsumerHost { [DependsOn(typeof(RebusRabbitMqConsumerModule))] public class DotNetFxConsumerHostModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAbplusRebusRabbitMqConsumer() .UseLogging(c => c.ColoredConsole())//c.NLog() .ConnectTo("amqp://dev:dev@rabbitmq.local.abplus.cn/")//set your own connection string of rabbitmq .UseQueue(Assembly.GetExecutingAssembly().GetName().Name) .Prefetch(5)//用于控制每次拉取的资源消耗(内存,带宽),消费速度还要看消费端自己的消息处理速度 .RegisterHandlerInAssemblys(Assembly.GetExecutingAssembly()); } public override void Initialize() { base.Initialize(); } public override void PostInitialize() { Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); } } } ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/Handlers/TestHandler.cs ================================================ using Abp.MqMessages; using Castle.Core.Logging; using Rebus.Handlers; using System.Threading.Tasks; namespace Sample.DotNetFxConsumerHost.Handlers { public class TestHandler : IHandleMessages { public ILogger Logger { get; set; } public IMqMessagePublisher Publisher { get; set; } public TestHandler() { Publisher = NullMqMessagePublisher.Instance; Logger = NullLogger.Instance; } public async Task Handle(TestMessage message) { var msg = $"{Logger.GetType()}:{message.Value},{message.Time}"; Logger.Debug(msg); //await Publisher.PublishAsync(msg);//send it again! } } } ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/NLog.config ================================================ ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/NLog.xsd ================================================  Watch config file for changes and reload automatically. Print internal NLog messages to the console. Default value is: false Print internal NLog messages to the console error output. Default value is: false Write internal NLog messages to the specified file. Log level threshold for internal log messages. Default value is: Info. Global log level threshold for application log messages. Messages below this level won't be logged.. Throw an exception when there is an internal error. Default value is: false. Throw an exception when there is a configuration error. If not set, determined by throwExceptions. Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false. Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false. Write timestamps for internal NLog messages. Default value is: true. Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false. Perform mesage template parsing and formatting of LogEvent messages (true = Always, false = Never, empty = Auto Detect). Default value is: empty. Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes). Prefix for targets/layout renderers/filters/conditions loaded from this assembly. Load NLog extensions from the specified file (*.dll) Load NLog extensions from the specified assembly. Assembly name should be fully qualified. Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name* Comma separated list of levels that this rule matches. Minimum level that this rule matches. Maximum level that this rule matches. Level that this rule matches. Comma separated list of target names. Ignore further rules if this one matches. Enable or disable logging rule. Disabled rules are ignored. Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file. Ignore any errors in the include file. Variable name. Variable value. Name of the target. Number of log events that should be processed in a batch by the lazy writer thread. Limit of full s to write before yielding into Performance is better when writing many small batches, than writing a single large batch Action to be taken when the lazy writer thread request queue count exceeds the set limit. Limit on the number of requests in the lazy writer thread request queue. Time in milliseconds to sleep between batches. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Delay the flush until the LogEvent has been confirmed as written Condition expression. Log events who meet this condition will cause a flush on the wrapped target. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Number of log events to be buffered. Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes. Action to take if the buffer overflows. Indicates whether to use sliding timeout. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Encoding to be used. Instance of that is used to format log messages. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Action that should be taken if the will be more connections than . Maximum queue size. Maximum current connections. 0 = no maximum. Indicates whether to keep connection open whenever possible. Size of the connection cache (number of connections which are kept alive). Network address. Action that should be taken if the message is larger than maxMessageSize. NDLC item separator. NDC item separator. Indicates whether to include NLog-specific extensions to log4j schema. Indicates whether to include source info (file name and line number) in the information sent over the network. Indicates whether to include contents of the stack. Indicates whether to include stack contents. Indicates whether to include dictionary contents. Indicates whether to include dictionary contents. Indicates whether to include call site (class and method name) in the information sent over the network. Option to include all properties from the log events AppInfo field. By default it's the friendly name of the current AppDomain. Renderer for log4j:event logger-xml-attribute (Default ${logger}) Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Layout that should be use to calcuate the value for the parameter. Viewer parameter name. Name of the target. Text to be rendered. Header. Footer. Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) The encoding for writing messages to the . Indicates whether the error stream (stderr) should be used instead of the output stream (stdout). Indicates whether to use default row highlighting rules. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Condition that must be met in order to set the specified foreground and background color. Background color. Foreground color. Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used. Indicates whether to ignore case when comparing texts. Regular expression to be matched. You must specify either text or regex. Text to be matched. You must specify either text or regex. Indicates whether to match whole words only. Background color. Foreground color. Name of the target. Text to be rendered. Header. Footer. Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) The encoding for writing messages to the . Indicates whether to send the log messages to the standard error instead of the standard output. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this. Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string. Name of the database provider. Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string. Indicates whether to keep the database connection open between the log events. Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string. Name of the connection string (as specified in <connectionStrings> configuration section. Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase. Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string. Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Text of the SQL command to be run on each log level. Type of the SQL command to be run on each log level. Type of the command. Connection string to run the command against. If not provided, connection string from the target is used. Indicates whether to ignore failures. Command text. Layout that should be use to calcuate the value for the parameter. Database parameter name. Database parameter precision. Database parameter scale. Database parameter size. Name of the target. Text to be rendered. Header. Footer. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Layout that renders event Category. Optional entrytype. When not set, or when not convertable to then determined by Layout that renders event ID. Name of the Event Log to write to. This can be System, Application or any user-defined name. Name of the machine on which Event Log service is running. Maximum Event log size in kilobytes. If null, the value won't be set. Default is 512 Kilobytes as specified by Eventlog API Message length limit to write to the Event Log. Value to be used as the event Source. Action to take if the message is larger than the option. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Indicates whether to return to the first target after any successful write. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Text to be rendered. Header. Footer. File encoding. Line ending mode. Indicates whether to compress archive files into the zip archive format. Way file archives are numbered. Name of the file to be used for an archive. Is the an absolute or relative path? Indicates whether to automatically archive log files every time the specified time passes. Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose: Maximum number of archive files that should be kept. Indicates whether the footer should be written only when the file is archived. Maximum number of log filenames that should be stored as existing. Is the an absolute or relative path? Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation. Value indicationg whether file creation calls should be synchronized by a system global mutex. Indicates whether to replace file contents on each write instead of appending log message at the end. Indicates whether to write BOM (byte order mark) in created files Indicates whether to enable log file(s) to be deleted. Name of the file to write to. Value specifying the date format to use when archiving files. Indicates whether to archive old log file on startup. Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong. Indicates whether to create directories if they do not exist. Indicates whether to delete old log file on startup. File attributes (Windows only). Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Indicates whether concurrent writes to the log file by multiple processes on different network hosts. Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity. Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger). Indicates whether to keep log file open instead of opening and closing it on each logging event. Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write Indicates whether concurrent writes to the log file by multiple processes on the same host. Number of times the write is appended on the file before NLog discards the log message. Delay in milliseconds to wait before attempting to write to the file again. Log file buffer size in bytes. Maximum number of seconds before open files are flushed. If this number is negative or zero the files are not flushed by timer. Indicates whether to automatically flush the file buffers after each log message. Name of the target. Condition expression. Log events who meet this condition will be forwarded to the wrapped target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Windows domain name to change context to. Required impersonation level. Type of the logon provider. Logon Type. User account password. Indicates whether to revert to the credentials of the process instead of impersonating another user. Username to change context to. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Interval in which messages will be written up to the number of messages. Maximum allowed number of messages written per . Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Endpoint address. Name of the endpoint configuration in WCF configuration file. Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply) Client ID. Indicates whether to include per-event properties in the payload sent to the server. Indicates whether to use binary message encoding. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Layout that should be use to calculate the value for the parameter. Name of the parameter. Type of the parameter. Type of the parameter. Obsolete alias for Name of the target. Text to be rendered. Header. Footer. Indicates whether NewLine characters in the body should be replaced with tags. Priority used for sending mails. Encoding to be used for sending e-mail. BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). Indicates whether to add new lines between log entries. Indicates whether to send message as HTML instead of plain text. Sender's email address (e.g. joe@domain.com). Mail message body (repeated for each log message send in one mail). Mail subject. Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Indicates the SMTP client timeout. SMTP Server to be used for sending. SMTP Authentication mode. Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic"). Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic"). Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server. Port number that SMTP Server is listening on. Indicates whether the default Settings from System.Net.MailSettings should be used. Folder where applications save mail messages to be processed by the local SMTP server. Specifies how outgoing email messages will be handled. Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Class name. Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Encoding to be used. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Network address. Size of the connection cache (number of connections which are kept alive). Indicates whether to keep connection open whenever possible. Maximum current connections. 0 = no maximum. Maximum queue size. Action that should be taken if the will be more connections than . Action that should be taken if the message is larger than maxMessageSize. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Encoding to be used. Instance of that is used to format log messages. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Action that should be taken if the will be more connections than . Maximum queue size. Maximum current connections. 0 = no maximum. Indicates whether to keep connection open whenever possible. Size of the connection cache (number of connections which are kept alive). Network address. Action that should be taken if the message is larger than maxMessageSize. NDLC item separator. NDC item separator. Indicates whether to include NLog-specific extensions to log4j schema. Indicates whether to include source info (file name and line number) in the information sent over the network. Indicates whether to include contents of the stack. Indicates whether to include stack contents. Indicates whether to include dictionary contents. Indicates whether to include dictionary contents. Indicates whether to include call site (class and method name) in the information sent over the network. Option to include all properties from the log events AppInfo field. By default it's the friendly name of the current AppDomain. Renderer for log4j:event logger-xml-attribute (Default ${logger}) Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Indicates whether to perform layout calculation. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Indicates whether performance counter should be automatically created. Name of the performance counter category. Counter help text. Name of the performance counter. Performance counter type. The value by which to increment the counter. Performance counter instance name. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Default filter to be applied when no specific rule matches. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Condition to be tested. Resulting filter to be applied when the condition matches. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Number of times to repeat each log message. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Number of retries that should be attempted on the wrapped target in case of a failure. Time to wait between retries in milliseconds. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Always use independent of Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8. Web service method name. Only used with Soap. Web service namespace. Only used with Soap. Protocol to be used when calling web service. Custom proxy address, include port separated by a colon Encoding. Web service URL. Value whether escaping be done according to the old NLog style (Very non-standard) Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs) Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in parameters) Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see and ). (optional) root namespace of the XML document, if POST of XML document chosen. (see and ). Proxy configuration when calling web service Footer layout. Header layout. Body layout (can be repeated multiple times). Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom'). Column delimiter. Quote Character. Quoting mode. Indicates whether CVS should include header. Layout of the column. Name of the column. List of property names to exclude when is true Option to include all properties from the log event (as JSON) Indicates whether to include contents of the dictionary. Indicates whether to include contents of the dictionary. Option to render the empty object value {} Option to suppress the extra spaces in the output json How far should the JSON serializer follow object references before backing off Layout that will be rendered as the attribute's value. Name of the attribute. Determines wether or not this attribute will be Json encoded. Indicates whether to escape non-ascii characters Whether an attribute with empty value should be included in the output Footer layout. Header layout. Body layout (can be repeated multiple times). Option to include all properties from the log events Indicates whether to include contents of the dictionary. Indicates whether to include contents of the dictionary. Indicates whether to include contents of the stack. Indicates whether to include contents of the stack. Layout text. Action to be taken when filter matches. Condition expression. Action to be taken when filter matches. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Substring to be matched. Action to be taken when filter matches. String to compare the layout to. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Action to be taken when filter matches. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Substring to be matched. Action to be taken when filter matches. String to compare the layout to. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Action to be taken when filter matches. Default number of unique filter values to expect, will automatically increase if needed Applies the configured action to the initial logevent that starts the timeout period. Used to configure that it should ignore all events until timeout. Layout to be used to filter log messages. Max number of unique filter values to expect simultaneously Max length of filter values, will truncate if above limit How long before a filter expires, and logging is accepted again Default buffer size for the internal buffers Reuse internal buffers, and doesn't have to constantly allocate new buffers Append FilterCount to the when an event is no longer filtered Insert FilterCount value into when an event is no longer filtered ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/Program.cs ================================================ using System; using Topshelf; namespace Sample.DotNetFxConsumerHost { class Program { static int Main() { return (int)HostFactory.Run(x => { x.UseAssemblyInfoForServiceInfo(); x.Service(s => { s.ConstructUsing(() => new DotNetFxConsumerHostBootstrap()); s.WhenStarted(v => v.Start()); s.WhenStopped(v => v.Stop()); s.BeforeStartingService(_ => { Console.WriteLine("Processor is starting"); }); s.BeforeStoppingService(_ => { Console.WriteLine("Processor is stopping"); }); }); // x.StartAutomatically(); x.SetStartTimeout(TimeSpan.FromSeconds(10)); x.SetStopTimeout(TimeSpan.FromSeconds(10)); x.EnableServiceRecovery(r => { r.RestartService(1); //r.RunProgram(7, "ping google.com"); r.RestartComputer(5, "message"); r.OnCrashOnly(); r.SetResetPeriod(2); }); //x.AddCommandLineSwitch("throwonstart", v => throwOnStart = v); //x.AddCommandLineSwitch("throwonstop", v => throwOnStop = v); //x.AddCommandLineSwitch("throwunhandled", v => throwUnhandled = v); x.OnException((exception) => { }); }); } } } ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Sample.DotNetFxConsumerHost")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Sample.DotNetFxConsumerHost")] [assembly: AssemblyCopyright("Copyright © 2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // 将 ComVisible 设置为 false 会使此程序集中的类型 //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("dd5f675f-9bc4-49a9-8ddc-ea536ff0c0f7")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/Sample.DotNetFxConsumerHost.csproj ================================================  Debug AnyCPU {DD5F675F-9BC4-49A9-8DDC-EA536FF0C0F7} Exe Sample.DotNetFxConsumerHost Sample.DotNetFxConsumerHost v4.7.1 512 true true AnyCPU true full false bin\Debug\ DEBUG;TRACE prompt 4 AnyCPU pdbonly true bin\Release\ TRACE prompt 4 ..\..\..\packages\Abp.4.6.0\lib\netstandard2.0\Abp.dll ..\..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\..\packages\Castle.LoggingFacility.4.1.1\lib\net45\Castle.Facilities.Logging.dll ..\..\..\packages\Castle.Core-NLog.4.3.1\lib\net45\Castle.Services.Logging.NLogIntegration.dll ..\..\..\packages\Castle.Windsor.4.1.1\lib\net45\Castle.Windsor.dll ..\..\..\packages\JetBrains.Annotations.2018.3.0\lib\net20\JetBrains.Annotations.dll ..\..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.28\lib\net46\Microsoft.Diagnostics.Tracing.EventSource.dll ..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Caching.Memory.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Options.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\..\packages\Microsoft.Extensions.Primitives.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll ..\..\..\packages\Nito.AsyncEx.Context.5.0.0\lib\netstandard2.0\Nito.AsyncEx.Context.dll ..\..\..\packages\Nito.AsyncEx.Coordination.5.0.0\lib\netstandard2.0\Nito.AsyncEx.Coordination.dll ..\..\..\packages\Nito.AsyncEx.Tasks.5.0.0\lib\netstandard2.0\Nito.AsyncEx.Tasks.dll ..\..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\..\packages\Nito.Disposables.2.0.0\lib\netstandard2.0\Nito.Disposables.dll ..\..\..\packages\NLog.4.5.10\lib\net45\NLog.dll ..\..\..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll ..\..\..\packages\Rebus.4.2.1\lib\net45\Rebus.dll ..\..\..\packages\Rebus.Castle.Windsor.4.1.0\lib\net45\Rebus.CastleWindsor.dll ..\..\..\packages\Rebus.NLog.5.0.0\lib\net45\Rebus.NLog.dll ..\..\..\packages\Rebus.RabbitMq.4.4.2\lib\net452\Rebus.RabbitMq.dll ..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True True ..\..\..\packages\System.Linq.Dynamic.Core.1.0.10\lib\net46\System.Linq.Dynamic.Core.dll ..\..\..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll ..\..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True True ..\..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True True ..\..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True True ..\..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True True ..\..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True True ..\..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True True ..\..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\..\packages\TimeZoneConverter.3.1.0\lib\net471\TimeZoneConverter.dll ..\..\..\packages\Topshelf.4.1.0\lib\net452\Topshelf.dll Always Designer {d27e21c1-96c8-4eff-aa4d-43a8ed7cc40b} Abplus.MqMessages.RebusCore {e0e26a07-b7a6-41fd-ab74-1cfcb5191f94} Abplus.MqMessages.RebusRabbitMqConsumer {10c03a51-881c-4779-9b24-5bfce234c175} Abplus {d71b7fba-e998-4141-81e6-e319c3941659} Sample.MqMessages ================================================ FILE: src/Samples/Sample.DotNetFxConsumerHost/packages.config ================================================  ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/App.config ================================================  ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/BackgroundWorker/TestWorker.cs ================================================ using Abp.Dependency; using Abp.MqMessages; using Abp.Threading.BackgroundWorkers; using Abp.Threading.Timers; using System; namespace Sample.DotNetFxPublisherHost.BackgroundWorker { public class TestWorker : PeriodicBackgroundWorkerBase, ISingletonDependency { private readonly IMqMessagePublisher _publisher; public TestWorker(AbpTimer timer, IMqMessagePublisher publisher) : base(timer) { _publisher = publisher; Timer.Period = 1 * 1000;//3 seconds Timer.RunOnStart = true; } protected override void DoWork() { Logger.Info($"TestWork Done! Time:{DateTime.Now}"); _publisher.Publish(new TestMessage { Value = "TestWork from DotNetFxHost:BlaBlaBlaBlaBlaBla", Time = DateTime.Now }); } } } ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/DotNetFxPublisherHostBootstrap.cs ================================================ using Abp; namespace Sample.DotNetFxPublisherHost { public class DotNetFxPublisherHostBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/DotNetFxPublisherHostModule.cs ================================================ using Abp.Configuration.Startup; using Abp.Modules; using Abp.MqMessages.Publishers; using Abp.Threading.BackgroundWorkers; using Castle.Facilities.Logging; using Castle.Services.Logging.NLogIntegration; using Rebus.NLog.Config; using Sample.DotNetFxPublisherHost.BackgroundWorker; using System.Reflection; namespace Sample.DotNetFxPublisherHost { [DependsOn(typeof(RebusRabbitMqPublisherModule))] public class DotNetFxPublisherHostModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAbplusRebusRabbitMqPublisher() .UseLogging(c => c.ColoredConsole())//c.NLog() .ConnectTo("amqp://dev:dev@rabbitmq.local.abplus.cn/");//set your own connection string of rabbitmq Configuration.BackgroundJobs.IsJobExecutionEnabled = true; } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); var workManager = IocManager.Resolve(); workManager.Add(IocManager.Resolve()); } } } ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/NLog.config ================================================ ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/NLog.xsd ================================================  Watch config file for changes and reload automatically. Print internal NLog messages to the console. Default value is: false Print internal NLog messages to the console error output. Default value is: false Write internal NLog messages to the specified file. Log level threshold for internal log messages. Default value is: Info. Global log level threshold for application log messages. Messages below this level won't be logged.. Throw an exception when there is an internal error. Default value is: false. Throw an exception when there is a configuration error. If not set, determined by throwExceptions. Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false. Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false. Write timestamps for internal NLog messages. Default value is: true. Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false. Perform mesage template parsing and formatting of LogEvent messages (true = Always, false = Never, empty = Auto Detect). Default value is: empty. Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes). Prefix for targets/layout renderers/filters/conditions loaded from this assembly. Load NLog extensions from the specified file (*.dll) Load NLog extensions from the specified assembly. Assembly name should be fully qualified. Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name* Comma separated list of levels that this rule matches. Minimum level that this rule matches. Maximum level that this rule matches. Level that this rule matches. Comma separated list of target names. Ignore further rules if this one matches. Enable or disable logging rule. Disabled rules are ignored. Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file. Ignore any errors in the include file. Variable name. Variable value. Name of the target. Number of log events that should be processed in a batch by the lazy writer thread. Limit of full s to write before yielding into Performance is better when writing many small batches, than writing a single large batch Action to be taken when the lazy writer thread request queue count exceeds the set limit. Limit on the number of requests in the lazy writer thread request queue. Time in milliseconds to sleep between batches. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Delay the flush until the LogEvent has been confirmed as written Condition expression. Log events who meet this condition will cause a flush on the wrapped target. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Number of log events to be buffered. Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes. Action to take if the buffer overflows. Indicates whether to use sliding timeout. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Encoding to be used. Instance of that is used to format log messages. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Action that should be taken if the will be more connections than . Maximum queue size. Maximum current connections. 0 = no maximum. Indicates whether to keep connection open whenever possible. Size of the connection cache (number of connections which are kept alive). Network address. Action that should be taken if the message is larger than maxMessageSize. NDLC item separator. NDC item separator. Indicates whether to include NLog-specific extensions to log4j schema. Indicates whether to include source info (file name and line number) in the information sent over the network. Indicates whether to include contents of the stack. Indicates whether to include stack contents. Indicates whether to include dictionary contents. Indicates whether to include dictionary contents. Indicates whether to include call site (class and method name) in the information sent over the network. Option to include all properties from the log events AppInfo field. By default it's the friendly name of the current AppDomain. Renderer for log4j:event logger-xml-attribute (Default ${logger}) Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Layout that should be use to calcuate the value for the parameter. Viewer parameter name. Name of the target. Text to be rendered. Header. Footer. Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) The encoding for writing messages to the . Indicates whether the error stream (stderr) should be used instead of the output stream (stdout). Indicates whether to use default row highlighting rules. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Condition that must be met in order to set the specified foreground and background color. Background color. Foreground color. Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used. Indicates whether to ignore case when comparing texts. Regular expression to be matched. You must specify either text or regex. Text to be matched. You must specify either text or regex. Indicates whether to match whole words only. Background color. Foreground color. Name of the target. Text to be rendered. Header. Footer. Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) The encoding for writing messages to the . Indicates whether to send the log messages to the standard error instead of the standard output. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this. Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string. Name of the database provider. Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string. Indicates whether to keep the database connection open between the log events. Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string. Name of the connection string (as specified in <connectionStrings> configuration section. Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase. Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string. Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Text of the SQL command to be run on each log level. Type of the SQL command to be run on each log level. Type of the command. Connection string to run the command against. If not provided, connection string from the target is used. Indicates whether to ignore failures. Command text. Layout that should be use to calcuate the value for the parameter. Database parameter name. Database parameter precision. Database parameter scale. Database parameter size. Name of the target. Text to be rendered. Header. Footer. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Layout that renders event Category. Optional entrytype. When not set, or when not convertable to then determined by Layout that renders event ID. Name of the Event Log to write to. This can be System, Application or any user-defined name. Name of the machine on which Event Log service is running. Maximum Event log size in kilobytes. If null, the value won't be set. Default is 512 Kilobytes as specified by Eventlog API Message length limit to write to the Event Log. Value to be used as the event Source. Action to take if the message is larger than the option. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Indicates whether to return to the first target after any successful write. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Text to be rendered. Header. Footer. File encoding. Line ending mode. Indicates whether to compress archive files into the zip archive format. Way file archives are numbered. Name of the file to be used for an archive. Is the an absolute or relative path? Indicates whether to automatically archive log files every time the specified time passes. Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose: Maximum number of archive files that should be kept. Indicates whether the footer should be written only when the file is archived. Maximum number of log filenames that should be stored as existing. Is the an absolute or relative path? Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation. Value indicationg whether file creation calls should be synchronized by a system global mutex. Indicates whether to replace file contents on each write instead of appending log message at the end. Indicates whether to write BOM (byte order mark) in created files Indicates whether to enable log file(s) to be deleted. Name of the file to write to. Value specifying the date format to use when archiving files. Indicates whether to archive old log file on startup. Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong. Indicates whether to create directories if they do not exist. Indicates whether to delete old log file on startup. File attributes (Windows only). Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Indicates whether concurrent writes to the log file by multiple processes on different network hosts. Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity. Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger). Indicates whether to keep log file open instead of opening and closing it on each logging event. Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write Indicates whether concurrent writes to the log file by multiple processes on the same host. Number of times the write is appended on the file before NLog discards the log message. Delay in milliseconds to wait before attempting to write to the file again. Log file buffer size in bytes. Maximum number of seconds before open files are flushed. If this number is negative or zero the files are not flushed by timer. Indicates whether to automatically flush the file buffers after each log message. Name of the target. Condition expression. Log events who meet this condition will be forwarded to the wrapped target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Windows domain name to change context to. Required impersonation level. Type of the logon provider. Logon Type. User account password. Indicates whether to revert to the credentials of the process instead of impersonating another user. Username to change context to. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Interval in which messages will be written up to the number of messages. Maximum allowed number of messages written per . Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Endpoint address. Name of the endpoint configuration in WCF configuration file. Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply) Client ID. Indicates whether to include per-event properties in the payload sent to the server. Indicates whether to use binary message encoding. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Layout that should be use to calculate the value for the parameter. Name of the parameter. Type of the parameter. Type of the parameter. Obsolete alias for Name of the target. Text to be rendered. Header. Footer. Indicates whether NewLine characters in the body should be replaced with tags. Priority used for sending mails. Encoding to be used for sending e-mail. BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). Indicates whether to add new lines between log entries. Indicates whether to send message as HTML instead of plain text. Sender's email address (e.g. joe@domain.com). Mail message body (repeated for each log message send in one mail). Mail subject. Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Indicates the SMTP client timeout. SMTP Server to be used for sending. SMTP Authentication mode. Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic"). Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic"). Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server. Port number that SMTP Server is listening on. Indicates whether the default Settings from System.Net.MailSettings should be used. Folder where applications save mail messages to be processed by the local SMTP server. Specifies how outgoing email messages will be handled. Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Class name. Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Encoding to be used. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Network address. Size of the connection cache (number of connections which are kept alive). Indicates whether to keep connection open whenever possible. Maximum current connections. 0 = no maximum. Maximum queue size. Action that should be taken if the will be more connections than . Action that should be taken if the message is larger than maxMessageSize. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Encoding to be used. Instance of that is used to format log messages. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Action that should be taken if the will be more connections than . Maximum queue size. Maximum current connections. 0 = no maximum. Indicates whether to keep connection open whenever possible. Size of the connection cache (number of connections which are kept alive). Network address. Action that should be taken if the message is larger than maxMessageSize. NDLC item separator. NDC item separator. Indicates whether to include NLog-specific extensions to log4j schema. Indicates whether to include source info (file name and line number) in the information sent over the network. Indicates whether to include contents of the stack. Indicates whether to include stack contents. Indicates whether to include dictionary contents. Indicates whether to include dictionary contents. Indicates whether to include call site (class and method name) in the information sent over the network. Option to include all properties from the log events AppInfo field. By default it's the friendly name of the current AppDomain. Renderer for log4j:event logger-xml-attribute (Default ${logger}) Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Indicates whether to perform layout calculation. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Indicates whether performance counter should be automatically created. Name of the performance counter category. Counter help text. Name of the performance counter. Performance counter type. The value by which to increment the counter. Performance counter instance name. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Default filter to be applied when no specific rule matches. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Condition to be tested. Resulting filter to be applied when the condition matches. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Number of times to repeat each log message. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Number of retries that should be attempted on the wrapped target in case of a failure. Time to wait between retries in milliseconds. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Always use independent of Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8. Web service method name. Only used with Soap. Web service namespace. Only used with Soap. Protocol to be used when calling web service. Custom proxy address, include port separated by a colon Encoding. Web service URL. Value whether escaping be done according to the old NLog style (Very non-standard) Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs) Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in parameters) Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see and ). (optional) root namespace of the XML document, if POST of XML document chosen. (see and ). Proxy configuration when calling web service Footer layout. Header layout. Body layout (can be repeated multiple times). Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom'). Column delimiter. Quote Character. Quoting mode. Indicates whether CVS should include header. Layout of the column. Name of the column. List of property names to exclude when is true Option to include all properties from the log event (as JSON) Indicates whether to include contents of the dictionary. Indicates whether to include contents of the dictionary. Option to render the empty object value {} Option to suppress the extra spaces in the output json How far should the JSON serializer follow object references before backing off Layout that will be rendered as the attribute's value. Name of the attribute. Determines wether or not this attribute will be Json encoded. Indicates whether to escape non-ascii characters Whether an attribute with empty value should be included in the output Footer layout. Header layout. Body layout (can be repeated multiple times). Option to include all properties from the log events Indicates whether to include contents of the dictionary. Indicates whether to include contents of the dictionary. Indicates whether to include contents of the stack. Indicates whether to include contents of the stack. Layout text. Action to be taken when filter matches. Condition expression. Action to be taken when filter matches. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Substring to be matched. Action to be taken when filter matches. String to compare the layout to. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Action to be taken when filter matches. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Substring to be matched. Action to be taken when filter matches. String to compare the layout to. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Action to be taken when filter matches. Default number of unique filter values to expect, will automatically increase if needed Applies the configured action to the initial logevent that starts the timeout period. Used to configure that it should ignore all events until timeout. Layout to be used to filter log messages. Max number of unique filter values to expect simultaneously Max length of filter values, will truncate if above limit How long before a filter expires, and logging is accepted again Default buffer size for the internal buffers Reuse internal buffers, and doesn't have to constantly allocate new buffers Append FilterCount to the when an event is no longer filtered Insert FilterCount value into when an event is no longer filtered ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/Program.cs ================================================ using System; using Topshelf; namespace Sample.DotNetFxPublisherHost { class Program { static int Main() { return (int)HostFactory.Run(x => { x.UseAssemblyInfoForServiceInfo(); x.Service(s => { s.ConstructUsing(() => new DotNetFxPublisherHostBootstrap()); s.WhenStarted(v => v.Start()); s.WhenStopped(v => v.Stop()); s.BeforeStartingService(_ => { Console.WriteLine("Processor is starting"); }); s.BeforeStoppingService(_ => { Console.WriteLine("Processor is stopping"); }); }); // x.StartAutomatically(); x.SetStartTimeout(TimeSpan.FromSeconds(10)); x.SetStopTimeout(TimeSpan.FromSeconds(10)); x.EnableServiceRecovery(r => { r.RestartService(1); //r.RunProgram(7, "ping google.com"); r.RestartComputer(5, "message"); r.OnCrashOnly(); r.SetResetPeriod(2); }); //x.AddCommandLineSwitch("throwonstart", v => throwOnStart = v); //x.AddCommandLineSwitch("throwonstop", v => throwOnStop = v); //x.AddCommandLineSwitch("throwunhandled", v => throwUnhandled = v); x.OnException((exception) => { }); }); } } } ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Sample.DotNetFxPublisherHost")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Sample.DotNetFxPublisherHost")] [assembly: AssemblyCopyright("Copyright © 2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // 将 ComVisible 设置为 false 会使此程序集中的类型 //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("53ab6f1d-333e-462b-bd21-b806e6a899a5")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/Sample.DotNetFxPublisherHost.csproj ================================================  Debug AnyCPU {53AB6F1D-333E-462B-BD21-B806E6A899A5} Exe Sample.DotNetFxPublisherHost Sample.DotNetFxPublisherHost v4.7.1 512 true true AnyCPU true full false bin\Debug\ DEBUG;TRACE prompt 4 AnyCPU pdbonly true bin\Release\ TRACE prompt 4 ..\..\..\packages\Abp.4.6.0\lib\netstandard2.0\Abp.dll ..\..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\..\packages\Castle.LoggingFacility.4.1.1\lib\net45\Castle.Facilities.Logging.dll ..\..\..\packages\Castle.Core-NLog.4.3.1\lib\net45\Castle.Services.Logging.NLogIntegration.dll ..\..\..\packages\Castle.Windsor.4.1.1\lib\net45\Castle.Windsor.dll ..\..\..\packages\JetBrains.Annotations.2018.3.0\lib\net20\JetBrains.Annotations.dll ..\..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.28\lib\net46\Microsoft.Diagnostics.Tracing.EventSource.dll ..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Caching.Memory.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Options.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\..\packages\Microsoft.Extensions.Primitives.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll ..\..\..\packages\Nito.AsyncEx.Context.5.0.0\lib\netstandard2.0\Nito.AsyncEx.Context.dll ..\..\..\packages\Nito.AsyncEx.Coordination.5.0.0\lib\netstandard2.0\Nito.AsyncEx.Coordination.dll ..\..\..\packages\Nito.AsyncEx.Tasks.5.0.0\lib\netstandard2.0\Nito.AsyncEx.Tasks.dll ..\..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\..\packages\Nito.Disposables.2.0.0\lib\netstandard2.0\Nito.Disposables.dll ..\..\..\packages\NLog.4.5.10\lib\net45\NLog.dll ..\..\..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll ..\..\..\packages\Rebus.4.2.1\lib\net45\Rebus.dll ..\..\..\packages\Rebus.Castle.Windsor.4.1.0\lib\net45\Rebus.CastleWindsor.dll ..\..\..\packages\Rebus.NLog.5.0.0\lib\net45\Rebus.NLog.dll ..\..\..\packages\Rebus.RabbitMq.4.4.2\lib\net452\Rebus.RabbitMq.dll ..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True True ..\..\..\packages\System.Linq.Dynamic.Core.1.0.10\lib\net46\System.Linq.Dynamic.Core.dll ..\..\..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll ..\..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True True ..\..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True True ..\..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True True ..\..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True True ..\..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True True ..\..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True True ..\..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\..\packages\TimeZoneConverter.3.1.0\lib\net471\TimeZoneConverter.dll ..\..\..\packages\Topshelf.4.1.0\lib\net452\Topshelf.dll Always Designer {d27e21c1-96c8-4eff-aa4d-43a8ed7cc40b} Abplus.MqMessages.RebusCore {1c7e75d5-f462-43c7-a230-4e31faf8cc00} Abplus.MqMessages.RebusRabbitMqPublisher {10c03a51-881c-4779-9b24-5bfce234c175} Abplus {d71b7fba-e998-4141-81e6-e319c3941659} Sample.MqMessages ================================================ FILE: src/Samples/Sample.DotNetFxPublisherHost/packages.config ================================================  ================================================ FILE: src/Samples/Sample.MqMessages/Sample.MqMessages.csproj ================================================ net5.0 Sample ================================================ FILE: src/Samples/Sample.MqMessages/TestMessage.cs ================================================ using System; namespace Sample { public class TestMessage { public string Value { get; set; } public DateTime Time { get; set; } } } ================================================ FILE: src2/Abplus/Abplus.csproj ================================================  Debug AnyCPU {1DE8D8D1-987D-4A9C-AEC5-FF0A9914BBD4} Library Properties Abp Abplus v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.XML ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll Designer Designer 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus/Abplus.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus/AbplusConsts.cs ================================================ namespace Abp { public static class AbplusConsts { public const string CurrentVersion = "0.1.7.7"; } } ================================================ FILE: src2/Abplus/Application/Navigation/MenuItemDefinitionPlugInExtensions.cs ================================================ using System.Linq; using Abp.Extensions; using Abp.Localization; namespace Abp.Application.Navigation { public static class MenuItemDefinitionPlugInExtensions { public static MenuItemDefinition GetOrCreatePlugInsRootMenu(this MenuDefinition menu, string url, string icon, string plugInMenuName = "PlugIns", string fixedDisplayName = null, string requiredPermission = null) { if (plugInMenuName.IsNullOrWhiteSpace()) { plugInMenuName = "PlugIns"; } if (fixedDisplayName.IsNullOrWhiteSpace()) { fixedDisplayName = "PlugIns"; } var plugInRoot = menu.Items.FirstOrDefault(i => i.Name == plugInMenuName); if (plugInRoot == null) { plugInRoot = new MenuItemDefinition( plugInMenuName, new FixedLocalizableString(fixedDisplayName), url: url, icon: icon, requiredPermissionName: requiredPermission ); menu.AddItem(plugInRoot); } return plugInRoot; } } } ================================================ FILE: src2/Abplus/Application/Services/Dto/IHasDateTimeFilterRequest.cs ================================================ namespace Abp.Application.Services.Dto { using System; public interface IHasDateTimeFilterRequest { DateTime? StartTime { get; set; } DateTime? EndTime { get; set; } } } ================================================ FILE: src2/Abplus/Application/Services/Dto/IHasKeywordFilterRequest.cs ================================================ namespace Abp.Application.Services.Dto { public interface IHasKeywordFilterRequest { string Keyword { get; set; } } } ================================================ FILE: src2/Abplus/Application/Services/Dto/IPaginationResultRequest.cs ================================================ namespace Abp.Application.Services.Dto { public interface IPaginationResultRequest : ISortedResultRequest { int PageIndex { get; set; } int PageSize { get; set; } } } ================================================ FILE: src2/Abplus/Application/Services/Dto/PaginationRequestInput.cs ================================================ namespace Abp.Application.Services.Dto { using System.ComponentModel.DataAnnotations; public class PaginationResultRequestInput : IPaginationResultRequest { public PaginationResultRequestInput() { PageIndex = 1; PageSize = 10; } [Range(1, 1000)] public int PageIndex { get; set; } [Range(1, 1000)] public int PageSize { get; set; } public string Sorting { get; set; } } } ================================================ FILE: src2/Abplus/Currencies/ChineseCentExtension.cs ================================================ namespace Abp.Currencies { public static class ChineseCentExtension { public static decimal ToYuan(this int moneyInCent) { return moneyInCent / 100m; } public static string ToYuanString(this int moneyInCent) { return $"{moneyInCent.ToYuan().ToString("0.00")}元"; } } } ================================================ FILE: src2/Abplus/Events/Bus/ChangedEventData.cs ================================================ namespace Abp.Events.Bus { public abstract class ChangedEventData : EventData { public T Origin { get; set; } public T Current { get; set; } } } ================================================ FILE: src2/Abplus/Events/Bus/IShouldBePublish.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Abp.Events.Bus { /// ///this is used to mark an event should be publish. /// [Obsolete("不推荐直接将EventData发布到消息队列", false)] public interface IShouldBePublish { } } ================================================ FILE: src2/Abplus/Extensions/DateTimeExtensions.cs ================================================ namespace Abp.Extensions { using System; /// /// Extension methods for . /// public static class DateTimeExtensions { /// /// 转换为完整时间的字符串(yyyy-MM-dd HH:mm:ss) /// public static string ToFullTimeString(this DateTime source) { return source.ToString("yyyy-MM-dd HH:mm:ss"); } /// /// 转换为短时间的字符串(yyyy-MM-dd HH:mm) /// public static string ToShortTimeString(this DateTime source) { return source.ToString("yyyy-MM-dd HH:mm"); } /// /// 转换为只有日期的字符串(yyyy-MM-dd) /// public static string ToDateString(this DateTime source) { return source.ToString("yyyy-MM-dd"); } } } ================================================ FILE: src2/Abplus/Extensions/EnumExtensions.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Abp.Extensions { public static class EnumExtensions { public static string GetDisplayName(FieldInfo field) { DisplayAttribute display = field.GetCustomAttribute(inherit: false); if (display != null) { string name = display.GetName(); if (!String.IsNullOrEmpty(name)) { return name; } } return field.Name; } } } ================================================ FILE: src2/Abplus/Extensions/GuidExtensions.cs ================================================ namespace Abp.Extensions { using System; public static class GuidExtensions { /// /// 将Guid转换为经过Base64编码的22位字符串 /// public static string ToShortString(this Guid source) { string base64 = Convert.ToBase64String(source.ToByteArray()); string result = base64.Replace("/", "_").Replace("+", "-").Substring(0, 22); return result; } /// /// 转换成sqlserver有序Guid,时间相关,精度为300分之一毫秒 /// /// /// public static Guid ToCombGuid(this Guid source) { byte[] guidArray = source.ToByteArray(); DateTime baseDate = new DateTime(1900, 1, 1); DateTime now = DateTime.Now; // Get the days and milliseconds which will be used to build the byte string TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks); TimeSpan msecs = new TimeSpan(now.Ticks - (new DateTime(now.Year, now.Month, now.Day).Ticks)); // Convert to a byte array // Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 byte[] daysArray = BitConverter.GetBytes(days.Days); byte[] msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds / 3.333333)); // Reverse the bytes to match SQL Servers ordering Array.Reverse(daysArray); Array.Reverse(msecsArray); // Copy the bytes into the guid Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2); Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4); return new Guid(guidArray); } } } ================================================ FILE: src2/Abplus/Extensions/IntExtension.cs ================================================ using System; using Abp.Application.Services.Dto; namespace Abp.Extensions { public static class IntExtension { public static int ToSkipCount(this IPaginationResultRequest pagination) { CheckErrors(pagination); return (pagination.PageIndex - 1) * pagination.PageSize; } public static int ToMaxResultCount(this IPaginationResultRequest pagination) { CheckErrors(pagination); return pagination.PageSize; } private static void CheckErrors(IPaginationResultRequest pagination) { if (pagination == null) { throw new ArgumentNullException("pagination"); } if (pagination.PageSize < 1) { throw new ArgumentOutOfRangeException("pagesize"); } if (pagination.PageIndex < 1) { throw new ArgumentOutOfRangeException("pageindex"); } } } } ================================================ FILE: src2/Abplus/Extensions/NullableDateTimeExtensions.cs ================================================ namespace Abp.Extensions { using System; public static class NullableDateTimeExtensions { /// /// 转换为完整时间的字符串(yyyy-MM-dd HH:mm:ss) /// public static string ToFullString(this DateTime? source) { return source.HasValue ? source.Value.ToFullTimeString() : string.Empty; } /// /// 转换为短时间的字符串(yyyy-MM-dd HH:mm) /// public static string ToShortString(this DateTime? source) { return source.HasValue ? source.Value.ToShortTimeString() : string.Empty; } /// /// 转换为只有日期的字符串(yyyy-MM-dd) /// public static string ToDateString(this DateTime? source) { return source.HasValue ? source.Value.ToDateString() : string.Empty; } } } ================================================ FILE: src2/Abplus/Extensions/StringExtensions.cs ================================================ namespace Abp.Extensions { using System; using Newtonsoft.Json; public static class StringExtensions { /// /// 字符串转换为Guid类型 /// /// /// 默认返回Guid.Empty public static Guid ToGuid(this string str) { return str.ToGuid(null); } /// /// 指定格式字符串转换为Guid类型 /// /// /// /// 默认返回Guid.Empty public static Guid ToGuid(this string str, string format) { var result = Guid.Empty; if (!format.IsNullOrWhiteSpace()) { Guid.TryParseExact(str, format, out result); } else { Guid.TryParse(str, out result); } return result; } /// /// 字符串转换为Guid类型或者null,不成功返回null /// public static Guid? ToGuidOrNull(this string str) { Guid? result = null; if (!string.IsNullOrWhiteSpace(str)) { Guid tmp; if (Guid.TryParse(str, out tmp)) { result = tmp; } } return result; } /// /// 字符串转换为int类型或者null,不成功返回null /// public static int? ToIntOrNull(this string str) { int? result = null; if (!string.IsNullOrWhiteSpace(str)) { int tmp; if (int.TryParse(str, out tmp)) { result = tmp; } } return result; } /// /// 将经过Base64编码的22位字符串还原为Guid /// public static Guid Base64ToGuid(this string str) { Guid result = Guid.Empty; str = str.Trim(); string encoded = string.Concat(str.Trim().Replace("-", "+").Replace("_", "/"), "=="); try { byte[] base64 = Convert.FromBase64String(encoded); result = new Guid(base64); } catch (Exception ex) { throw new AbpException("不是有效的参数格式", ex); } return result; } /// /// 由json字符串反序列化成指定类型的对象,字符串为空或不符合格式,则返回类型的默认值 /// public static T ToObject(this string json) { var obj = default(T); if (json.IsNullOrWhiteSpace()) { return obj; } try { obj = JsonConvert.DeserializeObject(json); } catch { //eat exception to return default value } return obj; } } } ================================================ FILE: src2/Abplus/Interceptors/AsyncHandlingInterceptor.cs ================================================ using System.Reflection; using System.Threading.Tasks; using Castle.DynamicProxy; namespace Abp.Interceptors { public abstract class AsyncHandlingInterceptor : IInterceptor { protected readonly IAsyncInterceptorHandler Handler; private static readonly MethodInfo HandleAsyncMethodInfo = typeof(AsyncHandlingInterceptor).GetMethod("HandleAsyncWithResult", BindingFlags.Instance | BindingFlags.NonPublic); /// /// /// /// protected AsyncHandlingInterceptor(IAsyncInterceptorHandler handler) { Handler = handler; } public void Intercept(IInvocation invocation) { var delegateType = GetDelegateType(invocation); if (delegateType == MethodType.Synchronous) { Handler.Handle(invocation); //Handle(() => invocation.Proceed()); } if (delegateType == MethodType.AsyncAction) { Handler.HandleAsync(invocation); //invocation.Proceed(); //invocation.ReturnValue = HandleAsync((Task)invocation.ReturnValue); } if (delegateType == MethodType.AsyncFunction) { //invocation.Proceed(); ExecuteHandleAsyncWithResultUsingReflection(invocation); } } private void ExecuteHandleAsyncWithResultUsingReflection(IInvocation invocation) { var resultType = invocation.Method.ReturnType.GetGenericArguments()[0]; var mi = HandleAsyncMethodInfo.MakeGenericMethod(resultType); invocation.ReturnValue = mi.Invoke(this, new[] { invocation }); } /// /// Used by Reflection /// /// /// /// protected virtual async Task HandleAsyncWithResult(IInvocation invocation) { return await Handler.HandleAsync(invocation); } private MethodType GetDelegateType(IInvocation invocation) { var returnType = invocation.Method.ReturnType; if (returnType == typeof(Task)) return MethodType.AsyncAction; if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>)) return MethodType.AsyncFunction; return MethodType.Synchronous; } private enum MethodType { Synchronous, AsyncAction, AsyncFunction } } } ================================================ FILE: src2/Abplus/Interceptors/IAsyncInterceptorHandler.cs ================================================ using System.Threading.Tasks; using Castle.DynamicProxy; namespace Abp.Interceptors { /// /// /// public interface IAsyncInterceptorHandler { /// /// /// /// void Handle(IInvocation invocation); /// /// /// /// /// Task HandleAsync(IInvocation invocation); /// /// /// /// /// /// Task HandleAsync(IInvocation invocation); } } ================================================ FILE: src2/Abplus/Json/LargeNumJsonConverter.cs ================================================ using System; using System.Collections.Generic; using Newtonsoft.Json; namespace Abp.Json { /// /// csharp long type number maybe overflow when it assigned to javascript in a json object, so serialize it as string when its value overflow. /// public class LargeNumJsonConverter : JsonConverter { public override bool CanRead => false; public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var num = value as long?; if (num.HasValue && (num > _maxJsNum || num < _minJsNum)) { writer.WriteValue(num.ToString()); } else { writer.WriteValue(value); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (LargeNumTypes.Contains(objectType)) { long result; if (reader.Value != null && long.TryParse(reader.Value.ToString(), out result)) { return result; } return (long?)null; } return reader.Value; } public override bool CanConvert(Type objectType) { //9007199254740992 return LargeNumTypes.Contains(objectType); } private static long _maxJsNum = 9007199254740992; private static long _minJsNum = -9007199254740992; private static readonly List LargeNumTypes = new List { typeof(long), typeof(long?) }; } } ================================================ FILE: src2/Abplus/MqMessages/IMqMessagePublisher.cs ================================================ using System.Threading.Tasks; using Abp.Dependency; namespace Abp.MqMessages { /// /// 消息发布接口 /// public interface IMqMessagePublisher : ITransientDependency { /// /// 发布 /// /// void Publish(object mqMessages); /// /// 发布 /// /// /// Task PublishAsync(object mqMessages); } } ================================================ FILE: src2/Abplus/MqMessages/MessageTrackers/DefaultInMemoryMessageTracker.cs ================================================ using System.Collections.Concurrent; using System.Linq; using System.Threading.Tasks; namespace Abp.MqMessages.MessageTrackers { public class DefaultInMemoryMessageTracker : IMessageTracker { private static readonly ConcurrentBag InMemoryStore; static DefaultInMemoryMessageTracker() { InMemoryStore = new ConcurrentBag(); } public static DefaultInMemoryMessageTracker Instance { get { return SingletonInstance; } } private static readonly DefaultInMemoryMessageTracker SingletonInstance = new DefaultInMemoryMessageTracker(); public Task MarkAsProcessed(string processId) { InMemoryStore.Add(processId); return Task.FromResult(0); } public Task HasProcessed(string processId) { return Task.FromResult(InMemoryStore.Contains(processId)); } } } ================================================ FILE: src2/Abplus/MqMessages/MessageTrackers/IMessageTracker.cs ================================================ using System.Threading.Tasks; namespace Abp.MqMessages.MessageTrackers { public interface IMessageTracker { /// /// 查询是否已处理过 /// /// 能唯一标记本次处理过程的Id,可采用msgId+HandlerName等组合 /// Task HasProcessed(string processId); /// /// 标记为已处理过 /// /// 能唯一标记本次处理过程的Id,可采用msgId+HandlerName等组合 /// Task MarkAsProcessed(string processId); } } ================================================ FILE: src2/Abplus/MqMessages/NullMqMessagePublisher.cs ================================================ using System.Threading.Tasks; namespace Abp.MqMessages { /// /// 空模式 /// public class NullMqMessagePublisher : IMqMessagePublisher { /// /// /// public static NullMqMessagePublisher Instance { get { return SingletonInstance; } } private static readonly NullMqMessagePublisher SingletonInstance = new NullMqMessagePublisher(); /// /// /// /// /// public Task PublishAsync(object mqMessages) { //do nothing. return Task.FromResult(0); } /// /// /// /// public void Publish(object mqMessages) { //do nothing. } } } ================================================ FILE: src2/Abplus/PlugIns/IPlugInAreaRegistration.cs ================================================ namespace Abp.PlugIns { public interface IPlugInAreaRegistration { } } ================================================ FILE: src2/Abplus/PlugIns/IPlugInAuthorizationProvider.cs ================================================ namespace Abp.PlugIns { public interface IPlugInAuthorizationProvider { } } ================================================ FILE: src2/Abplus/PlugIns/IPlugInNavigationProvider.cs ================================================ namespace Abp.PlugIns { public interface IPlugInNavigationProvider { } } ================================================ FILE: src2/Abplus/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus/QrCode/IQrCodeScannedRealTimeNotifier.cs ================================================ using System.Threading.Tasks; namespace Abp.QrCode { public interface IQrCodeScannedRealTimeNotifier { Task Notify(string scannerIdentifier, string connectionId, object properties = null); } } ================================================ FILE: src2/Abplus/Reservations/Events/ReservationCancelledEventData.cs ================================================ namespace Abp.Reservations.Events { /// /// 预定取消事件抽象基类 /// public abstract class ReservationCancelledEventData : ReservationEventDataBase { } } ================================================ FILE: src2/Abplus/Reservations/Events/ReservationEventDataBase.cs ================================================ using Abp.Events.Bus; using Abp.TimeRanges; namespace Abp.Reservations.Events { /// /// 预定发生变化的事件基类 /// public abstract class ReservationEventDataBase : EventData { /// /// 预定记录唯一标识 /// public string ReservationCode { get; set; } /// /// 预定主题 /// public string ReservationSubject { get; set; } /// /// 预定时间区间 /// public TimeRange ReservationTimeRange { get; set; } } } ================================================ FILE: src2/Abplus/Reservations/Events/ReservationSuccessEventData.cs ================================================ namespace Abp.Reservations.Events { /// /// 预定成功事件抽象基类 /// public abstract class ReservationSuccessEventData : ReservationEventDataBase { } } ================================================ FILE: src2/Abplus/Reservations/IReservation.cs ================================================ using System.Collections.Generic; using Abp.TimeRanges; namespace Abp.Reservations { /// /// 预定 /// public interface IReservation { /// /// 预定的主题 /// string ReservationSubject { get; } /// /// 预定的类型 /// string ReservationType { get; } /// /// 预定的唯一编码 /// string ReservationCode { get; } /// /// 预定的时间 /// TimeRange ReservationTime { get; } /// /// 同一预定主体的两个预定应检测是否冲突 /// /// /// bool IsConflict(IReservation reservation); /// /// /// /// /// bool IsConflict(IEnumerable reservations); } } ================================================ FILE: src2/Abplus/Reservations/IReservationBody.cs ================================================ using System; using System.Collections.Generic; namespace Abp.Reservations { /// /// 可被预定的资源主体 /// /// public interface IReservationBody where T : IReservation { /// /// 可被预定的资源唯一标识(建议8位数字) /// string ResourceCode { get; } /// /// 资源的预定列表 /// ICollection Reservations { get; } /// /// 预定 /// /// /// /// /// T Reserve(string subject, DateTime from, DateTime to); /// /// 取消预定 /// /// /// T CancelReservation(string reservationCode); } } ================================================ FILE: src2/Abplus/Reservations/ReservationBase.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using Abp.Domain.Entities.Auditing; using Abp.TimeRanges; namespace Abp.Reservations { /// /// 预定基类,可被预定的资源拥有一个预定的列表,具体预定的实现可继承本基类 /// public abstract class ReservationBase : CreationAuditedEntity, IReservation { /// /// 默认最小预定时间区间长度(单位:分钟) /// public const int DefaultMinTimeRangeLengthForReservationInMinutes = 3;//预定记录唯一编码受预定时间区间粒度影响 protected ReservationBase() { } public ReservationBase(string reservationSubject, TimeRange reservationTime, string reservationType, string reservationResourceCode) { if (reservationTime.To.Subtract(reservationTime.From).TotalMinutes < MinTimeRangeLengthForReservationInMinutes) { throw new ArgumentException($"预定时间区间应大于{MinTimeRangeLengthForReservationInMinutes}分钟!"); } ReservationType = reservationType; ReservationSubject = reservationSubject; ReservationTime = reservationTime; SetReservationCode(reservationResourceCode); } protected virtual int MinTimeRangeLengthForReservationInMinutes { get { return DefaultMinTimeRangeLengthForReservationInMinutes; } } /// /// 生成预定唯一编码 /// /// protected virtual void SetReservationCode(string resourceCode) { ReservationCode = $"{ReservationType}-{resourceCode}-{ReservationTime.From.ToString("yyyyMMddHHmm")}"; } /// /// 预定类型 /// [MaxLength(10)] public string ReservationType { get; private set; } /// /// 预定唯一编码 /// public string ReservationCode { get; private set; } /// /// 预定主题 /// [MaxLength(256)] public string ReservationSubject { get; private set; } /// /// 所预定的时间区间 /// public TimeRange ReservationTime { get; private set; } /// /// 是否冲突 /// /// /// public virtual bool IsConflict(IReservation reservation) { return ReservationTime.IsIntersect(reservation.ReservationTime); } /// /// 是否冲突 /// /// /// public virtual bool IsConflict(IEnumerable reservations)//ICollection 不支持逆变 { var times = reservations.Select(r => r.ReservationTime).ToList(); return ReservationTime.IsIntersect(times); } } } ================================================ FILE: src2/Abplus/Reservations/ReservationBodyBase.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using Abp.Domain.Entities; using Abp.Events.Bus; using Abp.TimeRanges; using Abp.Timing; namespace Abp.Reservations { /// /// 可被预定主体的抽象基类 /// /// /// public abstract class ReservationBodyBase : AggregateRoot, IReservationBody where TReservation : IReservation { /// /// 可被预定主体的唯一标识 /// public string ResourceCode { get; protected set; } /// /// 预定列表 /// public virtual ICollection Reservations { get; protected set; } /// /// 获取预定取消时应触发的事件 /// protected abstract Func GetReservationCancelledEventData { get; } /// /// 检查新增预定是否与已有预定相冲突 /// protected abstract Func, bool> GetIfTheseReservationsConflict { get; } /// /// 获取预定成功时应触发的事件 /// protected abstract Func GetReserveSuccessEventData { get; } /// /// 如果新增预定与已有预定相冲突时,应抛出的具体异常 /// protected abstract Action ThrowIfTheseReservationsConflict { get; } /// /// 取消预定 /// /// /// public virtual TReservation CancelReservation(string reservationCode) { Check.NotNullOrWhiteSpace(reservationCode, nameof(reservationCode)); var reservation = Reservations.FirstOrDefault(r => r.ReservationCode == reservationCode); if (reservation == null) { return reservation; } Reservations.Remove(reservation); DomainEvents.Add(GetReservationCancelledEventData(reservation)); return reservation; } /// /// 预定 /// /// 预定主题 /// 时间区间起 /// 时间区间止 /// public virtual TReservation Reserve(string subject, DateTime from, DateTime to) { Check.NotNullOrWhiteSpace(subject, nameof(subject)); TReservation newReservation = (TReservation)Activator.CreateInstance(typeof(TReservation), subject, new TimeRange(from, to), ResourceCode); var reservations = Reservations.Where(r => r.ReservationTime.To > Clock.Now).ToList(); if (reservations.Any()) { if (GetIfTheseReservationsConflict(newReservation, reservations)) { ThrowIfTheseReservationsConflict(); } } Reservations.Add(newReservation); DomainEvents.Add(GetReserveSuccessEventData(newReservation)); return newReservation; } } } ================================================ FILE: src2/Abplus/TimeRanges/TimeRange.cs ================================================ using System; using System.Collections.Generic; using Abp.Domain.Values; namespace Abp.TimeRanges { public class TimeRange : ValueObject { protected TimeRange() { } public TimeRange(DateTime from, DateTime to) { Check.NotNull(from, nameof(from)); Check.NotNull(to, nameof(to)); if (from >= to) { throw new ArgumentException("时间区间的起点必须小于终点!"); } From = from; To = to; } /// /// 时间区间起 /// public DateTime From { get; private set; } /// /// 时间区间止 /// public DateTime To { get; private set; } /// /// 包含,一般用于匹配 /// /// /// public bool IsIncluding(TimeRange that) { Check.NotNull(that, nameof(that)); return From <= that.From && To >= that.To; } /// /// 相交,一般用于检测冲突 /// /// /// public bool IsIntersect(TimeRange that) { Check.NotNull(that, nameof(that)); return To >= that.From && To <= that.To || From >= that.From && To <= that.To || From >= that.From && From <= that.To; } /// /// 相交,一般用于检测冲突 /// /// /// public bool IsIntersect(ICollection those) { Check.NotNull(those, nameof(those)); foreach (var that in those) { if (IsIntersect(that)) { return true; } } return false; } } } ================================================ FILE: src2/Abplus/app.config ================================================  ================================================ FILE: src2/Abplus/packages.config ================================================  ================================================ FILE: src2/Abplus.Common/Abplus.Common.csproj ================================================  Debug AnyCPU {2C69763F-3880-4D4D-8E14-A0D3A2B2B4F8} Library Properties Abplus Abplus.Common v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.Common.XML ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\AutoMapper.6.2.2\lib\net45\AutoMapper.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll ..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll Designer 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.Common/Abplus.Common.nuspec ================================================ $id$ $version$ $title$ mienreal mienreal https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. upgrade version of automapper,abp etc. Copyright 2017 ================================================ FILE: src2/Abplus.Common/Application/Services/Dto/IPagedQueryInput.cs ================================================ namespace Abp.Application.Services.Dto { public interface IPagedQueryInput : IPagedResultRequest, ISortedResultRequest { } } ================================================ FILE: src2/Abplus.Common/Application/Services/Dto/PagedQueryInput.cs ================================================ namespace Abp.Application.Services.Dto { using System; using System.ComponentModel.DataAnnotations; public class PagedQueryInput : IPagedQueryInput { const int MaxPageSize = 500; const int DefaultPageSize = 10; [Range(1, MaxPageSize)] public virtual int MaxResultCount { get; set; } [Range(0, int.MaxValue)] public virtual int SkipCount { get; set; } public virtual string Sorting { get; set; } public virtual string Filter { get; set; } public PagedQueryInput() { MaxResultCount = DefaultPageSize; } } } ================================================ FILE: src2/Abplus.Common/Linq/Extensions/IQueryableExtension.cs ================================================ using AutoMapper.QueryableExtensions; namespace Abp.Linq.Extensions { using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Data.Entity; using System.Linq; using System.Linq.Dynamic; using System.Threading.Tasks; using Abp.Application.Services.Dto; using Abp.Linq.Extensions; using Abp.Threading; using Domain.Entities; using System.Linq.Expressions; using Abp.Extensions; public static class IQueryableExtension { /// /// 应用requestInput指定的排序参数 /// public static IQueryable ApplySorting(this IQueryable query, ISortedResultRequest requestInput = null) where T : class { if (requestInput != null && !requestInput.Sorting.IsNullOrWhiteSpace()) //有排序参数 { return query.OrderBy(requestInput.Sorting); } return query; } /// /// 应用requestInput指定的分页参数 /// public static IQueryable ApplyPaging(this IQueryable query, IPagedResultRequest requestInput = null) where T : class { if (requestInput != null) { return query.PageBy(requestInput); } return query; } /// /// 根据requestInput进行排序、分页。 /// public static IQueryable ApplySortingAndPaging(this IQueryable query, IPagedQueryInput requestInput = null) where T : class { query = query.ApplySorting(requestInput); query = query.ApplyPaging(requestInput); return query; } /// /// 转换为指定Dto类型的IQueryable /// public static IQueryable ProjectTo(this IQueryable query, params Expression>[] membersToExpand) { return query.ProjectTo(membersToExpand); } /// /// 只查Dto类型指定字段的列表数据 /// /// 实体类型 /// 列表Dto类型 /// /// 查询参数(指定排序列) /// 查询出Dto类型指定字段的列表数据 public static async Task> ToListResultAsync(this IQueryable query, ISortedResultRequest requestInput = null) where TSource : class where TDto : class { query = query.ApplySorting(requestInput); var result = new ListResultDto() { Items = await query.ProjectTo().ToListAsync() }; return result; } /// /// 只查Dto类型指定字段的列表数据 /// /// 实体类型 /// 列表Dto类型 /// /// 查询参数(指定排序列) /// 查询出Dto类型指定字段的列表数据 public static ListResultDto ToListResult(this IQueryable query, ISortedResultRequest requestInput = null) where TSource : class where TDto : class { return AsyncHelper.RunSync(() => query.ToListResultAsync(requestInput)); } /// /// 根据requestInput进行排序、分页后,转换为分页查询结果 /// /// 原Entity类型 /// 目标Dto类型 /// /// 查询参数 /// public static async Task> ToPagedResultAsync(this IQueryable query, IPagedQueryInput requestInput = null) where TSource : class where TDto : class { var pagedQuery = query.ApplySortingAndPaging(requestInput); var result = new PagedResultDto() { Items = await pagedQuery.ProjectTo().ToListAsync() }; //没有分页参数,或者第1页的结果不足一整页时,不需要统计总记录数 if (requestInput == null || (requestInput.SkipCount == 0 && result.Items.Count < requestInput.MaxResultCount)) { result.TotalCount = result.Items.Count; } else { result.TotalCount = await query.CountAsync(); } return result; } /// /// 根据requestInput进行排序、分页后,转换为分页查询结果 /// /// 原Entity类型 /// 目标Dto类型 /// /// 查询参数 /// public static PagedResultDto ToPagedResult(this IQueryable query, IPagedQueryInput requestInput = null) where TSource : class where TDto : class { return AsyncHelper.RunSync(() => query.ToPagedResultAsync(requestInput)); } } } ================================================ FILE: src2/Abplus.Common/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.Common")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.Common")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("2c69763f-3880-4d4d-8e14-a0d3a2b2b4f8")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.2.1")] [assembly: AssemblyFileVersion("0.1.2.1")] ================================================ FILE: src2/Abplus.Common/app.config ================================================ 
================================================ FILE: src2/Abplus.Common/packages.config ================================================  ================================================ FILE: src2/Abplus.EntityFramework/Abplus.EntityFramework.csproj ================================================  Debug AnyCPU {4BEE8A8E-59D8-4DD4-BE1C-0DE31A348515} Library Properties Abp Abplus.EntityFramework v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll ..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll ================================================ FILE: src2/Abplus.EntityFramework/Abplus.EntityFramework.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.EntityFramework/App.config ================================================ 
================================================ FILE: src2/Abplus.EntityFramework/EntityFramework/DbContextUtils.cs ================================================ using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Core.Mapping; using System.Data.Entity.Core.Metadata.Edm; using System.Data.Entity.Infrastructure; namespace Abp.EntityFramework { public static class DbContextUtils { public static void WarmUp() where TContext : DbContext, new() { using (var dbcontext = new TContext()) { var objectContext = ((IObjectContextAdapter)dbcontext).ObjectContext; var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace); mappingCollection.GenerateViews(new List()); } } } } ================================================ FILE: src2/Abplus.EntityFramework/EntityFramework/DbModelBuilderExtensions.cs ================================================ using System; using System.Data.Entity; using System.Linq; using System.Reflection; namespace Abp.EntityFramework { public static class DbModelBuilderExtensions { public static void AutoRegisterTypeConfigurations(this DbModelBuilder modelBuilder, Assembly assembly, params Type[] baseTypes) { var typesToRegister = assembly.GetTypes() .Where(type => !string.IsNullOrEmpty(type.Namespace)) .Where(type => type.BaseType != null && type.BaseType.IsGenericType && baseTypes.Contains(type.BaseType.GetGenericTypeDefinition())); foreach (var type in typesToRegister) { dynamic configurationInstance = Activator.CreateInstance(type); modelBuilder.Configurations.Add(configurationInstance); } } } } ================================================ FILE: src2/Abplus.EntityFramework/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.EntityFramework")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.EntityFramework")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("4bee8a8e-59d8-4dd4-be1c-0de31a348515")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] [assembly: AssemblyFileVersion("0.1.0.0")] ================================================ FILE: src2/Abplus.EntityFramework/packages.config ================================================  ================================================ FILE: src2/Abplus.Events.Producer/Abplus.Events.Producer.csproj ================================================  Debug AnyCPU {E9957D88-655D-4411-98C3-C7D6009BA13C} Library Properties Abp Abplus.Events.Producer v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.Events.Producer.XML ..\..\packages\Abp.1.4.2.0\lib\net452\Abp.dll True ..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True ..\..\packages\Castle.LoggingFacility.3.4.0\lib\net45\Castle.Facilities.Logging.dll True ..\..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.Events.Producer/Abplus.Events.Producer.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.Events.Producer/Events/Producer/AbpEventsProducerModule.cs ================================================ using System.Reflection; using Abp.Modules; namespace Abp.Events.Producer { [DependsOn(typeof(AbpKernelModule))] public class AbpEventsProducerModule : AbpModule { public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } } } ================================================ FILE: src2/Abplus.Events.Producer/Events/Producer/Handler/PublishAllEventsHandler.cs ================================================ using Abp.Dependency; using Abp.Domain.Uow; using Abp.Events.Bus; using Abp.Events.Bus.Handlers; namespace Abp.Events.Producer.Handler { public class PublishAllEventsHandler : IEventHandler, ITransientDependency { public IProducer _producer { get; set; } private readonly IUnitOfWorkManager _unitOfWorkManager; public PublishAllEventsHandler(IUnitOfWorkManager unitOfWorkManager) { _producer = NullProducer.Instance; _unitOfWorkManager = unitOfWorkManager; } public void HandleEvent(EventData eventData) { if (eventData is IShouldBePublish) { if (_unitOfWorkManager.Current == null) { _producer.Publish(eventData); } else { _unitOfWorkManager.Current.Completed += (sender, e) => _producer.Publish(eventData); } } } } } ================================================ FILE: src2/Abplus.Events.Producer/Events/Producer/IProducer.cs ================================================  using System; namespace Abp.Events.Producer { [Obsolete("不推荐直接将EventData发布到消息队列,请使用Abp.MqMessages.IMqMessagePublisher", false)] public interface IProducer { void Publish(object events); } } ================================================ FILE: src2/Abplus.Events.Producer/Events/Producer/NullProducer.cs ================================================  namespace Abp.Events.Producer { public class NullProducer : IProducer { public static NullProducer Instance { get { return SingletonInstance; } } private static readonly NullProducer SingletonInstance = new NullProducer(); public void Publish(object events) { } } } ================================================ FILE: src2/Abplus.Events.Producer/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.Events.Producer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.Events.Producer")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("e9957d88-655d-4411-98c3-c7d6009ba13c")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.Events.Producer/packages.config ================================================  ================================================ FILE: src2/Abplus.MqMessages/Abplus.MqMessages.csproj ================================================  Debug AnyCPU {F0ECE646-29F7-48EB-AB40-6D238F785B73} Library Properties Abp Abplus.MqMessages v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Abp.AutoMapper.3.7.2\lib\netstandard2.0\Abp.AutoMapper.dll ..\..\packages\AutoMapper.6.2.2\lib\net45\AutoMapper.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll Designer {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.MqMessages/Abplus.MqMessages.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.MqMessages/Configuration/Startup/ExceptionLogInterceptorRegistrar.cs ================================================ using Abp.Dependency; using Abp.MqMessages.MqHandlers; using Abp.MqMessages.MqHandlers.ExceptionLogging; using Castle.Core; using Castle.MicroKernel; namespace Abp.Configuration.Startup { public static class ExceptionLogInterceptorRegistrar { public static void Initialize(IIocManager iocManager) { iocManager.Register(); iocManager.Register(); iocManager.IocContainer.Kernel.ComponentRegistered += Kernel_ComponentRegistered; } private static void Kernel_ComponentRegistered(string key, IHandler handler) { if (typeof(AbpMqHandlerBase).IsAssignableFrom(handler.ComponentModel.Implementation)) { handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(ExceptionLogInterceptor))); } } } } ================================================ FILE: src2/Abplus.MqMessages/MqMessages/AutoMapper/AutoEventsMapToMqMessagesHelper.cs ================================================ using System.Linq; using System.Reflection; using Abp.MqMessages.Handlers; using AutoMapper; namespace Abp.MqMessages.AutoMapper { public static class AutoEventsMapToMqMessagesHelper { public static void CreateEventsToMqMessagesMappings(this IMapperConfigurationExpression mapper, Assembly assembly) { var typesToRegister = assembly.GetTypes() .Where(type => !string.IsNullOrEmpty(type.Namespace)) .Where(type => type.BaseType != null && type.BaseType.IsGenericType && (type.BaseType.GetGenericTypeDefinition() == typeof(EventDataPublishHandlerBase<,>))); foreach (var type in typesToRegister) { var genericArgs = type.BaseType.GetGenericArguments(); if (genericArgs.Length > 1 && !genericArgs[0].BaseType.IsGenericType) { mapper.CreateMap(genericArgs[0], genericArgs[1]); } } } } } ================================================ FILE: src2/Abplus.MqMessages/MqMessages/Handlers/EventDataPublishHandlerBase.cs ================================================ using Abp.AutoMapper; using Abp.Dependency; using Abp.Domain.Uow; using Abp.Events.Bus; using Abp.Events.Bus.Handlers; using Castle.Core.Logging; namespace Abp.MqMessages.Handlers { /// /// 订阅EventData并发布消息到消息队列的抽象基类 /// /// Abp事件 /// 支持序列化的消息体(类DTO对象) public abstract class EventDataPublishHandlerBase : IEventHandler, ITransientDependency where TEventData : EventData where TMqMessage : class { protected readonly IUnitOfWorkManager UnitOfWorkManager; public ILogger Logger { get; set; } public IMqMessagePublisher MqMessagePublisher { get; set; } public EventDataPublishHandlerBase(IUnitOfWorkManager unitOfWorkManager) { UnitOfWorkManager = unitOfWorkManager; Logger = NullLogger.Instance; MqMessagePublisher = NullMqMessagePublisher.Instance; } public virtual void HandleEvent(TEventData eventData) { if (UnitOfWorkManager.Current == null) { MqMessagePublisher.Publish(ConvertEventDataToMqMessage(eventData)); } else { UnitOfWorkManager.Current.Completed += (sender, e) => MqMessagePublisher.Publish(ConvertEventDataToMqMessage(eventData)); } } /// /// 转换EventData为MqMessage,默认采用eventData.MapTo() /// /// /// public virtual TMqMessage ConvertEventDataToMqMessage(TEventData eventData) { return eventData.MapTo(); } } } ================================================ FILE: src2/Abplus.MqMessages/MqMessages/MqHandlers/AbpMqHandlerBase.cs ================================================ using System; using System.Threading.Tasks; using Abp.Dependency; using Abp.MqMessages.MessageTrackers; namespace Abp.MqMessages.MqHandlers { public abstract class AbpMqHandlerBase : AbpServiceBase, ITransientDependency { public IMessageTracker MessageTracker { get; set; } public AbpMqHandlerBase(string localizationSourceName) { LocalizationSourceName = localizationSourceName; MessageTracker = DefaultInMemoryMessageTracker.Instance; } protected async Task IsTrueSetting(string settingKey) { return string.Equals("true", await SettingManager.GetSettingValueForApplicationAsync(settingKey), StringComparison.CurrentCultureIgnoreCase); } } } ================================================ FILE: src2/Abplus.MqMessages/MqMessages/MqHandlers/ExceptionLoggling/ExceptionLogAttribute.cs ================================================ using System; using Abp.Logging; namespace Abp.MqMessages.MqHandlers.ExceptionLogging { public class ExceptionLogAttribute : Attribute { /// /// 需拦截的异常 /// public Type[] ExceptionTypes { get; set; } /// /// 是否记录日志,默认true /// public bool Logged { get; set; } /// /// 日志级别,默认Warn /// public LogSeverity LogLevel { get; set; } /// /// 是否吃掉异常,默认false /// public bool NotThrow { get; set; } /// /// /// /// public ExceptionLogAttribute(params Type[] exceptionTypes) : this(true, LogSeverity.Warn, false, exceptionTypes) { } /// /// /// /// /// public ExceptionLogAttribute(bool notThrow, params Type[] exceptionTypes) : this(true, LogSeverity.Warn, notThrow, exceptionTypes) { } /// /// /// /// /// /// public ExceptionLogAttribute(bool logged, LogSeverity logLevel, params Type[] exceptionTypes) : this(logged, logLevel, false, exceptionTypes) { } /// /// /// /// 记录日志(警告级别),默认true /// 日志等级 /// 是否吃掉异常 /// 需拦截的异常 public ExceptionLogAttribute(bool logged, LogSeverity logLevel, bool notThrow, params Type[] exceptionTypes) { Logged = logged; LogLevel = logLevel; NotThrow = notThrow; ExceptionTypes = exceptionTypes; } } } ================================================ FILE: src2/Abplus.MqMessages/MqMessages/MqHandlers/ExceptionLoggling/ExceptionLogHandler.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Abp.Extensions; using Abp.Interceptors; using Castle.Core.Logging; using Castle.DynamicProxy; namespace Abp.MqMessages.MqHandlers.ExceptionLogging { public class ExceptionLogHandler : IAsyncInterceptorHandler { public ILogger Logger { get; set; } public ExceptionLogHandler() { Logger = NullLogger.Instance; } public void Handle(IInvocation invocation) { var handleExceptionAttributes = GetAttributesOfMemberAndDeclaringType( invocation.MethodInvocationTarget); if (handleExceptionAttributes.Count <= 0) { invocation.Proceed(); return; } else { try { invocation.Proceed(); } catch (Exception ex) { var exType = ex.GetType(); var attribute = handleExceptionAttributes.FirstOrDefault(h => h.ExceptionTypes.Contains(exType)); if (attribute == null) { ex.ReThrow(); } LogException(attribute, ex, invocation.MethodInvocationTarget); if (!attribute.NotThrow) { ex.ReThrow(); } } } } public async Task HandleAsync(IInvocation invocation) { var handleExceptionAttributes = GetAttributesOfMemberAndDeclaringType( invocation.MethodInvocationTarget); if (handleExceptionAttributes.Count <= 0) { invocation.Proceed(); await (Task)invocation.ReturnValue; } else { try { invocation.Proceed(); await (Task)invocation.ReturnValue; } catch (Exception ex) { var exType = ex.GetType(); var attribute = handleExceptionAttributes.FirstOrDefault(h => h.ExceptionTypes.Contains(exType)); if (attribute == null) { ex.ReThrow(); } LogException(attribute, ex, invocation.MethodInvocationTarget); if (!attribute.NotThrow) { ex.ReThrow(); } } } } public async Task HandleAsync(IInvocation invocation) { var handleExceptionAttributes = GetAttributesOfMemberAndDeclaringType( invocation.MethodInvocationTarget); if (handleExceptionAttributes.Count <= 0) { invocation.Proceed(); return await (Task)invocation.ReturnValue; } else { try { invocation.Proceed(); return await (Task)invocation.ReturnValue; } catch (Exception ex) { var exType = ex.GetType(); var attribute = handleExceptionAttributes.FirstOrDefault(h => h.ExceptionTypes.Contains(exType)); if (attribute == null) { ex.ReThrow(); } LogException(attribute, ex, invocation.MethodInvocationTarget); if (!attribute.NotThrow) { ex.ReThrow(); } return default(T); } } } private static List GetAttributesOfMemberAndDeclaringType(MemberInfo memberInfo) where TAttribute : Attribute { var attributeList = new List(); //Add attributes on the member if (memberInfo.IsDefined(typeof(TAttribute), true)) { attributeList.AddRange(memberInfo.GetCustomAttributes(typeof(TAttribute), true).Cast()); } //Add attributes on the class if (memberInfo.DeclaringType != null && memberInfo.DeclaringType.IsDefined(typeof(TAttribute), true)) { attributeList.AddRange(memberInfo.DeclaringType.GetCustomAttributes(typeof(TAttribute), true).Cast()); } return attributeList; } private void LogException(ExceptionLogAttribute attribute, Exception ex, MethodInfo methodInfo) { if (attribute.Logged) { var msg = $"{methodInfo.DeclaringType.FullName}.{$".{methodInfo.Name}"} Fail:{ex.Message}"; switch (attribute.LogLevel) { case Abp.Logging.LogSeverity.Debug: Logger.Debug(msg, ex); return; case Abp.Logging.LogSeverity.Info: Logger.Info(msg, ex); return; case Abp.Logging.LogSeverity.Warn: Logger.Warn(msg, ex); return; case Abp.Logging.LogSeverity.Error: Logger.Error(msg, ex); return; case Abp.Logging.LogSeverity.Fatal: Logger.Fatal(msg, ex); return; default: Logger.Warn(msg, ex); return; } } } } } ================================================ FILE: src2/Abplus.MqMessages/MqMessages/MqHandlers/ExceptionLoggling/ExceptionLogInterceptor.cs ================================================ using Abp.Interceptors; namespace Abp.MqMessages.MqHandlers.ExceptionLogging { public class ExceptionLogInterceptor : AsyncHandlingInterceptor { public ExceptionLogInterceptor(ExceptionLogHandler handler) : base(handler) { } } } ================================================ FILE: src2/Abplus.MqMessages/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.MqMessages")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.MqMessages")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("f0ece646-29f7-48eb-ab40-6d238f785b73")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.MqMessages/app.config ================================================  ================================================ FILE: src2/Abplus.MqMessages/packages.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/Abplus.MqMessages.AuditingConsumerRebusHandler.csproj ================================================  Debug AnyCPU {0F8EDD31-AB0A-45FE-8F35-AE7AF0873AE3} Library Properties Abp Abplus.MqMessages.AuditingConsumerRebusHandler v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.1.4.2.0\lib\net452\Abp.dll True ..\..\packages\Castle.Core.3.3.0\lib\net45\Castle.Core.dll True ..\..\packages\Castle.LoggingFacility.3.4.0\lib\net45\Castle.Facilities.Logging.dll True ..\..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Rebus.3.1.4\lib\NET45\Rebus.dll True ..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True {b1585b83-25a5-4c8c-a384-b1205e459c16} Abplus.MqMessages.AuditingStore {f0ece646-29f7-48eb-ab40-6d238f785b73} Abplus.MqMessages {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/Auditing/AuditingStore/AuditingConsumerRebusHandlerModule.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Abp.Modules; namespace Abp.Auditing.AuditingStore { public class AuditingConsumerRebusHandlerModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { MqMessageAuditingStoreRebusHandler.Timer.Start(); } public override void Shutdown() { MqMessageAuditingStoreRebusHandler.Timer.Stop(); } } } ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/Auditing/AuditingStore/AuditingConsumerRebusHandlerModuleConfig.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Abp.Auditing.AuditingStore { public class AuditingConsumerRebusHandlerModuleConfig : IAuditingConsumerRebusHandlerModuleConfig { public AuditingConsumerRebusHandlerModuleConfig() { BatchSize = 100; PeriodInSeconds = 1; BatchStoreAction = (msgList) => { }; } public int BatchSize { get; private set; } public Action> BatchStoreAction { get; private set; } public int PeriodInSeconds { get; private set; } } } ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/Auditing/AuditingStore/IAuditingConsumerRebusHandlerModuleConfig.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Abp.Auditing.AuditingStore { public interface IAuditingConsumerRebusHandlerModuleConfig { /// /// 每批大小 /// int BatchSize { get; } /// /// 执行间隔(单位:秒) /// int PeriodInSeconds { get; } /// /// 批量存储的委托 /// Action> BatchStoreAction { get; } } } ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/Auditing/AuditingStore/MqMessageAuditingStoreRebusHandler.cs ================================================ using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading.Tasks; using Abp.Dependency; using Abp.Threading.Timers; using Rebus.Handlers; using System.Linq; namespace Abp.Auditing.AuditingStore { public class MqMessageAuditingStoreRebusHandler : IHandleMessages , ITransientDependency { private static ConcurrentQueue InMemoryAuditInfoQueue; public static AbpTimer Timer; static MqMessageAuditingStoreRebusHandler() { InMemoryAuditInfoQueue = new ConcurrentQueue(); var config = IocManager.Instance.Resolve(); Timer = new AbpTimer(config.PeriodInSeconds * 1000); Timer.Elapsed += (s, e) => { var tmpMsg = new List(); for (int i = 0; i < config.BatchSize; i++) { AuditInfoMqMessage msg; if (InMemoryAuditInfoQueue.TryDequeue(out msg)) { tmpMsg.Add(msg); } else { break; } } if (tmpMsg.Any()) { config.BatchStoreAction(tmpMsg); } }; } public async Task Handle(AuditInfoMqMessage message) { InMemoryAuditInfoQueue.Enqueue(message); } } } ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/Configuration/Startup/AuditingConsumerRebusHandlerConfigurationExtensions.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Abp.Configuration.Startup { public static class AuditingConsumerRebusHandlerConfigurationExtensions { } } ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.MqMessages.AuditingConsumerHandler")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.MqMessages.AuditingConsumerHandler")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("0f8edd31-ab0a-45fe-8f35-ae7af0873ae3")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/app.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.AuditingConsumerHandler/packages.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.AuditingStore/Abplus.MqMessages.AuditingStore.csproj ================================================  Debug AnyCPU {B1585B83-25A5-4C8C-A384-B1205E459C16} Library Properties Abp Abplus.MqMessages.AuditingStore v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Abplus.0.1.7.6\lib\net461\Abplus.dll ..\..\packages\Abplus.MqMessages.RebusCore.0.1.6.3\lib\net461\Abplus.MqMessages.RebusCore.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\Rebus.4.2.1\lib\net45\Rebus.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.MqMessages.AuditingStore/Abplus.MqMessages.AuditingStore.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.MqMessages.AuditingStore/Auditing/AuditingStores/AuditInfoMqMessage.cs ================================================ using System; namespace Abp.Auditing.AuditingStores { public class AuditInfoMqMessage { /// /// TenantId. /// public int? TenantId { get; set; } /// /// UserId. /// public long? UserId { get; set; } /// /// ImpersonatorUserId. /// public long? ImpersonatorUserId { get; set; } /// /// ImpersonatorTenantId. /// public int? ImpersonatorTenantId { get; set; } /// /// Service (class/interface) name. /// public string ServiceName { get; set; } /// /// Executed method name. /// public string MethodName { get; set; } /// /// Calling parameters. /// public string Parameters { get; set; } /// /// Start time of the method execution. /// public DateTime ExecutionTime { get; set; } /// /// Total duration of the method call. /// public int ExecutionDuration { get; set; } /// /// IP address of the client. /// public string ClientIpAddress { get; set; } /// /// Name (generally computer name) of the client. /// public string ClientName { get; set; } /// /// Browser information if this method is called in a web request. /// public string BrowserInfo { get; set; } /// /// Optional custom data that can be filled and used. /// public string CustomData { get; set; } /// /// /// public string Exception { get; set; } } } ================================================ FILE: src2/Abplus.MqMessages.AuditingStore/Auditing/AuditingStores/MqMessageAuditingStore.cs ================================================ using System; using System.Threading.Tasks; using Abp.Dependency; using Abp.MqMessages; namespace Abp.Auditing.AuditingStores { public class MqMessageAuditingStore : IAuditingStore, ITransientDependency { private readonly Lazy MqMessagePublisher;//why this need Lazy<>? public MqMessageAuditingStore() { MqMessagePublisher = new Lazy(() => { return IocManager.Instance.Resolve(); }); } public async Task SaveAsync(AuditInfo auditInfo) { var mqMsgAuditInfo = new AuditInfoMqMessage { BrowserInfo = auditInfo.BrowserInfo, ClientIpAddress = auditInfo.ClientIpAddress, ClientName = auditInfo.ClientName, CustomData = auditInfo.CustomData, ExecutionDuration = auditInfo.ExecutionDuration, ImpersonatorTenantId = auditInfo.ImpersonatorTenantId, ImpersonatorUserId = auditInfo.ImpersonatorUserId, MethodName = auditInfo.MethodName, Parameters = auditInfo.Parameters, ServiceName = auditInfo.ServiceName, UserId = auditInfo.UserId, ExecutionTime = auditInfo.ExecutionTime, TenantId = auditInfo.TenantId }; if (auditInfo.Exception != null) { mqMsgAuditInfo.CustomData += $" {auditInfo.Exception.Message}"; mqMsgAuditInfo.Exception = auditInfo.Exception.StackTrace; if (auditInfo.Exception.InnerException != null) { mqMsgAuditInfo.CustomData += $" {auditInfo.Exception.InnerException.Message}"; mqMsgAuditInfo.Exception = auditInfo.Exception.InnerException.StackTrace; } } await MqMessagePublisher.Value.PublishAsync(mqMsgAuditInfo); } } } ================================================ FILE: src2/Abplus.MqMessages.AuditingStore/Auditing/AuditingStores/MqMessageAuditingStoreModule.cs ================================================ using Abp.Modules; using Abp.MqMessages.Publishers; namespace Abp.Auditing.AuditingStores { [DependsOn(typeof(RebusRabbitMqPublisherCoreModule))] public class MqMessageAuditingStoreModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } } } ================================================ FILE: src2/Abplus.MqMessages.AuditingStore/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.MqMessages.AuditingStore")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.MqMessages.AuditingStore")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("b1585b83-25a5-4c8c-a384-b1205e459c16")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.MqMessages.AuditingStore/app.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.AuditingStore/packages.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.IndexToES/Abplus.MqMessages.IndexToES.csproj ================================================  Debug AnyCPU {47D3D635-4801-4D88-8AB5-B933FBFB8BA6} Library Properties Abp Abplus.MqMessages.IndexToES v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\Elasticsearch.Net.6.0.2\lib\net46\Elasticsearch.Net.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\NEST.6.0.2\lib\net46\Nest.dll ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\Rebus.4.2.1\lib\net45\Rebus.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll MqMessageIndexToESHandlerBuilder.tt True True {f0ece646-29f7-48eb-ab40-6d238f785b73} Abplus.MqMessages TextTemplatingFileGenerator MqMessageIndexToESHandlerBuilder.cs 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.MqMessages.IndexToES/Abplus.MqMessages.IndexToES.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.MqMessages.IndexToES/DateTimeExtensions.cs ================================================ using System; namespace Abp { public static class DateTimeExtensions { public static string GetESIndexName(this DateTime now, string defaultIndexName, IndexFreq freqSetting) { Check.NotNullOrWhiteSpace(defaultIndexName, nameof(defaultIndexName)); if (freqSetting == IndexFreq.PerDay) { return $"{defaultIndexName}-{DateTime.Now.Date.ToString("yyyy.MM.dd")}"; } else if (freqSetting == IndexFreq.PerMonth) { return $"{defaultIndexName}-{DateTime.Now.Date.ToString("yyyy.MM")}"; } else if (freqSetting == IndexFreq.PerYear) { return $"{defaultIndexName}-{DateTime.Now.Date.ToString("yyyy")}"; } else { return defaultIndexName; } } } } ================================================ FILE: src2/Abplus.MqMessages.IndexToES/IndexFreq.cs ================================================ namespace Abp { /// /// 定义创建索引的频率 /// public enum IndexFreq { /// /// 每天一个索引 /// PerDay = 0, /// /// 每月一个索引 /// PerMonth = 1, /// /// 每年一个索引 /// PerYear = 2, /// /// 仅一个索引,索引名不加日期后缀 /// None = 3 } } ================================================ FILE: src2/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/MqMessageIndexToESHandlerBase.cs ================================================ using System; using System.Threading.Tasks; using Abp.Dependency; using Nest; using Rebus.Handlers; namespace Abp.MqMessages.MqHandlers { public abstract class MqMessageIndexToESHandlerBase : AbpMqHandlerBase , IHandleMessages , ITransientDependency where TMqMessage : class { protected string DefaultIndexName { get; set; } protected IndexFreq IndexFreq { get; set; } public IElasticClient ElasticClient { get; set; } public MqMessageIndexToESHandlerBase(string defaultIndexName, IndexFreq indexFreq, string localizationSourceName) : base(localizationSourceName) { DefaultIndexName = defaultIndexName; IndexFreq = indexFreq; } public async Task Handle(TMqMessage message) { var indexName = CustomIndexName(); var indexFreq = CustomIndexFreq(); await ElasticClient.IndexAsync(message, i => i.Index(DateTime.Now.GetESIndexName(indexName, indexFreq))); } public virtual string CustomIndexName() { return DefaultIndexName; } public virtual IndexFreq CustomIndexFreq() { return IndexFreq; } } } ================================================ FILE: src2/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/MqMessageIndexToESHandlerBuilder.cs ================================================ ================================================ FILE: src2/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/MqMessageIndexToESHandlerBuilder.tt ================================================ <#@ template debug="false" hostspecific="true" language="C#" #> <#@ include file="T4MultipleOutputManager.ttinclude" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.IO" #> <#@ assembly name="$(SolutionDir)packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll" #> <#@ assembly name="$(ProjectDir)bin\$(ConfigurationName)\$(ProjectName).exe" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="Newtonsoft.Json" #> <#@ import namespace="Newtonsoft.Json.Linq" #> <#@ import namespace="System.Globalization" #> <#@ import namespace="Abp.MqMessages.MqHandlers" #> <#@ output extension=".cs" #> <# var tempateManager = Manager.Create(Host,GenerationEnvironment); string projectName = Host.ResolveAssemblyReference("$(ProjectName)"); var types=MqMessagesT4Register.MqMessageTypes; foreach(var type in types) { tempateManager.StartNewFile(type.Name+"IndexToESHandler.cs"); #> using Abp; using Abp.MqMessages.MqHandlers; using <#=type.Namespace#>; namespace <#=projectName#>.MqMessages.MqHandlers { public class <#=type.Name#>IndexToESHandler : MqMessageIndexToESHandlerBase<<#=type.Name#>> { public <#=type.Name#>IndexToESHandler() : base(【DefaultIndexName】, IndexFreq.PerMonth, 【Consts.LocalizationSourceName】) { } } } <# }//foreach-end tempateManager.EndBlock(); tempateManager.Process(true); #> ================================================ FILE: src2/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/MqMessagesT4Register.cs ================================================ using System; namespace Abp.MqMessages.MqHandlers { public static class MqMessagesT4Register { public static Type[] MqMessageTypes = new Type[] { //typeof(SampleMqMessage) }; } } ================================================ FILE: src2/Abplus.MqMessages.IndexToES/MqMessages/MqHandlers/T4MultipleOutputManager.ttinclude ================================================ <#@ assembly name="System.Core" #><#@ assembly name="System.Data.Linq" #><#@ assembly name="EnvDTE" #><#@ assembly name="System.Xml" #><#@ assembly name="System.Xml.Linq" #><#@ import namespace="System.Collections.Generic" #><#@ import namespace="System.IO" #><#@ import namespace="System.Text" #><#@ import namespace="Microsoft.VisualStudio.TextTemplating" #><#+ // https://raw.github.com/damieng/DamienGKit // http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited // Manager class records the various blocks so it can split them up class Manager { private class Block { public String Name; public int Start, Length; public bool IncludeInDefault; } private Block currentBlock; private readonly List files = new List(); private readonly Block footer = new Block(); private readonly Block header = new Block(); private readonly ITextTemplatingEngineHost host; private readonly StringBuilder template; protected readonly List generatedFileNames = new List(); public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) { return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template); } public void StartNewFile(String name) { if (name == null) throw new ArgumentNullException("name"); CurrentBlock = new Block { Name = name }; } public void StartFooter(bool includeInDefault=true) { CurrentBlock = footer; footer.IncludeInDefault = includeInDefault; } public void StartHeader(bool includeInDefault=true) { CurrentBlock = header; header.IncludeInDefault = includeInDefault; } public void EndBlock() { if (CurrentBlock == null) return; CurrentBlock.Length = template.Length - CurrentBlock.Start; if (CurrentBlock != header && CurrentBlock != footer) files.Add(CurrentBlock); currentBlock = null; } public virtual void Process(bool split, bool sync =true) { if (split) { EndBlock(); String headerText = template.ToString(header.Start, header.Length); String footerText = template.ToString(footer.Start, footer.Length); String outputPath = Path.GetDirectoryName(host.TemplateFile); files.Reverse(); if (!footer.IncludeInDefault) template.Remove(footer.Start, footer.Length); foreach(Block block in files) { String fileName = Path.Combine(outputPath, block.Name); String content = headerText + template.ToString(block.Start, block.Length) + footerText; generatedFileNames.Add(fileName); CreateFile(fileName, content); template.Remove(block.Start, block.Length); } if (!header.IncludeInDefault) template.Remove(header.Start, header.Length); } } protected virtual void CreateFile(String fileName, String content) { if (IsFileContentDifferent(fileName, content)) File.WriteAllText(fileName, content); } public virtual String GetCustomToolNamespace(String fileName) { return null; } public virtual String DefaultProjectNamespace { get { return null; } } protected bool IsFileContentDifferent(String fileName, String newContent) { return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); } private Manager(ITextTemplatingEngineHost host, StringBuilder template) { this.host = host; this.template = template; } private Block CurrentBlock { get { return currentBlock; } set { if (CurrentBlock != null) EndBlock(); if (value != null) value.Start = template.Length; currentBlock = value; } } private class VSManager: Manager { private readonly EnvDTE.ProjectItem templateProjectItem; private readonly EnvDTE.DTE dte; private readonly Action checkOutAction; private readonly Action> projectSyncAction; public override String DefaultProjectNamespace { get { return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString(); } } public override String GetCustomToolNamespace(string fileName) { return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString(); } public override void Process(bool split, bool sync) { if (templateProjectItem.ProjectItems == null) return; base.Process(split, sync); if (sync) projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); } protected override void CreateFile(String fileName, String content) { if (IsFileContentDifferent(fileName, content)) { CheckoutFileIfRequired(fileName); File.WriteAllText(fileName, content); } } internal VSManager(ITextTemplatingEngineHost host, StringBuilder template) : base(host, template) { var hostServiceProvider = (IServiceProvider)host; if (hostServiceProvider == null) throw new ArgumentNullException("Could not obtain IServiceProvider"); dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); if (dte == null) throw new ArgumentNullException("Could not obtain DTE from host"); templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile); checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); } private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, List keepFileNames) { var keepFileNameSet = new HashSet(keepFileNames); var projectFiles = new Dictionary(); var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]) + "."; foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) projectFiles.Add(projectItem.FileNames[0], projectItem); // Remove unused items from the project foreach (var pair in projectFiles) if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix)) pair.Value.Delete(); // Add missing files to the project foreach(String fileName in keepFileNameSet) if (!projectFiles.ContainsKey(fileName)) templateProjectItem.ProjectItems.AddFromFile(fileName); } private void CheckoutFileIfRequired(String fileName) { var sc = dte.SourceControl; if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName)) checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); } } } #> ================================================ FILE: src2/Abplus.MqMessages.IndexToES/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.MqMessages.IndexToES")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.MqMessages.IndexToES")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("47d3d635-4801-4d88-8ab5-b933fbfb8ba6")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src2/Abplus.MqMessages.IndexToES/app.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.IndexToES/packages.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/Abplus.MqMessages.RebusConsumer.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/Abplus.MqMessages.RebusRabbitMqConsumer.csproj ================================================  Debug AnyCPU {9AF821F9-8F33-489D-97E9-3BA5127320DE} Library Properties Abp Abplus.MqMessages.RebusRabbitMqConsumer v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.2.0.0\lib\net461\Microsoft.Diagnostics.Tracing.EventSource.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll ..\..\packages\Rebus.4.2.1\lib\net45\Rebus.dll ..\..\packages\Rebus.Castle.Windsor.4.0.0\lib\net45\Rebus.CastleWindsor.dll ..\..\packages\Rebus.NewtonsoftJson.3.1.5\lib\NET45\Rebus.NewtonsoftJson.dll ..\..\packages\Rebus.RabbitMq.4.4.2\lib\net452\Rebus.RabbitMq.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll {220d5f17-f49b-4a66-b2ee-cf107ef0d9be} Abplus.MqMessages.RebusCore {1DE8D8D1-987D-4A9C-AEC5-FF0A9914BBD4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/Configuration/Startup/RebusRabbitMqConsumerConfigurationExtensions.cs ================================================ using Abp.MqMessages.Consumers; namespace Abp.Configuration.Startup { public static class RebusRabbitMqConsumerConfigurationExtensions { public static IRebusRabbitMqConsumerModuleConfig UseAbplusRebusRabbitMqConsumer(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abp.RebusRabbitMqConsumer", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/MqMessages/Consumers/IRebusRabbitMqConsumerModuleConfig.cs ================================================ using System; using System.Reflection; using Rebus.Config; using Rebus.Serialization; namespace Abp.MqMessages.Consumers { public interface IRebusRabbitMqConsumerModuleConfig { /// /// 是否启用,默认启用 /// bool Enabled { get; } /// /// RabbitMq连接字符串 /// string ConnectString { get; } /// /// 队列名 /// string QueueName { get; } /// /// 最大并行数 /// int MaxParallelism { get; } /// /// 最大Worker数 /// int NumberOfWorkers { get; } /// /// 消息审计是否开启,默认不开启 /// bool MessageAuditingEnabled { get; } /// /// 消息审计队列名,默认不启用 /// string MessageAuditingQueueName { get; } /// /// 包含RebusMqMessageHandler的程序集(自动订阅消息和自动注册handler) /// Assembly[] AssemblysIncludeRebusMqMessageHandlers { get; } /// /// 配置日志组件 /// Action LoggingConfigurer { get; } /// /// 其他选项配置 /// Action OptionsConfigurer { get; } /// /// 序列化组件配置 /// Action> SerializerConfigurer { get; } /// /// /// /// 是否启用,默认启用 /// IRebusRabbitMqConsumerModuleConfig Enable(bool enabled); /// /// /// /// RabbitMq连接字符串 /// IRebusRabbitMqConsumerModuleConfig ConnectTo(string connectString); /// /// /// /// 使用队列名 /// IRebusRabbitMqConsumerModuleConfig UseQueue(string queueName); /// /// /// /// 最大并行数 /// IRebusRabbitMqConsumerModuleConfig SetMaxParallelism(int maxParallelism); /// /// /// /// 最大Worker数 /// IRebusRabbitMqConsumerModuleConfig SetNumberOfWorkers(int numberOfWorkers); /// /// 启用消息审计 /// /// 消息审计队列名 /// IRebusRabbitMqConsumerModuleConfig EnableMessageAuditing(string messageAuditingQueueName); /// /// 注册Rebus Handlers /// /// 包含Rebus Handlers的程序集 /// IRebusRabbitMqConsumerModuleConfig RegisterHandlerInAssemblys(params Assembly[] assemblys); /// /// 配置日志组件 /// /// /// IRebusRabbitMqConsumerModuleConfig UseLogging(Action loggingConfigurer); /// /// 配置其他选项 /// /// /// IRebusRabbitMqConsumerModuleConfig UseOptions(Action optionsConfigurer); /// /// 配置序列化 /// /// /// IRebusRabbitMqConsumerModuleConfig UseSerializer(Action> serializerConfigurer); } } ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/MqMessages/Consumers/RebusRabbitMqConsumerModule.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Abp.Modules; using Abp.MqMessages.Publishers; using Rebus.Auditing.Messages; using Rebus.Bus; using Rebus.CastleWindsor; using Rebus.Config; using Rebus.Handlers; namespace Abp.MqMessages.Consumers { [DependsOn(typeof(RebusRabbitMqPublisherCoreModule))] public class RebusRabbitMqConsumerModule : AbpModule { private IBus _bus; public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { var moduleConfig = IocManager.Resolve(); if (moduleConfig.Enabled) { var rebusConfig = Configure.With(new CastleWindsorContainerAdapter(IocManager.IocContainer)); if (moduleConfig.LoggingConfigurer != null) { rebusConfig.Logging(moduleConfig.LoggingConfigurer); } rebusConfig.Serialization(moduleConfig.SerializerConfigurer); if (moduleConfig.OptionsConfigurer != null) { rebusConfig.Options(moduleConfig.OptionsConfigurer); } rebusConfig.Options(c => { c.SetMaxParallelism(moduleConfig.MaxParallelism); c.SetNumberOfWorkers(moduleConfig.NumberOfWorkers); }); if (moduleConfig.MessageAuditingEnabled) { rebusConfig.Options(o => o.EnableMessageAuditing(moduleConfig.MessageAuditingQueueName)); } var mqMessageTypes = new List(); //Register handlers first! foreach (var assembly in moduleConfig.AssemblysIncludeRebusMqMessageHandlers) { IocManager.IocContainer.AutoRegisterHandlersFromAssembly(assembly); mqMessageTypes.AddRange(assembly.GetTypes() .Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandleMessages<>))) .SelectMany(t => t.GetInterfaces()) .Distinct() .SelectMany(t => t.GetGenericArguments()) .Distinct()); } _bus = rebusConfig.Transport(c => c.UseRabbitMq(moduleConfig.ConnectString, moduleConfig.QueueName)) .Start(); //Subscribe messages mqMessageTypes = mqMessageTypes.Distinct().ToList(); foreach (var mqMessageType in mqMessageTypes) { _bus.Subscribe(mqMessageType); } } } public override void Shutdown() { if (_bus != null) { _bus.Dispose(); } } } } ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/MqMessages/Consumers/RebusRabbitMqConsumerModuleConfig.cs ================================================ using System; using System.Reflection; using Newtonsoft.Json; using Rebus.Config; using Rebus.NewtonsoftJson; using Rebus.Serialization; namespace Abp.MqMessages.Consumers { public class RebusRabbitMqConsumerModuleConfig : IRebusRabbitMqConsumerModuleConfig { public RebusRabbitMqConsumerModuleConfig() { Enabled = true; MessageAuditingEnabled = false; MaxParallelism = 1; NumberOfWorkers = 1; SerializerConfigurer = c => c.UseNewtonsoftJson(new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); } public Assembly[] AssemblysIncludeRebusMqMessageHandlers { get; private set; } public string ConnectString { get; private set; } public bool Enabled { get; private set; } public Action LoggingConfigurer { get; private set; } public int MaxParallelism { get; private set; } public bool MessageAuditingEnabled { get; private set; } public string MessageAuditingQueueName { get; private set; } public int NumberOfWorkers { get; private set; } public Action OptionsConfigurer { get; private set; } public string QueueName { get; private set; } public Action> SerializerConfigurer { get; private set; } public IRebusRabbitMqConsumerModuleConfig ConnectTo(string connectString) { ConnectString = connectString; return this; } public IRebusRabbitMqConsumerModuleConfig Enable(bool enabled) { Enabled = enabled; return this; } public IRebusRabbitMqConsumerModuleConfig EnableMessageAuditing(string messageAuditingQueueName) { MessageAuditingEnabled = true; MessageAuditingQueueName = messageAuditingQueueName; return this; } public IRebusRabbitMqConsumerModuleConfig RegisterHandlerInAssemblys(params Assembly[] assemblys) { AssemblysIncludeRebusMqMessageHandlers = assemblys; return this; } public IRebusRabbitMqConsumerModuleConfig SetMaxParallelism(int maxParallelism) { MaxParallelism = maxParallelism; return this; } public IRebusRabbitMqConsumerModuleConfig SetNumberOfWorkers(int numberOfWorkers) { NumberOfWorkers = numberOfWorkers; return this; } public IRebusRabbitMqConsumerModuleConfig UseLogging(Action loggingConfigurer) { LoggingConfigurer = loggingConfigurer; return this; } public IRebusRabbitMqConsumerModuleConfig UseOptions(Action optionsConfigurer) { OptionsConfigurer = optionsConfigurer; return this; } public IRebusRabbitMqConsumerModuleConfig UseQueue(string queueName) { QueueName = queueName; return this; } public IRebusRabbitMqConsumerModuleConfig UseSerializer(Action> serializerConfigurer) { SerializerConfigurer = serializerConfigurer; return this; } } } ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.MqMessages.RebusConsumer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.MqMessages.RebusConsumer")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("9af821f9-8f33-489d-97e9-3ba5127320de")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/app.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.RebusConsumer/packages.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.RebusCore/Abplus.MqMessages.RebusCore.csproj ================================================  Debug AnyCPU {220D5F17-F49B-4A66-B2EE-CF107EF0D9BE} Library Properties Abp Abplus.MqMessages.RebusCore v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\Rebus.4.2.1\lib\net45\Rebus.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.MqMessages.RebusCore/Abplus.MqMessages.RebusCore.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.MqMessages.RebusCore/MqMessages/Publishers/RebusRabbitMqPublisher.cs ================================================ using System.Threading.Tasks; using Abp.Json; using Abp.Runtime.Session; using Abp.Threading; using Castle.Core.Logging; using Rebus.Bus; namespace Abp.MqMessages.Publishers { public class RebusRabbitMqPublisher : IMqMessagePublisher { private readonly IBus _bus; public ILogger Logger { get; set; } public IAbpSession AbpSession { get; set; } public RebusRabbitMqPublisher(IBus bus) { _bus = bus; Logger = NullLogger.Instance; AbpSession = NullAbpSession.Instance; } public void Publish(object mqMessages) { TryFillSessionInfo(mqMessages); Logger.Debug(mqMessages.GetType().FullName + ":" + mqMessages.ToJsonString()); AsyncHelper.RunSync(() => _bus.Publish(mqMessages)); } private void TryFillSessionInfo(object mqMessages) { if (AbpSession.UserId.HasValue) { var operatorUserIdProperty = mqMessages.GetType().GetProperty("OperatorUserId"); if (operatorUserIdProperty != null && (operatorUserIdProperty.PropertyType == typeof(long?))) { operatorUserIdProperty.SetValue(mqMessages, AbpSession.UserId); } } if (AbpSession.TenantId.HasValue) { var tenantIdProperty = mqMessages.GetType().GetProperty("TenantId"); if (tenantIdProperty != null && (tenantIdProperty.PropertyType == typeof(int?))) { tenantIdProperty.SetValue(mqMessages, AbpSession.TenantId); } } } public async Task PublishAsync(object mqMessages) { Logger.Debug(mqMessages.GetType().FullName + ":" + mqMessages.ToJsonString()); await _bus.Publish(mqMessages); } } } ================================================ FILE: src2/Abplus.MqMessages.RebusCore/MqMessages/Publishers/RebusRabbitMqPublisherCoreModule.cs ================================================ using Abp.Modules; namespace Abp.MqMessages.Publishers { public class RebusRabbitMqPublisherCoreModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } } } ================================================ FILE: src2/Abplus.MqMessages.RebusCore/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.MqMessages.RebusRabbitMqCore")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.MqMessages.RebusRabbitMqCore")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("220d5f17-f49b-4a66-b2ee-cf107ef0d9be")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.MqMessages.RebusCore/app.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.RebusCore/packages.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/Abplus.MqMessages.RebusPublisher.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/Abplus.MqMessages.RebusRabbitMqPublisher.csproj ================================================  Debug AnyCPU {97AA3659-AE5C-4561-A4A0-51FB71144E03} Library Properties Abp Abplus.MqMessages.RebusRabbitMqPublisher v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.2.0.0\lib\net461\Microsoft.Diagnostics.Tracing.EventSource.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll ..\..\packages\Rebus.4.2.1\lib\net45\Rebus.dll ..\..\packages\Rebus.Castle.Windsor.4.0.0\lib\net45\Rebus.CastleWindsor.dll ..\..\packages\Rebus.RabbitMq.4.4.2\lib\net452\Rebus.RabbitMq.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll {220d5f17-f49b-4a66-b2ee-cf107ef0d9be} Abplus.MqMessages.RebusCore {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/Configuration/Startup/RebusRabbitMqPublisherConfigurationExtensions.cs ================================================ using Abp.MqMessages.Publishers; namespace Abp.Configuration.Startup { public static class RebusRabbitMqPublisherConfigurationExtensions { public static IRebusRabbitMqPublisherModuleConfig UseAbplusRebusRabbitMqPublisher(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abp.RebusRabbitMqPublisher", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/MqMessages/Publishers/IRebusRabbitMqPublisherModuleConfig.cs ================================================ using System; using Rebus.Config; namespace Abp.MqMessages.Publishers { public interface IRebusRabbitMqPublisherModuleConfig { /// /// 是否启用,默认启用 /// bool Enabled { get; } /// /// 日志配置委托 /// Action LoggingConfigurer { get; } /// /// RabbitMq连接字符串 /// string ConnectionString { get; } /// /// 消息审计是否开启,默认不开启 /// bool MessageAuditingEnabled { get; } /// /// 消息审计队列名,默认不启用 /// string MessageAuditingQueueName { get; } /// /// 是否启用,默认启用 /// /// /// IRebusRabbitMqPublisherModuleConfig Enable(bool enabled); /// /// 设置RabbitMq连接字符串 /// /// /// IRebusRabbitMqPublisherModuleConfig ConnectionTo(string connectionString); /// /// 配置日志组件 /// /// /// IRebusRabbitMqPublisherModuleConfig UseLogging(Action loggingConfigurer); /// /// 是否启用消息审计,默认不启用 /// /// 审计队列名 /// IRebusRabbitMqPublisherModuleConfig EnableMessageAuditing(string messageAuditingQueueName); } } ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/MqMessages/Publishers/RebusRabbitMqPublisherModule.cs ================================================ using System.Reflection; using Abp.Modules; using Rebus.Auditing.Messages; using Rebus.Bus; using Rebus.Config; namespace Abp.MqMessages.Publishers { [DependsOn(typeof(RebusRabbitMqPublisherCoreModule))] public class RebusRabbitMqPublisherModule : AbpModule { private IBus _bus; public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { var moduleConfig = IocManager.Resolve(); if (moduleConfig.Enabled) { var rebusConfig = Configure.With(new CastleWindsorContainerAdapter(IocManager.IocContainer)); if (moduleConfig.MessageAuditingEnabled) { rebusConfig.Options(o => o.EnableMessageAuditing(moduleConfig.MessageAuditingQueueName)); } if (moduleConfig.LoggingConfigurer != null) { rebusConfig.Logging(moduleConfig.LoggingConfigurer); } _bus = rebusConfig.Transport(t => t.UseRabbitMqAsOneWayClient(moduleConfig.ConnectionString)) .Start(); } } public override void Shutdown() { if (_bus != null) { _bus.Dispose(); } } } } ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/MqMessages/Publishers/RebusRabbitMqPublisherModuleConfig.cs ================================================ using System; using Rebus.Config; namespace Abp.MqMessages.Publishers { public class RebusRabbitMqPublisherModuleConfig : IRebusRabbitMqPublisherModuleConfig { public RebusRabbitMqPublisherModuleConfig() { Enabled = true; MessageAuditingEnabled = false; } public string ConnectionString { get; private set; } public bool Enabled { get; private set; } public Action LoggingConfigurer { get; private set; } public bool MessageAuditingEnabled { get; private set; } public string MessageAuditingQueueName { get; private set; } public IRebusRabbitMqPublisherModuleConfig ConnectionTo(string connectionString) { ConnectionString = connectionString; return this; } public IRebusRabbitMqPublisherModuleConfig Enable(bool enabled) { Enabled = enabled; return this; } public IRebusRabbitMqPublisherModuleConfig EnableMessageAuditing(string messageAuditingQueueName) { MessageAuditingEnabled = true; MessageAuditingQueueName = messageAuditingQueueName; return this; } public IRebusRabbitMqPublisherModuleConfig UseLogging(Action loggingConfigurer) { LoggingConfigurer = loggingConfigurer; return this; } } } ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.MqMessages.RebusRabbitMqPublisher")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.MqMessages.RebusRabbitMqPublisher")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("97aa3659-ae5c-4561-a4a0-51fb71144e03")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/app.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.RebusPublisher/packages.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.RedisStoreMessageTracker/Abplus.MqMessages.RedisStoreMessageTracker.csproj ================================================  Debug AnyCPU {0F4D2D6F-801A-49A5-8B17-1E188CA0C6F8} Library Properties Abp Abplus.MqMessages.RedisStoreMessageTracker v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Abp.RedisCache.3.7.2\lib\netstandard2.0\Abp.RedisCache.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\StackExchange.Redis.1.2.6\lib\net46\StackExchange.Redis.dll ..\..\packages\StackExchange.Redis.StrongName.1.2.6\lib\net46\StackExchange.Redis.StrongName.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.MqMessages.RedisStoreMessageTracker/Abplus.MqMessages.RedisStoreMessageTracker.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.MqMessages.RedisStoreMessageTracker/MqMessages/MessageTrackers/RedisStoreMessageTracker.cs ================================================ using System; using System.Threading.Tasks; using Abp.Extensions; using Abp.Runtime.Caching; namespace Abp.MqMessages.MessageTrackers { public class RedisStoreMessageTracker : IMessageTracker { private const string CacheKey = "Abplus.MqMessages.MessageTrackers.RedisStoreMessageTracker"; private readonly ICacheManager _cacheManager; public RedisStoreMessageTracker(ICacheManager cacheManager) { _cacheManager = cacheManager; } public async Task HasProcessed(string processId) { var value = await _cacheManager.GetCache(CacheKey).GetOrDefaultAsync(processId); return !value.IsNullOrWhiteSpace(); } public async Task MarkAsProcessed(string processId) { await _cacheManager.GetCache(CacheKey).SetAsync(processId, "1", TimeSpan.FromDays(30)); } } } ================================================ FILE: src2/Abplus.MqMessages.RedisStoreMessageTracker/MqMessages/MessageTrackers/RedisStoreMessageTrackerModule.cs ================================================ using Abp.Modules; using Abp.Runtime.Caching.Redis; namespace Abp.MqMessages.MessageTrackers { [DependsOn(typeof(AbpRedisCacheModule))] public class RedisStoreMessageTrackerModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { //IocManager.RegisterIfNot(DependencyLifeStyle.Singleton); //IocManager.RegisterIfNot(DependencyLifeStyle.Singleton); } } } ================================================ FILE: src2/Abplus.MqMessages.RedisStoreMessageTracker/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.MqMessages.RedisStoreMessageTracker")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.MqMessages.RedisStoreMessageTracker")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("0f4d2d6f-801a-49a5-8b17-1e188ca0c6f8")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src2/Abplus.MqMessages.RedisStoreMessageTracker/app.config ================================================  ================================================ FILE: src2/Abplus.MqMessages.RedisStoreMessageTracker/packages.config ================================================  ================================================ FILE: src2/Abplus.RebusRabbitmqConsumer/Abplus.RebusRabbitmqConsumer.csproj ================================================  Debug AnyCPU {32E6558A-DCDB-434C-B683-0EC88F1CEEAD} Library Properties Abp Abplus.RebusRabbitmqConsumer v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.RebusRabbitmqConsumer.XML ..\..\packages\Abp.1.4.2.0\lib\net452\Abp.dll True ..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True ..\..\packages\Castle.LoggingFacility.3.4.0\lib\net45\Castle.Facilities.Logging.dll True ..\..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\RabbitMQ.Client.4.1.1\lib\net451\RabbitMQ.Client.dll True ..\..\packages\Rebus.2.1.6\lib\NET45\Rebus.dll True ..\..\packages\Rebus.RabbitMq.2.0.0\lib\NET452\Rebus.RabbitMq.dll True ..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.RebusRabbitmqConsumer/Abplus.RebusRabbitmqConsumer.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.RebusRabbitmqConsumer/Configuration/Startup/AbpRebusRabbitMqConsumerConfigurationExtensions.cs ================================================ using Abp.Events.Consumer.RebusRabbitMq; namespace Abp.Configuration.Startup { public static class AbpRebusRabbitMqConsumerConfigurationExtensions { public static IAbpRebusRabbitMqConsumerModuleConfig AbpRebusRabbitMqConsumer(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abp.RebusRabbitMqConsumer", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src2/Abplus.RebusRabbitmqConsumer/Events/Consumer/RebusRabbitMq/AbpRebusRabbitMqConsumerModule.cs ================================================ using System; using System.Reflection; using Abp.Modules; using Rebus.Activation; using Rebus.Auditing.Messages; using Rebus.Config; using Rebus.RabbitMq; namespace Abp.Events.Consumer.RebusRabbitMq { [DependsOn(typeof(AbpKernelModule))] public class AbpRebusRabbitMqConsumerModule : AbpModule { public Action RegisterHandlers; public Action SubscribeEvents; public Action RebusConfigAppend; private BuiltinHandlerActivator _activator; public AbpRebusRabbitMqConsumerModule() { _activator = new BuiltinHandlerActivator(); } public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { var config = IocManager.Resolve(); RegisterHandlers(_activator); var rebusConfig = Configure.With(_activator); rebusConfig.Options(o => o.SetNumberOfWorkers(config.NumberOfWorkers)); rebusConfig.Options(o => o.SetMaxParallelism(config.MaxParallelism)); if (config.MessageAuditingEnabled) { rebusConfig.Options(o => o.EnableMessageAuditing(config.MessageAuditingQueueName)); } if (config.RebusLoggingConfig != null) { rebusConfig.Logging(config.RebusLoggingConfig); } RebusConfigAppend?.Invoke(rebusConfig); rebusConfig.Transport(t => t.UseRabbitMq(config.ConnectionString, config.QueueName)) .Start(); SubscribeEvents(_activator); } public override void Shutdown() { //base.Shutdown(); _activator.Bus.Dispose(); _activator.Dispose(); } } } ================================================ FILE: src2/Abplus.RebusRabbitmqConsumer/Events/Consumer/RebusRabbitMq/AbpRebusRabbitMqConsumerModuleConfig.cs ================================================  using System; using Rebus.Config; namespace Abp.Events.Consumer.RebusRabbitMq { public class AbpRebusRabbitMqConsumerModuleConfig : IAbpRebusRabbitMqConsumerModuleConfig { public string ConnectionString { get; private set; } public string QueueName { get; private set; } public int NumberOfWorkers { get; private set; } public int MaxParallelism { get; private set; } public bool MessageAuditingEnabled { get; private set; } public string MessageAuditingQueueName { get; private set; } public Action RebusLoggingConfig { get; private set; } public AbpRebusRabbitMqConsumerModuleConfig() { NumberOfWorkers = 1; MaxParallelism = 1; MessageAuditingEnabled = false; MessageAuditingQueueName = "Audit"; } public IAbpRebusRabbitMqConsumerModuleConfig Connect(string connectString) { ConnectionString = connectString; return this; } public IAbpRebusRabbitMqConsumerModuleConfig UseQueue(string queueName) { QueueName = queueName; return this; } public IAbpRebusRabbitMqConsumerModuleConfig SetNumberOfWorkers(int num) { NumberOfWorkers = num; return this; } public IAbpRebusRabbitMqConsumerModuleConfig SetMaxParallelism(int num) { MaxParallelism = num; return this; } public IAbpRebusRabbitMqConsumerModuleConfig EnableMessageAuditing() { MessageAuditingEnabled = true; return this; } public IAbpRebusRabbitMqConsumerModuleConfig SetMessageAuditingQueueName(string queueName) { MessageAuditingQueueName = queueName; return this; } public IAbpRebusRabbitMqConsumerModuleConfig SetRebusLoggingConfigurer(Action loggingConfigurer) { RebusLoggingConfig = loggingConfigurer; return this; } } } ================================================ FILE: src2/Abplus.RebusRabbitmqConsumer/Events/Consumer/RebusRabbitMq/IAbpRebusRabbitMqConsumerModuleConfig.cs ================================================  using System; using Rebus.Config; namespace Abp.Events.Consumer.RebusRabbitMq { public interface IAbpRebusRabbitMqConsumerModuleConfig { string ConnectionString { get; } string QueueName { get; } int NumberOfWorkers { get; } int MaxParallelism { get; } bool MessageAuditingEnabled { get; } string MessageAuditingQueueName { get; } Action RebusLoggingConfig { get; } IAbpRebusRabbitMqConsumerModuleConfig Connect(string connectString); IAbpRebusRabbitMqConsumerModuleConfig UseQueue(string queueName); IAbpRebusRabbitMqConsumerModuleConfig SetNumberOfWorkers(int num); IAbpRebusRabbitMqConsumerModuleConfig SetMaxParallelism(int num); IAbpRebusRabbitMqConsumerModuleConfig EnableMessageAuditing(); IAbpRebusRabbitMqConsumerModuleConfig SetMessageAuditingQueueName(string queueName); IAbpRebusRabbitMqConsumerModuleConfig SetRebusLoggingConfigurer(Action loggingConfigurer); } } ================================================ FILE: src2/Abplus.RebusRabbitmqConsumer/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.RebusRabbitmqConsumer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.RebusRabbitmqConsumer")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("32e6558a-dcdb-434c-b683-0ec88f1ceead")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.RebusRabbitmqConsumer/packages.config ================================================  ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/Abplus.RebusRabbitmqProducer.csproj ================================================  Debug AnyCPU {17DC37E5-6756-4462-AF34-674738762F0B} Library Properties Abp Abplus.RebusRabbitmqProducer v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.RebusRabbitmqProducer.XML ..\..\packages\Abp.1.4.2.0\lib\net452\Abp.dll True ..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True ..\..\packages\Castle.LoggingFacility.3.4.0\lib\net45\Castle.Facilities.Logging.dll True ..\..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\RabbitMQ.Client.4.1.1\lib\net451\RabbitMQ.Client.dll True ..\..\packages\Rebus.2.1.6\lib\NET45\Rebus.dll True ..\..\packages\Rebus.Castle.Windsor.2.0.1\lib\NET45\Rebus.CastleWindsor.dll True ..\..\packages\Rebus.RabbitMq.2.0.0\lib\NET452\Rebus.RabbitMq.dll True ..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True {e9957d88-655d-4411-98c3-c7d6009ba13c} Abplus.Events.Producer {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/Abplus.RebusRabbitmqProducer.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/Configuration/Startup/AbpRebusRabbitMqProducerConfigurationExtensions.cs ================================================ using Abp.Events.Producer.RebusRabbitMq; namespace Abp.Configuration.Startup { public static class AbpRebusRabbitMqProducerConfigurationExtensions { public static IAbpRebusRabbitMqProducerModuleConfig AbpRebusRabbitMqProducer(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abp.RebusRabbitMqProducer", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/Events/Producer/RebusRabbitMq/AbpRebusRabbitMqProducerModule.cs ================================================ using System.Reflection; using Abp.Modules; using Rebus.Bus; using Rebus.CastleWindsor; using Rebus.Config; using Rebus.RabbitMq; using Rebus.Auditing.Messages; namespace Abp.Events.Producer.RebusRabbitMq { [DependsOn(typeof(AbpEventsProducerModule))] public class AbpRebusRabbitMqProducerModule : AbpModule { private IBus _bus; public override void PreInitialize() { IocManager.Register(); IocManager.Register(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { var config = IocManager.Resolve(); if (config.Enabled) { var container = IocManager.IocContainer; var adapter = new CastleWindsorContainerAdapter(container); var rebusConfig = Configure.With(adapter); if (config.MessageAuditingEnabled) { rebusConfig.Options(o => o.EnableMessageAuditing(config.MessageAuditingQueueName)); } rebusConfig.Logging(config.RebusLoggingConfig); _bus = rebusConfig.Transport(t => t.UseRabbitMqAsOneWayClient(config.ConnectionString)) .Start(); } } public override void Shutdown() { if (_bus != null) { _bus.Dispose(); } } } } ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/Events/Producer/RebusRabbitMq/AbpRebusRabbitMqProducerModuleConfig.cs ================================================ using System; using Rebus.Config; namespace Abp.Events.Producer.RebusRabbitMq { internal class AbpRebusRabbitMqProducerModuleConfig : IAbpRebusRabbitMqProducerModuleConfig { public string ConnectionString { get; private set; } public bool Enabled { get; private set; } public bool MessageAuditingEnabled { get; private set; } public string MessageAuditingQueueName { get; private set; } public Action RebusLoggingConfig { get; private set; } public IAbpRebusRabbitMqProducerModuleConfig EnableMessageAuditing() { MessageAuditingEnabled = true; return this; } public IAbpRebusRabbitMqProducerModuleConfig SetMessageAuditingQueueName(string queueName) { MessageAuditingQueueName = queueName; return this; } public IAbpRebusRabbitMqProducerModuleConfig SetRebusLoggingConfigurer(Action loggingConfigurer) { RebusLoggingConfig = loggingConfigurer; return this; } public IAbpRebusRabbitMqProducerModuleConfig Enable() { Enabled = true; return this; } public IAbpRebusRabbitMqProducerModuleConfig Connect(string connectionString) { ConnectionString = connectionString; return this; } } } ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/Events/Producer/RebusRabbitMq/IAbpRebusRabbitMqProducerModuleConfig.cs ================================================ using System; using Rebus.Config; namespace Abp.Events.Producer.RebusRabbitMq { public interface IAbpRebusRabbitMqProducerModuleConfig { string ConnectionString { get; } bool Enabled { get; } bool MessageAuditingEnabled { get; } string MessageAuditingQueueName { get; } Action RebusLoggingConfig { get; } IAbpRebusRabbitMqProducerModuleConfig EnableMessageAuditing(); IAbpRebusRabbitMqProducerModuleConfig SetMessageAuditingQueueName(string queueName); IAbpRebusRabbitMqProducerModuleConfig SetRebusLoggingConfigurer(Action loggingConfigurer); IAbpRebusRabbitMqProducerModuleConfig Enable(); IAbpRebusRabbitMqProducerModuleConfig Connect(string connectionString); } } ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/Events/Producer/RebusRabbitMq/RebusRabbitMqProducer.cs ================================================ using Rebus.Bus; namespace Abp.Events.Producer.RebusRabbitMq { public class RebusRabbitMqProducer : IProducer { private IBus _bus; private IAbpRebusRabbitMqProducerModuleConfig _config; public RebusRabbitMqProducer(IBus bus, IAbpRebusRabbitMqProducerModuleConfig config) { _bus = bus; _config = config; } public void Publish(object events) { if (_config.Enabled) { _bus.Publish(events); } } } } ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.RebusRabbitmqProducer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.RebusRabbitmqProducer")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("17dc37e5-6756-4462-af34-674738762f0b")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/app.config ================================================  ================================================ FILE: src2/Abplus.RebusRabbitmqProducer/packages.config ================================================  ================================================ FILE: src2/Abplus.T4.PermissionsFromJson/Abplus.T4.PermissionsFromJson.csproj ================================================  Debug AnyCPU {84127C3A-3C37-4BB1-BCCD-AB62C3E2FE3E} Library Properties Abplus.T4.PermissionsFromJson Abplus.T4.PermissionsFromJson v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 True True PermissionBuilder.tt TextTemplatingFileGenerator PermissionBuilder.cs ================================================ FILE: src2/Abplus.T4.PermissionsFromJson/Abplus.T4.PermissionsFromJson.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.T4.PermissionsFromJson/Authorization/Builders/BuilderUtils.cs ================================================ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Dynamic; using System.Reflection; using Abp.Authorization; using Abp.Localization; using Abp.MultiTenancy; using Newtonsoft.Json; namespace 【YourCompany.YourProject】.Authorization { public static class BuilderUtils { public static void Build(IPermissionDefinitionContext context, string name) { var asm = Assembly.GetExecutingAssembly();//读取嵌入式资源 var sm = asm.GetManifestResourceStream("【YourCompany.YourProject】.Authorization.Builders.Permissions." + name + ".json"); var list = GetPermissionJson(sm); foreach (var item in list) { var module = context.CreatePermission( item.Name, new FixedLocalizableString(item.DisplayName), multiTenancySides: item.GetMultiTenancySides()); var children = item.GetChildren(); BuildChildrenPermission(children, module, item.Name); } } //供t4调用 public static Dictionary> GeneratePermission() { var dic = new Dictionary>(); var asm = Assembly.GetExecutingAssembly();//读取嵌入式资源 var jsons = asm.GetManifestResourceNames() .Where(c => c.StartsWith("【YourCompany.YourProject】.Authorization.Builders.Permissions") && c.EndsWith(".json")); foreach (var item in jsons) { var name = item.Replace("【YourCompany.YourProject】.Authorization.Builders.Permissions.", "") .Replace(".json", ""); var sm = asm.GetManifestResourceStream(item); var list = BuildPermissionConst(GetPermissionJson(sm)); dic.Add(name, list); } return dic; } private static List GetPermissionJson(Stream sm) { using (var reader = new StreamReader(sm)) { string text = reader.ReadToEnd(); var json = JsonConvert.DeserializeObject>(text).OrderBy(c => c.Order).ToList(); return json; } } private static void BuildChildrenPermission(List children, Permission module, string parentName) { foreach (var item in children) { var name = $"{parentName}.{item.Name}"; var itemModule = module.CreateChildPermission(name, new FixedLocalizableString(item.DisplayName), multiTenancySides: item.GetMultiTenancySides()); var itemchildren = item.GetChildren(); if (itemchildren.Any()) { BuildChildrenPermission(itemchildren, itemModule, name); } } } private static List BuildPermissionConst(List permissionJsons, string name = null, string value = null, string summary = null, List permissionConsts = null) { permissionConsts = permissionConsts ?? new List(); foreach (var item in permissionJsons) { var permissionConst = new PermissionConst { Summary = $"{summary}_{item.DisplayName}".Trim('_'), Name = $"{name}_{item.Name}".Trim('_').Replace('.', '_'), Value = $"{value}.{item.Name}".Trim('.').Replace('_', '.') }; permissionConsts.Add(permissionConst); var children = item.GetChildren(); if (children.Any()) { BuildPermissionConst(children, permissionConst.Name, permissionConst.Value, permissionConst.Summary, permissionConsts); } } return permissionConsts; } } public class PermissionJson { public PermissionJson() { Order = 100; } public string Name { get; set; } public string DisplayName { get; set; } public string Description { get; set; } [JsonProperty(PropertyName = "multiTenancySides")] public MultiTenancySides? MultiTenancySide { private get; set; } public bool DefaultPermission { private get; set; } public List Children { private get; set; } public int Order { get; set; } public List DisableOrder { get; set; } public List GetChildren() { Children = Children ?? new List(); DisableOrder = DisableOrder ?? new List(); if (DefaultPermission) { Children.Add(new PermissionJson { Name = "Create", DisplayName = "新增", Order = 10, DefaultPermission = false }); Children.Add(new PermissionJson { Name = "Edit", DisplayName = "编辑", Order = 20, DefaultPermission = false }); Children.Add(new PermissionJson { Name = "Delete", DisplayName = "删除", Order = 30, DefaultPermission = false }); } if (MultiTenancySide.HasValue) { Children.ForEach(c => { c.MultiTenancySide = MultiTenancySide.Value; }); } return Children.OrderBy(c => c.Order).Where(c => !DisableOrder.Contains(c.Order)).ToList(); } public MultiTenancySides GetMultiTenancySides() { if (MultiTenancySide.HasValue) { return MultiTenancySide.Value; } return MultiTenancySides.Tenant | MultiTenancySides.Host; } } public class PermissionConst { public string Summary { get; set; } public string Name { get; set; } public string Value { get; set; } } } ================================================ FILE: src2/Abplus.T4.PermissionsFromJson/Authorization/Builders/PermissionBuilder.cs ================================================ ================================================ FILE: src2/Abplus.T4.PermissionsFromJson/Authorization/Builders/PermissionBuilder.tt ================================================ <#@ template debug="false" hostspecific="true" language="C#" #> <#@ include file="T4MultipleOutputManager.ttinclude" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.IO" #> <#@ assembly name="$(SolutionDir)packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll" #> <#@ assembly name="$(ProjectDir)bin\$(ConfigurationName)\【YourCompany.YourProject】.Core.dll" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="Newtonsoft.Json" #> <#@ import namespace="Newtonsoft.Json.Linq" #> <#@ import namespace="System.Globalization" #> <#@ import namespace="【YourCompany.YourProject】.Authorization" #> <#@ output extension=".cs" #> <# var tempateManager = Manager.Create(Host,GenerationEnvironment); string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)"); string projectPath = Host.ResolveAssemblyReference("$(ProjectDir)"); var dic = BuilderUtils.GeneratePermission(); foreach(var item in dic) { var list= item.Value; tempateManager.StartNewFile(item.Key+"Permissions.cs"); #> namespace 【YourCompany.YourProject】.Authorization { /// /// Permissions definition /// public static class <#=item.Key #>Permissions { <# foreach(var item1 in list){ #> /// /// <#=item1.Summary #> /// public const string <#=item1.Name #> = "<#=item1.Value #>"; <# } #> } } <# } tempateManager.EndBlock(); tempateManager.Process(true); #> ================================================ FILE: src2/Abplus.T4.PermissionsFromJson/Authorization/Builders/Permissions/Sample.json ================================================ [ { "name": "User", "displayName": "用户中心", "children": [ { "name": "UserInfo", "displayName": "用户管理", "defaultPermission": false }, { "name": "UserIdCard", "displayName": "身份信息管理", "defaultPermission": false, "children": [ { "name": "Reviewed", "displayName": "审核/编辑" } ] } ] } ] ================================================ FILE: src2/Abplus.T4.PermissionsFromJson/Authorization/Builders/T4MultipleOutputManager.ttinclude ================================================ <#@ assembly name="System.Core" #><#@ assembly name="System.Data.Linq" #><#@ assembly name="EnvDTE" #><#@ assembly name="System.Xml" #><#@ assembly name="System.Xml.Linq" #><#@ import namespace="System.Collections.Generic" #><#@ import namespace="System.IO" #><#@ import namespace="System.Text" #><#@ import namespace="Microsoft.VisualStudio.TextTemplating" #><#+ // https://raw.github.com/damieng/DamienGKit // http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited // Manager class records the various blocks so it can split them up class Manager { private class Block { public String Name; public int Start, Length; public bool IncludeInDefault; } private Block currentBlock; private readonly List files = new List(); private readonly Block footer = new Block(); private readonly Block header = new Block(); private readonly ITextTemplatingEngineHost host; private readonly StringBuilder template; protected readonly List generatedFileNames = new List(); public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) { return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template); } public void StartNewFile(String name) { if (name == null) throw new ArgumentNullException("name"); CurrentBlock = new Block { Name = name }; } public void StartFooter(bool includeInDefault=true) { CurrentBlock = footer; footer.IncludeInDefault = includeInDefault; } public void StartHeader(bool includeInDefault=true) { CurrentBlock = header; header.IncludeInDefault = includeInDefault; } public void EndBlock() { if (CurrentBlock == null) return; CurrentBlock.Length = template.Length - CurrentBlock.Start; if (CurrentBlock != header && CurrentBlock != footer) files.Add(CurrentBlock); currentBlock = null; } public virtual void Process(bool split, bool sync =true) { if (split) { EndBlock(); String headerText = template.ToString(header.Start, header.Length); String footerText = template.ToString(footer.Start, footer.Length); String outputPath = Path.GetDirectoryName(host.TemplateFile); files.Reverse(); if (!footer.IncludeInDefault) template.Remove(footer.Start, footer.Length); foreach(Block block in files) { String fileName = Path.Combine(outputPath, block.Name); String content = headerText + template.ToString(block.Start, block.Length) + footerText; generatedFileNames.Add(fileName); CreateFile(fileName, content); template.Remove(block.Start, block.Length); } if (!header.IncludeInDefault) template.Remove(header.Start, header.Length); } } protected virtual void CreateFile(String fileName, String content) { if (IsFileContentDifferent(fileName, content)) File.WriteAllText(fileName, content); } public virtual String GetCustomToolNamespace(String fileName) { return null; } public virtual String DefaultProjectNamespace { get { return null; } } protected bool IsFileContentDifferent(String fileName, String newContent) { return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); } private Manager(ITextTemplatingEngineHost host, StringBuilder template) { this.host = host; this.template = template; } private Block CurrentBlock { get { return currentBlock; } set { if (CurrentBlock != null) EndBlock(); if (value != null) value.Start = template.Length; currentBlock = value; } } private class VSManager: Manager { private readonly EnvDTE.ProjectItem templateProjectItem; private readonly EnvDTE.DTE dte; private readonly Action checkOutAction; private readonly Action> projectSyncAction; public override String DefaultProjectNamespace { get { return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString(); } } public override String GetCustomToolNamespace(string fileName) { return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString(); } public override void Process(bool split, bool sync) { if (templateProjectItem.ProjectItems == null) return; base.Process(split, sync); if (sync) projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); } protected override void CreateFile(String fileName, String content) { if (IsFileContentDifferent(fileName, content)) { CheckoutFileIfRequired(fileName); File.WriteAllText(fileName, content); } } internal VSManager(ITextTemplatingEngineHost host, StringBuilder template) : base(host, template) { var hostServiceProvider = (IServiceProvider)host; if (hostServiceProvider == null) throw new ArgumentNullException("Could not obtain IServiceProvider"); dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); if (dte == null) throw new ArgumentNullException("Could not obtain DTE from host"); templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile); checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); } private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, List keepFileNames) { var keepFileNameSet = new HashSet(keepFileNames); var projectFiles = new Dictionary(); var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]) + "."; foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) projectFiles.Add(projectItem.FileNames[0], projectItem); // Remove unused items from the project foreach (var pair in projectFiles) if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix)) pair.Value.Delete(); // Add missing files to the project foreach(String fileName in keepFileNameSet) if (!projectFiles.ContainsKey(fileName)) templateProjectItem.ProjectItems.AddFromFile(fileName); } private void CheckoutFileIfRequired(String fileName) { var sc = dte.SourceControl; if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName)) checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); } } } #> ================================================ FILE: src2/Abplus.T4.PermissionsFromJson/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.T4.PermissionsFromJson")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.T4.PermissionsFromJson")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("84127c3a-3c37-4bb1-bccd-ab62c3e2fe3e")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.1")] [assembly: AssemblyFileVersion("1.0.0.1")] ================================================ FILE: src2/Abplus.Web.Api/Abplus.Web.Api.csproj ================================================  Debug AnyCPU {84D80055-6A95-4DE3-B1E7-68B88838F2BE} Library Properties Abp Abplus.Web.Api v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.Web.Api.XML ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.4\lib\net45\System.Net.Http.Formatting.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.4\lib\net45\System.Web.Http.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.Web.Api/Abplus.Web.Api.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.Web.Api/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.Web.Api")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.Web.Api")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("84d80055-6a95-4de3-b1e7-68b88838f2be")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.Web.Api/WebApi/JsonMediaTypeFormatterExtension.cs ================================================ using System.Net.Http.Formatting; using Abp.Json; namespace Abp.WebApi { public static class JsonMediaTypeFormatterExtension { public static void SetCustomDateFormatString(this JsonMediaTypeFormatter formatter, string dateTimeFormat) { var converters = formatter.SerializerSettings.Converters; foreach (var converter in converters) { if (converter is AbpDateTimeConverter) { var tmpConverter = converter as AbpDateTimeConverter; tmpConverter.DateTimeFormat = dateTimeFormat; } } } } } ================================================ FILE: src2/Abplus.Web.Api/WebApiVersionRoute/RoutingConstraints/VersionConstraint.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Web.Http.Routing; namespace Abplus.WebApiVersionRoute.RoutingConstraints { public class VersionConstraint : IHttpRouteConstraint { public static Version DefaultClientMinVersion = new Version(VersionConsts.DefaultClientMinVersionString); public static Version DefaultClientMaxVersion = new Version(VersionConsts.DefaultClientMaxVersionString); private static SysCode DefaultSysCode = SysCode.H5;//请求端未声明SysCode时,默认为H5 public VersionConstraint(int allowedVersion, SysCode allowedSysCode, List allowedClientVersionRangeList) { AllowedVersion = allowedVersion; AllowedSysCode = allowedSysCode; AllowedClientVersionRangeList = allowedClientVersionRangeList; } public List AllowedClientVersionRangeList { get; private set; } public int AllowedVersion { get; private set; } public SysCode AllowedSysCode { get; private set; } public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary values, HttpRouteDirection routeDirection) { return MatchClientVersion(request, routeDirection) && MatchApiVersion(request, routeDirection) && MatchSysCode(request, routeDirection); } private bool MatchSysCode(HttpRequestMessage request, HttpRouteDirection routeDirection) { if (routeDirection == HttpRouteDirection.UriResolution) { var sysCode = GetSysCodeHeader(request) ?? DefaultSysCode;//请求方未声明则默认为H5 return (sysCode & AllowedSysCode) == sysCode; } return false; } private bool MatchApiVersion(HttpRequestMessage request, HttpRouteDirection routeDirection) { if (routeDirection == HttpRouteDirection.UriResolution) { int apiVersion = GetApiVersionHeader(request) ?? VersionConsts.DefaultApiMinVersion;//请求方未声明,则为1 return (apiVersion == AllowedVersion); } return false; } private bool MatchClientVersion(HttpRequestMessage request, HttpRouteDirection routeDirection) { if (routeDirection == HttpRouteDirection.UriResolution) { if (!AllowedClientVersionRangeList.Any()) { throw new Exception("AllowedClientVersionRange is empty!"); } Version clientVersion = GetClientVersionHeader(request) ?? DefaultClientMinVersion;//请求方未声明,则为1.0.0 if (clientVersion == null) { clientVersion = DefaultClientMinVersion; } foreach (var range in AllowedClientVersionRangeList) { if (range.MinVersion.CompareTo(clientVersion) <= 0 && range.MaxVersion.CompareTo(clientVersion) >= 0) { return true; } } return false; } return false; } private Version GetClientVersionHeader(HttpRequestMessage request) { string clientVersionAsString; IEnumerable headerValue; if (request.Headers.TryGetValues(VersionConsts.ClientVersionHeaderName, out headerValue) && headerValue.Count() == 1) { clientVersionAsString = headerValue.First(); } else { return null; } if (string.IsNullOrWhiteSpace(clientVersionAsString)) { return null; } return new Version(clientVersionAsString); } private SysCode? GetSysCodeHeader(HttpRequestMessage request) { string sysCodeAsString; IEnumerable headerValue; if (request.Headers.TryGetValues(VersionConsts.SysCodeHeaderName, out headerValue) && headerValue.Count() == 1) { sysCodeAsString = headerValue.First(); } else { return null; } SysCode tag; if (sysCodeAsString != null && Enum.TryParse(sysCodeAsString, out tag)) { return tag; } return null; } private int? GetApiVersionHeader(HttpRequestMessage request) { string apiVersionAsString; IEnumerable headerValues; if (request.Headers.TryGetValues(VersionConsts.VersionHeaderName, out headerValues) && headerValues.Count() == 1) { apiVersionAsString = headerValues.First(); } else { return null; } int version; if (apiVersionAsString != null && Int32.TryParse(apiVersionAsString, out version)) { return version; } return null; } } } ================================================ FILE: src2/Abplus.Web.Api/WebApiVersionRoute/RoutingConstraints/VersionedRoute.cs ================================================ using System.Collections.Generic; using System.Web.Http.Routing; namespace Abplus.WebApiVersionRoute.RoutingConstraints { public class VersionedRoute : RouteFactoryAttribute { private static string DefaultAllowedClientVersionRange = VersionConsts.DefaultClientMinVersionString + "-" + VersionConsts.DefaultClientMaxVersionString; private static SysCode DefaultAllowedSysCode = SysCode.H5 | SysCode.IPhone | SysCode.Android; private const int DefaultAllowedApiVersion = 1; #region 构造函数 #region 单参构造 public VersionedRoute(string template) : this(template, DefaultAllowedApiVersion) { } #endregion #region 双参构造 public VersionedRoute(string template, int apiVersion) : this(template, apiVersion, DefaultAllowedSysCode) { } public VersionedRoute(string template, SysCode allowedTags) : this(template, DefaultAllowedApiVersion, allowedTags) { } #endregion #region 三参构造 public VersionedRoute(string template, int apiVersion, SysCode allowedTags) : this(template, apiVersion, allowedTags, DefaultAllowedClientVersionRange) { } public VersionedRoute(string template, int apiVersion, params string[] allowedClientVersionRangeString) : this(template, apiVersion, DefaultAllowedSysCode, allowedClientVersionRangeString) { } public VersionedRoute(string template, SysCode allowedTags, params string[] allowedClientVersionRangeString) : this(template, DefaultAllowedApiVersion, DefaultAllowedSysCode, allowedClientVersionRangeString) { } #endregion public VersionedRoute(string template, int apiVersion, SysCode allowedTags, params string[] allowedClientVersionRangeString) : base(template) { AllowedClientVersionRangeList = new List(); foreach (var rangeString in allowedClientVersionRangeString) { AllowedClientVersionRangeList.Add(VersionRange.CreateVersionRangeFromString(rangeString)); } AllowedTags = allowedTags; ApiVersion = apiVersion; } #endregion public List AllowedClientVersionRangeList { get; private set; } /// /// 接口的版本号 /// public int ApiVersion { get; private set; } /// /// 接口的设备区分标签 /// public SysCode AllowedTags { get; private set; } public override IDictionary Constraints { get { var constraints = new HttpRouteValueDictionary(); constraints.Add("version", new VersionConstraint(ApiVersion, AllowedTags, AllowedClientVersionRangeList)); return constraints; } } } } ================================================ FILE: src2/Abplus.Web.Api/WebApiVersionRoute/SysCode.cs ================================================ using System; namespace Abplus.WebApiVersionRoute { [Flags] public enum SysCode : long { H5 = 0x1 << 0, Android = 0x1 << 1, IPhone = 0x1 << 2 } } ================================================ FILE: src2/Abplus.Web.Api/WebApiVersionRoute/Version.cs ================================================ using System; using System.Collections.Generic; using System.Linq; namespace Abplus.WebApiVersionRoute { public class Version : IComparable { public Version(string version) { VersionNumberList = new List(); version.Split(new string[] { "." }, StringSplitOptions.None).ToList() .ForEach((s) => { VersionNumberList.Add(int.Parse(s)); }); } public List VersionNumberList { get; private set; } public int CompareTo(Version other) { if (this.VersionNumberList.Count == other.VersionNumberList.Count) { for (int i = 0; i < this.VersionNumberList.Count; i++) { var thisVersionNumber = this.VersionNumberList[i]; var otherVersionNumber = other.VersionNumberList[i]; if (thisVersionNumber == otherVersionNumber) { continue; } if (thisVersionNumber < otherVersionNumber) { return -1; } if (thisVersionNumber > otherVersionNumber) { return 1; } } return 0; } else { throw new Exception("version format not same!"); } } } } ================================================ FILE: src2/Abplus.Web.Api/WebApiVersionRoute/VersionConsts.cs ================================================ namespace Abplus.WebApiVersionRoute { public class VersionConsts { public const string ClientVersionHeaderName = "Abplus-ClientVersion"; public const string VersionHeaderName = "Abplus-ApiVersion"; public const string SysCodeHeaderName = "Abplus-SysCode"; public const string DefaultClientMinVersionString = "1.0.0"; public const string DefaultClientMaxVersionString = "9999.9999.9999"; public const int DefaultApiMinVersion = 1; } } ================================================ FILE: src2/Abplus.Web.Api/WebApiVersionRoute/VersionRange.cs ================================================ using System; using System.Linq; namespace Abplus.WebApiVersionRoute { public class VersionRange { public VersionRange(string minVersionString, string maxVersionString) : this(new Version(minVersionString), new Version(maxVersionString)) { } public VersionRange(Version min, Version max) { if (min == null) { throw new ArgumentNullException("min is null!"); } if (max == null) { throw new ArgumentNullException("max is null!"); } MinVersion = min; MaxVersion = max; ThrowIfMaxVersionLessThenMinVersion(); } private void ThrowIfMaxVersionLessThenMinVersion() { if (MaxVersion.CompareTo(MinVersion) < 0) { throw new Exception("MaxVersion < MinVersion !"); } } public Version MinVersion { get; private set; } public Version MaxVersion { get; private set; } public static VersionRange CreateVersionRangeFromString(string versionRangeString) { var minVersion = CreateMinVersionFromString(versionRangeString); var maxVersion = CreateMaxVersionFromString(versionRangeString); return new VersionRange(minVersion, maxVersion); } public static Version CreateMinVersionFromString(string versionRangeString) { if (string.IsNullOrWhiteSpace(versionRangeString)) { throw new ArgumentNullException("versionRangeString is empty!"); } var versionFirstToken = versionRangeString.Split('-').First(); if (versionFirstToken == "*") { versionFirstToken = VersionConsts.DefaultClientMinVersionString; } return new Version(versionFirstToken); } public static Version CreateMaxVersionFromString(string versionRangeString) { if (string.IsNullOrWhiteSpace(versionRangeString)) { throw new ArgumentNullException("versionRangeString is empty!"); } var versionTokens = versionRangeString.Split('-'); if (versionTokens.Length > 1) { if (versionTokens[1] == "*") { return new Version(VersionConsts.DefaultClientMaxVersionString); } else { return new Version(versionTokens[1]); } } else { return new Version(versionTokens[0]); } } } } ================================================ FILE: src2/Abplus.Web.Api/app.config ================================================  ================================================ FILE: src2/Abplus.Web.Api/packages.config ================================================  ================================================ FILE: src2/Abplus.Web.PlugIns/Abplus.Web.PlugIns.csproj ================================================  Debug AnyCPU {E834592D-71F9-49A4-A4FB-017A83712255} Library Properties Abp Abplus.Web.PlugIns v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\packages\Abp.1.4.2.0\lib\net452\Abp.dll True ..\..\packages\Abp.Web.1.4.2.0\lib\net452\Abp.Web.dll True ..\..\packages\Abp.Web.Common.1.4.2.0\lib\net452\Abp.Web.Common.dll True ..\..\packages\Abp.Web.Mvc.1.4.2.0\lib\net452\Abp.Web.Mvc.dll True ..\..\packages\Castle.Core.3.3.0\lib\net45\Castle.Core.dll True ..\..\packages\Castle.LoggingFacility.3.4.0\lib\net45\Castle.Facilities.Logging.dll True ..\..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll True ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll True ..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll True ..\..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll True ..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll True ..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll True ..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll True {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.Web.PlugIns/Abplus.Web.PlugIns.csproj.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.Web.PlugIns/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.Web.PlugIns")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.Web.PlugIns")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("e834592d-71f9-49a4-a4fb-017a83712255")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(Abp.AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(Abp.AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.Web.PlugIns/Web/Mvc/AbpWebPlugInModule.cs ================================================ using System; using System.Linq; using System.Web.Mvc; using System.Web.Routing; using Abp.Extensions; using Abp.Modules; using Abp.PlugIns; using Abp.Web.Mvc.Controllers; namespace Abp.Web.Mvc { /// /// If web host enable plugins, you should place code: /// AbpBootstrapper.PlugInSources.Add(new FolderPlugInSource($"{AppDomain.CurrentDomain.BaseDirectory.EnsureEndsWith('\\')}Plugins", System.IO.SearchOption.AllDirectories)); /// before /// base.Application_Start(sender, e); /// in global.asax /// [DependsOn(typeof(AbpWebMvcModule))] public class AbpWebPlugInModule : AbpModule { private readonly IAbpPlugInManager _abpPlugInManager; public AbpWebPlugInModule(IAbpPlugInManager abpPlugInManager) { _abpPlugInManager = abpPlugInManager; } public override void PreInitialize() { var autoLoadTypes = _abpPlugInManager.PlugInSources.GetAllModules().Select(m => m.Assembly).Distinct().ToList() .SelectMany(a => a.GetTypes()) .Where(t => t != null && t.IsPublic && !t.IsAbstract && (typeof(IPlugInAreaRegistration).IsAssignableFrom(t) || typeof(IPlugInAuthorizationProvider).IsAssignableFrom(t) || typeof(IPlugInNavigationProvider).IsAssignableFrom(t)) ).ToList(); //Auto Load IPlugInAreaRegistration foreach (var item in autoLoadTypes.Where(t => typeof(IPlugInAreaRegistration).IsAssignableFrom(t))) { if (!typeof(AreaRegistration).IsAssignableFrom(item)) { throw new AbpException($"{item.FullName} should inherits from {typeof(AreaRegistration).FullName}"); } var instance = (AreaRegistration)Activator.CreateInstance(item); AreaRegistrationContext context = new AreaRegistrationContext(instance.AreaName, RouteTable.Routes, null); if (!item.Namespace.IsNullOrWhiteSpace()) { context.Namespaces.Add(item.Namespace + ".*"); } instance.RegisterArea(context); } //Auto Load IPlugInAuthorizationProvider foreach (var item in autoLoadTypes.Where(t => typeof(IPlugInAuthorizationProvider).IsAssignableFrom(t))) { Configuration.Authorization.Providers.Add(item); } //Auto Load IPlugInNavigationProvider foreach (var item in autoLoadTypes.Where(t => typeof(IPlugInNavigationProvider).IsAssignableFrom(t))) { Configuration.Navigation.Providers.Add(item); } } public override void PostInitialize() { ControllerBuilder.Current.SetControllerFactory(new PlugInWindsorControllerFactory(IocManager, IocManager.Resolve())); } } } ================================================ FILE: src2/Abplus.Web.PlugIns/Web/Mvc/Controllers/PlugInWindsorControllerFactory.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using System.Web.Routing; using Abp.Dependency; using Abp.PlugIns; namespace Abp.Web.Mvc.Controllers { public class PlugInWindsorControllerFactory : WindsorControllerFactory { private readonly IAbpPlugInManager _plugInManager; private readonly object _locker = new object(); private volatile Dictionary> _plugInControllerTypesCache; public PlugInWindsorControllerFactory(IIocResolver iocManager, IAbpPlugInManager plugInManager) : base(iocManager) { _plugInManager = plugInManager; } protected override Type GetControllerType(RequestContext requestContext, string controllerName) { var controllerType = base.GetControllerType(requestContext, controllerName); if (controllerType == null) { //TODO@personball Maybe it's better to search controllerType in IoC Container? controllerType = GetControllerTypeFromPlugIns(requestContext, controllerName); } return controllerType; } private Type GetControllerTypeFromPlugIns(RequestContext requestContext, string controllerName) { InitPlugInControllerTypesCache(); HashSet matchingTypes = new HashSet(); ILookup namespaceLookup; if (_plugInControllerTypesCache.TryGetValue(controllerName, out namespaceLookup)) { //TODO@personball Should deal with namespace. // this friendly name was located in the cache, now cycle through namespaces //if (namespaces != null) //{ // foreach (string requestedNamespace in namespaces) // { // foreach (var targetNamespaceGrouping in namespaceLookup) // { // if (IsNamespaceMatch(requestedNamespace, targetNamespaceGrouping.Key)) // { // matchingTypes.UnionWith(targetNamespaceGrouping); // } // } // } //} //else //{ // if the namespaces parameter is null, search *every* namespace foreach (var namespaceGroup in namespaceLookup) { matchingTypes.UnionWith(namespaceGroup); } //} } switch (matchingTypes.Count) { case 0: return null; case 1: return matchingTypes.First(); default: throw new InvalidOperationException("AmbiguousControllerTypeFromPlugIns"); } } private void InitPlugInControllerTypesCache() { if (_plugInControllerTypesCache == null) { lock (_locker) { if (_plugInControllerTypesCache == null) { var controllerTypes = _plugInManager.PlugInSources .GetAllModules().Select(m => m.Assembly).Distinct().ToList() .SelectMany(a => a.GetTypes()) .Where(t => t != null && t.IsPublic && !t.IsAbstract && typeof(IController).IsAssignableFrom(t) && t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) .ToList(); var groupedByName = controllerTypes.GroupBy( t => t.Name.Substring(0, t.Name.Length - "Controller".Length), StringComparer.OrdinalIgnoreCase); _plugInControllerTypesCache = groupedByName.ToDictionary( g => g.Key, g => g.ToLookup(t => t.Namespace ?? String.Empty, StringComparer.OrdinalIgnoreCase), StringComparer.OrdinalIgnoreCase); } } } } } } ================================================ FILE: src2/Abplus.Web.PlugIns/packages.config ================================================  ================================================ FILE: src2/Abplus.Web.SignalR/Abplus.Web.SignalR.csproj ================================================  Debug AnyCPU {27F80F3E-AEC9-47BC-8FF0-2FE9197A2293} Library Properties Abp Abplus.Web.SignalR v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.Web.SignalR.XML ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Abp.Web.SignalR.3.7.2\lib\net461\Abp.Web.SignalR.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.AspNet.SignalR.Core.2.2.3\lib\net45\Microsoft.AspNet.SignalR.Core.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Owin.4.0.0\lib\net451\Microsoft.Owin.dll ..\..\packages\Microsoft.Owin.Security.4.0.0\lib\net451\Microsoft.Owin.Security.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\Owin.1.0\lib\net40\Owin.dll True ..\..\packages\StackExchange.Redis.1.2.6\lib\net46\StackExchange.Redis.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.Web.SignalR/Abplus.Web.SignalR.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.Web.SignalR/Configuration/Startup/RedisOnlineClientManagerConfiguationExtensions.cs ================================================ using Abp.Configuration.Startup; using Abp.RealTime; namespace Abp.Configuration.Startup { public static class RedisOnlineClientManagerConfiguationExtensions { public static IRedisOnlineClientManagerModuleConfig UseRedisOnlineClientManager(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abplus.RedisOnlineClientManager", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src2/Abplus.Web.SignalR/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.Web.SignalR")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.Web.SignalR")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("27f80f3e-aec9-47bc-8ff0-2fe9197a2293")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.Web.SignalR/RealTime/IRedisOnlineClientManagerModuleConfig.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Abp.RealTime { public interface IRedisOnlineClientManagerModuleConfig { /// /// Redis连接字符串 /// string ConnectionString { get; } /// /// 在线状态列表存储的键名 /// string StoreKey { get; } IRedisOnlineClientManagerModuleConfig ConnectTo(string connectionString); IRedisOnlineClientManagerModuleConfig WithStoreKey(string storeKey); } } ================================================ FILE: src2/Abplus.Web.SignalR/RealTime/RedisOnlineClientManager.cs ================================================ using System; using System.Collections.Generic; using System.Collections.Immutable; using Abp.Dependency; using Abp.Extensions; using Abp.Json; using Castle.Core.Logging; using Newtonsoft.Json; using StackExchange.Redis; namespace Abp.RealTime { /// /// 基于Redis的OnlineClientManager /// public class RedisOnlineClientManager : IOnlineClientManager { /// /// Client 连接成功时 /// public event EventHandler ClientConnected; /// /// Client断开连接时 /// public event EventHandler ClientDisconnected; /// /// 用户连接成功时 /// public event EventHandler UserConnected; /// /// 用户断开连接时 /// public event EventHandler UserDisconnected; private readonly string _connectionString; private readonly string _storeKey; private readonly string _clientStoreKey; private readonly string _userStoreKey; private readonly Lazy _connectionMultiplexer; private readonly object _syncObj = new object(); /// /// 日志 /// public ILogger Logger { get; set; } /// /// ctor /// public RedisOnlineClientManager() { var config = IocManager.Instance.Resolve(); if (config == null || config.ConnectionString.IsNullOrWhiteSpace() || config.StoreKey.IsNullOrWhiteSpace()) { throw new Exception("RedisOnlineClientManagerModuleConfig is invalid!"); } _connectionString = config.ConnectionString; _storeKey = config.StoreKey; _clientStoreKey = _storeKey + ".Clients"; _userStoreKey = _storeKey + ".Users"; Logger = NullLogger.Instance; _connectionMultiplexer = new Lazy(CreateConnectionMultiplexer); } private ConnectionMultiplexer CreateConnectionMultiplexer() { return ConnectionMultiplexer.Connect(_connectionString); } /// /// 获取Redis Database /// /// protected IDatabase GetDatabase() { return _connectionMultiplexer.Value.GetDatabase(); } /// /// 添加Client /// /// public void Add(IOnlineClient client) { lock (_syncObj) { var userWasAlreadyOnline = false; var user = client.ToUserIdentifierOrNull(); if (user != null) { userWasAlreadyOnline = IsUserOnline(user); } AddClientToRedisStore(client); ClientConnected.InvokeSafely(this, new OnlineClientEventArgs(client)); if (user != null && !userWasAlreadyOnline) { UserConnected.InvokeSafely(this, new OnlineUserEventArgs(user, client)); } } } private bool IsUserOnline(UserIdentifier user) { var _database = GetDatabase(); return _database.HashExists(_userStoreKey, user.ToUserIdentifierString()); } private void AddClientToRedisStore(IOnlineClient client) { var _database = GetDatabase(); _database.HashSet(_clientStoreKey, new HashEntry[] { new HashEntry(client.ConnectionId, client.ToString()) }); var userId = client.ToUserIdentifierOrNull(); if (userId == null) { return; } var userClients = new List(); var userClientsValue = _database.HashGet(_userStoreKey, userId.ToUserIdentifierString()); if (userClientsValue.HasValue) { userClients = JsonConvert.DeserializeObject>(userClientsValue); } if (userClients.Contains(client.ConnectionId)) { return; } userClients.Add(client.ConnectionId); _database.HashSet(_userStoreKey, new HashEntry[] { new HashEntry(userId.ToUserIdentifierString(), userClients.ToJsonString()) }); } /// /// 获取所有Clients /// /// public IReadOnlyList GetAllClients() { lock (_syncObj) { var _database = GetDatabase(); var clientsEntries = _database.HashGetAll(_clientStoreKey); var clients = new List(); foreach (var entry in clientsEntries) { clients.Add(JsonConvert.DeserializeObject(entry.Value)); } return clients.ToImmutableList(); } } /// /// 根据连接id获取client /// /// /// public IOnlineClient GetByConnectionIdOrNull(string connectionId) { lock (_syncObj) { var _database = GetDatabase(); var clientValue = _database.HashGet(_clientStoreKey, connectionId); if (clientValue.IsNullOrEmpty) { return null; } return JsonConvert.DeserializeObject(clientValue); } } /// /// 移除Client /// /// /// public bool Remove(string connectionId) { lock (_syncObj) { var _database = GetDatabase(); var clientValue = _database.HashGet(_clientStoreKey, connectionId); if (clientValue.IsNullOrEmpty) { return true; } var client = JsonConvert.DeserializeObject(clientValue); var user = client.ToUserIdentifierOrNull(); if (user != null) { //从_userStoreKey中移除一个client var userClientsValue = _database.HashGet(_userStoreKey, user.ToUserIdentifierString()); if (userClientsValue.HasValue) { var userClients = JsonConvert.DeserializeObject>(userClientsValue); userClients.Remove(connectionId); if (userClients.Count > 0) { //更新 _database.HashSet(_userStoreKey, new HashEntry[] { new HashEntry(user.ToUserIdentifierString(), userClients.ToJsonString()) }); } else { //删除 _database.HashDelete(_userStoreKey, user.ToUserIdentifierString()); } } _database.HashDelete(_clientStoreKey, connectionId); if (!IsUserOnline(user)) { UserDisconnected.InvokeSafely(this, new OnlineUserEventArgs(user, client)); } } ClientDisconnected.InvokeSafely(this, new OnlineClientEventArgs(client)); return true; } } /// /// 获取指定user的所有clients /// /// /// public IReadOnlyList GetAllByUserId(IUserIdentifier user) { var clients = new List(); var userIdentifier = new UserIdentifier(user.TenantId, user.UserId); if (!IsUserOnline(userIdentifier)) { return clients; } lock (_syncObj) { var _database = GetDatabase(); var userClients = new List(); var userClientsValue = _database.HashGet(_userStoreKey, userIdentifier.ToUserIdentifierString()); if (userClientsValue.HasValue) { userClients = JsonConvert.DeserializeObject>(userClientsValue); foreach (var connectionId in userClients) { var clientValue = _database.HashGet(_clientStoreKey, connectionId); if (clientValue.IsNullOrEmpty) { continue; } clients.Add(JsonConvert.DeserializeObject(clientValue)); } } } return clients; } } } ================================================ FILE: src2/Abplus.Web.SignalR/RealTime/RedisOnlineClientManagerModule.cs ================================================ using System.Reflection; using Abp.Dependency; using Abp.Modules; namespace Abp.RealTime { public class RedisOnlineClientManagerModule : AbpModule { public override void PreInitialize() { //base.PreInitialize(); IocManager.Register(); IocManager.Register(DependencyLifeStyle.Singleton); } public override void Initialize() { //base.Initialize(); IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } } } ================================================ FILE: src2/Abplus.Web.SignalR/RealTime/RedisOnlineClientManagerModuleConfig.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Abp.RealTime { public class RedisOnlineClientManagerModuleConfig : IRedisOnlineClientManagerModuleConfig { public string ConnectionString { get; private set; } public string StoreKey { get; private set; } public RedisOnlineClientManagerModuleConfig() { ConnectionString = string.Empty; StoreKey = "Abplus.RealTime.OnlineClients"; } public IRedisOnlineClientManagerModuleConfig ConnectTo(string connectionString) { ConnectionString = connectionString; return this; } public IRedisOnlineClientManagerModuleConfig WithStoreKey(string storeKey) { StoreKey = storeKey; return this; } } } ================================================ FILE: src2/Abplus.Web.SignalR/Web/SignalR/QrScan/SignalRQrCodeScannedRealTimeNotifier.cs ================================================ using System; using System.Threading.Tasks; using Abp.QrCode; using Abp.Web.SignalR.Hubs; using Castle.Core.Logging; using Microsoft.AspNet.SignalR; namespace Abp.Web.SignalR.QrScan { public class SignalRQrCodeScannedRealTimeNotifier : IQrCodeScannedRealTimeNotifier { /// /// Reference to the logger. /// public ILogger Logger { get; set; } private static IHubContext CommonHub { get { return GlobalHost.ConnectionManager.GetHubContext(); } } /// /// Initializes a new instance of the class. /// public SignalRQrCodeScannedRealTimeNotifier() { Logger = NullLogger.Instance; } public Task Notify(string scannerId, string connectionId, object properties = null) { try { var signalRClient = CommonHub.Clients.Client(connectionId); if (signalRClient == null) { throw new Exception($"Can not find the client with connectionId:{connectionId}"); } signalRClient.qrScanned(scannerId, properties); } catch (Exception ex) { Logger.Warn(ex.ToString(), ex); } return Task.FromResult(0); } } } ================================================ FILE: src2/Abplus.Web.SignalR/Web/SignalR/QrScan/SignalRQrCodeScannedRealTimeNotifierModule.cs ================================================ using Abp.Modules; using Abp.QrCode; namespace Abp.Web.SignalR.QrScan { public class SignalRQrCodeScannedRealTimeNotifierModule : AbpModule { public override void PreInitialize() { //base.PreInitialize(); IocManager.Register(); } } } ================================================ FILE: src2/Abplus.Web.SignalR/app.config ================================================  ================================================ FILE: src2/Abplus.Web.SignalR/packages.config ================================================  ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Abplus.Web.SimpleCaptcha.csproj ================================================  Debug AnyCPU {2AEA2117-3019-41B0-94F9-2B071B4FDEE4} Library Properties Abp Abplus.Web.SimpleCaptcha v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.Web.SimpleCaptcha.XML ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Abplus.Web.SimpleCaptcha.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Configuration/Startup/SimpleCaptchaManagerConfigurationExtension.cs ================================================ using Abp.Web.SimpleCaptcha; namespace Abp.Configuration.Startup { public static class SimpleCaptchaManagerConfigurationExtension { public static ISimpleCaptchaModuleConfig UseSimpleCaptchaModule(this IModuleConfigurations configurations) { return configurations.AbpConfiguration.GetOrCreate("Modules.Abplus.Web.SimpleCaptcha.ISimpleCaptchaModuleConfig", () => configurations.AbpConfiguration.IocManager.Resolve()); } } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.Web.SimpleCaptcha")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.Web.SimpleCaptcha")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("2aea2117-3019-41b0-94f9-2b071b4fdee4")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.1.1.0")] [assembly: AssemblyFileVersion("1.1.1.0")] ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Web/SimpleCaptcha/ISimpleCaptchaModuleConfig.cs ================================================ using Abp.Dependency; namespace Abp.Web.SimpleCaptcha { public interface ISimpleCaptchaModuleConfig : ITransientDependency { #region Properties /// /// 使用cookie存储验证码时,必须提供16位加密密钥 /// string CookieCodeStoreSecretKey { get; } /// /// 验证码有效期,单位:分钟 /// int CodeExpiredInMinutes { get; } /// /// 验证码是否可重复使用,默认false /// bool CodeReusable { get; } /// /// 是否扭曲,默认不扭曲 /// bool TwistEnabled { get; } /// /// 随机线条,默认启用 /// bool RandomLineEnabled { get; } /// /// 随机线条数量,默认1 /// int RandomLineCount { get; } /// /// 是否大小写敏感, 默认false /// bool CaseSensitive { get; } /// /// 字符集是否包含小写字母,默认false /// bool CharSetIncludeLowercases { get; } /// /// 字符集是否包含大写字母,默认true /// bool CharSetIncludeUppercases { get; } /// /// 字符集是否包含数字,默认true /// bool CharSetIncludeNumbers { get; } /// /// 排除易混淆字符,默认"01IOlo" /// string CharSetExcluded { get; } #endregion #region Methods /// /// 设置验证码过期时长,默认20分钟 /// /// /// ISimpleCaptchaModuleConfig SetMinutesCodeExpiredIn(int minutes); /// /// 验证码是否可多次使用,默认false,一旦验证通过立即清除 /// /// /// ISimpleCaptchaModuleConfig EnableCodeReusable(bool enabled); /// /// 是否启用图片扭曲,默认不启用 /// /// ISimpleCaptchaModuleConfig EnableTwist(bool enabled); /// /// 是否启用随机线条,默认启用 /// ISimpleCaptchaModuleConfig EnableRandomLine(bool enabled); /// /// 设置随机线条数量,默认1 /// ISimpleCaptchaModuleConfig SetRandomLineCount(int count); /// /// 是否大小写敏感, 默认false /// ISimpleCaptchaModuleConfig EnableCaseSensitive(bool caseSensitive); /// /// 字符集是否包含小写字母,默认false /// ISimpleCaptchaModuleConfig IncludeCharSetLowercases(bool included); /// /// 字符集是否包含大写字母,默认true /// ISimpleCaptchaModuleConfig IncludeCharSetUppercases(bool included); /// /// 字符集是否包含数字,默认true /// ISimpleCaptchaModuleConfig IncludeCharSetNumbers(bool included); /// /// 排除易混淆字符,默认"01IOlo" /// ISimpleCaptchaModuleConfig ExcludeCharSet(params char[] excludedChars); /// /// 使用cookie存储验证码时,必须提供16位加密密钥 /// /// /// ISimpleCaptchaModuleConfig SetCookieCodeStoreSecretKey(string secretKey); /// /// 使用Cookie存储验证码,默认使用Session /// 注意使用Cookie存储验证码时,必须提供长度为16位的加密密钥以对验证码值进行加密解密 /// /// /// ISimpleCaptchaModuleConfig UseCookieCodeStore(string secretKey); /// /// 使用缓存存储验证码,默认使用session /// 注意使用缓存存储验证码时,验证码存储的StoreKey必须包含用户会话标识, /// 建议读取Key为ASP.NET_SessionId的Cookie值作为StoreKey的一部分。 /// /// ISimpleCaptchaModuleConfig UseCacheCodeStore(); /// /// 使用session存储验证码 /// /// ISimpleCaptchaModuleConfig UseSessionCodeStore(); #endregion } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Web/SimpleCaptcha/IVerificationCodeStore.cs ================================================ namespace Abp.Web.SimpleCaptcha { /// /// 验证码存储介质 /// public interface IVerificationCodeStore { void Save(string storeKey, string verificationCode); string Find(string storeKey); void Clear(string storeKey); } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Web/SimpleCaptcha/SimpleCaptchaManager.cs ================================================ using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Web; using Abp.Dependency; using Abp.Extensions; using Abp.UI; namespace Abp.Web.SimpleCaptcha { public class SimpleCaptchaManager : ITransientDependency { public const string DefaultCharSetNumbers = "0123456789"; public const string DefaultCharSetUpperCases = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public const string DefaultCharSetLowerCases = "abcdefghijklmnopqrstuvwxyz"; private readonly IVerificationCodeStore _codeStore; private readonly ISimpleCaptchaModuleConfig _config; public SimpleCaptchaManager( IVerificationCodeStore codeStore, ISimpleCaptchaModuleConfig config ) { _codeStore = codeStore; _config = config; } public virtual void DisableHttpResponseCache() { //禁止图片缓存 HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache); } public virtual void ClearHttpResponseAndSetContentType() { HttpContext.Current.Response.Clear(); HttpContext.Current.Response.ContentType = "image/pjpeg"; } /// /// 输出验证码图片 /// /// 验证码字串存储的键名 /// 图片宽,必须大于CodeNum*17 /// 图片高,必须大于20 /// 字符数量 public void ImageRefresher(Stream outputStream, string storeKey, int ImgWidth, int ImgHeight, int CodeNum) { if (ImgWidth <= CodeNum * 17) { ImgWidth = CodeNum * 17 + 1; } if (ImgHeight <= 20) { ImgHeight = 21; } DisableHttpResponseCache(); //设置字符集 string charSetString = string.Empty;//增大字符集 if (_config.CharSetIncludeNumbers) { charSetString += DefaultCharSetNumbers; } if (_config.CharSetIncludeLowercases) { charSetString += DefaultCharSetLowerCases; } if (_config.CharSetIncludeUppercases) { charSetString += DefaultCharSetUpperCases; } if (!_config.CharSetExcluded.IsNullOrWhiteSpace()) { var units = _config.CharSetExcluded.ToCharArray(); foreach (var unit in units) { charSetString = charSetString.Replace(unit.ToString(), ""); } } int ccslength = charSetString.Length; //设置字体集合 Font[] fonts = new Font[] { new Font("宋体", 15, FontStyle.Bold|FontStyle.Regular), new Font("宋体", 16, FontStyle.Bold|FontStyle.Italic), new Font("宋体", 17, FontStyle.Bold|FontStyle.Strikeout), new Font("宋体", 16, FontStyle.Bold|FontStyle.Underline), new Font("宋体", 15, FontStyle.Bold|FontStyle.Italic|FontStyle.Strikeout), new Font("宋体", 16, FontStyle.Bold|FontStyle.Italic|FontStyle.Underline) }; //设置画笔 Brush brush = null; Color brushColor = new Color(); //验证码字串 string valiCode = string.Empty; string codeUnit = string.Empty; Bitmap image = new Bitmap(ImgWidth, ImgHeight);//图片规格 //范围 int yOffset = (image.Height - 17) / 2;//字符垂直偏移度 int[] offSetFixArr = new int[] { -4, -3, -2, -1, 0, 1, 2, 3, 4 }; Graphics g = Graphics.FromImage(image);//画布 g.Clear(Color.White);//初始化画布 int startOffset = (image.Width - CodeNum * 17) / 2; int startX = startOffset; Random random = new Random(); string tmpcode = ""; for (int i = 0; i < CodeNum; i++) { int rNum1 = random.Next(ccslength, DateTime.Now.Millisecond + ccslength); int rNum2 = random.Next(fonts.Length, DateTime.Now.Millisecond + fonts.Length); int rNum3 = random.Next(offSetFixArr.Length, DateTime.Now.Millisecond + offSetFixArr.Length); codeUnit = charSetString.Substring(rNum1 % ccslength, 1);//随机提取字符 if (codeUnit == tmpcode) { codeUnit = charSetString.Substring((rNum1 + 1) % ccslength, 1);//与上一字符重复时,再次提取字符 } valiCode = valiCode + codeUnit;//记录提取的字符 tmpcode = codeUnit; //调整画笔以及写入坐标,实现验证码粘连、倾斜 Font font = fonts[rNum2 % fonts.Length];//选择字体 brushColor = Color.FromArgb(random.Next(255), random.Next(80), random.Next(255));//设置随机颜色 brush = new SolidBrush(brushColor); int offSetFix = offSetFixArr[rNum3 % offSetFixArr.Length]; g.DrawString(codeUnit, font, brush, startX, yOffset + offSetFix); startX += 13 + offSetFix; } //随机产生的线条 if (_config.RandomLineEnabled) { LinearGradientBrush lgb = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.Red, 1.2f, true); for (int i = 0; i < _config.RandomLineCount; i++) { int x1 = random.Next(image.Width); int x2 = random.Next(image.Width); int y1 = random.Next(image.Height); int y2 = random.Next(image.Height); g.DrawLine(new Pen(Color.Black), x1, y1, x2, y2); } } //背景随机点 for (int i = 0; i < 100; i++) { int x1 = random.Next(image.Width); int y1 = random.Next(image.Height); image.SetPixel(x1, y1, Color.FromArgb(random.Next(255), random.Next(255), random.Next(255))); } int rNum4 = random.Next(0, 6); //扭曲 if (_config.TwistEnabled) { image = TwistImage(image, true, 3, rNum4); } ClearHttpResponseAndSetContentType(); image.Save(outputStream, ImageFormat.Jpeg); _codeStore.Save(storeKey, valiCode); image.Dispose(); } #region 产生波形滤镜效果 private const double PI = 3.1415926535897932384626433832795; private const double PI2 = 6.283185307179586476925286766559; /// /// 正弦曲线Wave扭曲图片 /// /// 图片路径 /// 如果扭曲则选择为True /// 波形的幅度倍数,越大扭曲的程度越高,一般为3 /// 波形的起始相位,取值区间[0-2*PI) /// private Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase) { Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height); // 将位图背景填充为白色 Graphics graph = Graphics.FromImage(destBmp); graph.FillRectangle(new SolidBrush(Color.White), 0, 0, destBmp.Width, destBmp.Height); double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width; for (int i = 0; i < destBmp.Width; i++) { for (int j = 0; j < destBmp.Height; j++) { double dx = 0; dx = bXDir ? (PI2 * (double)j) / dBaseAxisLen : (PI2 * (double)i) / dBaseAxisLen; dx += dPhase; double dy = Math.Sin(dx); // 取得当前点的颜色 int nOldX = 0, nOldY = 0; nOldX = bXDir ? i + (int)(dy * dMultValue) : i; nOldY = bXDir ? j : j + (int)(dy * dMultValue); Color color = srcBmp.GetPixel(i, j); if (nOldX >= 0 && nOldX < destBmp.Width && nOldY >= 0 && nOldY < destBmp.Height) { destBmp.SetPixel(nOldX, nOldY, color); } } } graph.DrawRectangle(new Pen(Color.Silver), 0, 0, destBmp.Width - 1, destBmp.Height - 1); graph.Dispose(); return destBmp; } #endregion public bool Verify(string storeKey, string codeToBeVerified) { var codeStored = _codeStore.Find(storeKey); if (codeStored.IsNullOrWhiteSpace()) { throw new UserFriendlyException("VerificationCode Expired!"); } var matched = false; if (_config.CaseSensitive) { matched = (codeStored == codeToBeVerified); } else { matched = (codeStored.ToLower() == codeToBeVerified.ToLower()); } if (matched && !_config.CodeReusable) { _codeStore.Clear(storeKey); } return matched; } } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Web/SimpleCaptcha/SimpleCaptchaModule.cs ================================================ using System.Reflection; using Abp.Dependency; using Abp.Modules; using Abp.Web.SimpleCaptcha.VerificationCodeStores; namespace Abp.Web.SimpleCaptcha { public class SimpleCaptchaModule : AbpModule { public override void PreInitialize() { IocManager.Register(); } public override void Initialize() { IocManager.RegisterIfNot(); IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Web/SimpleCaptcha/SimpleCaptchaModuleConfig.cs ================================================ using System; using System.Linq; using Abp.Dependency; using Abp.Web.SimpleCaptcha.VerificationCodeStores; namespace Abp.Web.SimpleCaptcha { public class SimpleCaptchaModuleConfig : ISimpleCaptchaModuleConfig { public SimpleCaptchaModuleConfig() { CookieCodeStoreSecretKey = string.Empty; CodeExpiredInMinutes = 20; CodeReusable = false; TwistEnabled = false; RandomLineEnabled = true; RandomLineCount = 1; CaseSensitive = false; CharSetIncludeNumbers = true; CharSetIncludeUppercases = true; CharSetIncludeLowercases = false; CharSetExcluded = "01IOlo"; } /// /// 是否扭曲,默认不扭曲 /// public bool TwistEnabled { get; private set; } /// /// 随机线条,默认启用 /// public bool RandomLineEnabled { get; private set; } /// /// 随机线条数量,默认1 /// public int RandomLineCount { get; private set; } /// /// 是否大小写敏感, 默认false /// public bool CaseSensitive { get; private set; } /// /// 字符集是否包含小写字母,默认false /// public bool CharSetIncludeLowercases { get; private set; } /// /// 字符集是否包含大写字母,默认true /// public bool CharSetIncludeUppercases { get; private set; } /// /// 字符集是否包含数字,默认true /// public bool CharSetIncludeNumbers { get; private set; } /// /// 排除易混淆字符,默认"01IOlo" /// public string CharSetExcluded { get; private set; } /// /// 验证码是否可重复使用,默认false /// public bool CodeReusable { get; private set; } /// /// 验证码过期时长 /// public int CodeExpiredInMinutes { get; private set; } /// /// 验证码存于cookie时,需配置16位加密密钥 /// public string CookieCodeStoreSecretKey { get; private set; } public ISimpleCaptchaModuleConfig EnableCodeReusable(bool enabled) { CodeReusable = enabled; return this; } public ISimpleCaptchaModuleConfig EnableTwist(bool enabled) { TwistEnabled = enabled; return this; } public ISimpleCaptchaModuleConfig EnableRandomLine(bool enabled) { RandomLineEnabled = enabled; return this; } public ISimpleCaptchaModuleConfig SetRandomLineCount(int count) { if (count < 1) { throw new ArgumentOutOfRangeException(nameof(count), $"{nameof(count)} should greater than 0!"); } RandomLineCount = count; return this; } public ISimpleCaptchaModuleConfig EnableCaseSensitive(bool caseSensitive) { CaseSensitive = caseSensitive; return this; } public ISimpleCaptchaModuleConfig IncludeCharSetLowercases(bool included) { CharSetIncludeLowercases = included; return this; } public ISimpleCaptchaModuleConfig IncludeCharSetUppercases(bool included) { CharSetIncludeUppercases = included; return this; } public ISimpleCaptchaModuleConfig IncludeCharSetNumbers(bool included) { CharSetIncludeNumbers = included; return this; } public ISimpleCaptchaModuleConfig ExcludeCharSet(params char[] excludedChars) { if (!excludedChars.Any()) { CharSetExcluded = string.Empty; } CharSetExcluded = string.Join("", excludedChars); return this; } public ISimpleCaptchaModuleConfig SetMinutesCodeExpiredIn(int minutes) { if (minutes < 1) { minutes = 1; } CodeExpiredInMinutes = minutes; return this; } public ISimpleCaptchaModuleConfig SetCookieCodeStoreSecretKey(string secretKey) { Check.NotNullOrWhiteSpace(secretKey, nameof(secretKey)); if (secretKey.Length != 16) { throw new ArgumentException("请提供长度为16位的加密密钥!", nameof(secretKey)); } CookieCodeStoreSecretKey = secretKey; return this; } public ISimpleCaptchaModuleConfig UseCookieCodeStore(string secretKey) { IocManager.Instance.Register(); return SetCookieCodeStoreSecretKey(secretKey); } public ISimpleCaptchaModuleConfig UseCacheCodeStore() { IocManager.Instance.Register(); return this; } public ISimpleCaptchaModuleConfig UseSessionCodeStore() { IocManager.Instance.Register(); return this; } } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Web/SimpleCaptcha/VerificationCodeStores/CacheVerificationCodeStore.cs ================================================ using System; using Abp.Extensions; using Abp.Runtime.Caching; using Castle.Core.Logging; namespace Abp.Web.SimpleCaptcha.VerificationCodeStores { public class CacheVerificationCodeStore : IVerificationCodeStore { private readonly ICacheManager _cacheManager; private const string DefaultCacheName = "CacheVerificationCodeStore"; public ILogger Logger { get; set; } public CacheVerificationCodeStore(ICacheManager cacheManager) { Logger = NullLogger.Instance; _cacheManager = cacheManager; } public void Clear(string storeKey) { Check.NotNullOrWhiteSpace(storeKey, nameof(storeKey)); try { _cacheManager.GetCache(DefaultCacheName).Remove(storeKey); } catch (Exception ex) { Logger.Warn(ex.Message, ex); } } public string Find(string storeKey) { Check.NotNullOrWhiteSpace(storeKey, nameof(storeKey)); var code = _cacheManager.GetCache(DefaultCacheName).GetOrDefault(storeKey); if (code.IsNullOrWhiteSpace()) { return string.Empty; } return code; } public void Save(string storeKey, string verificationCode) { Check.NotNullOrWhiteSpace(storeKey, nameof(storeKey)); Check.NotNullOrWhiteSpace(verificationCode, nameof(verificationCode)); _cacheManager.GetCache(DefaultCacheName).Set(storeKey, verificationCode, null, TimeSpan.FromMinutes(20)); } } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Web/SimpleCaptcha/VerificationCodeStores/CookieVerificationCodeStore.cs ================================================ using System; using System.Web; using Abp.Runtime.Security; using Abp.Extensions; namespace Abp.Web.SimpleCaptcha.VerificationCodeStores { public class CookieVerificationCodeStore : IVerificationCodeStore { private readonly ISimpleCaptchaModuleConfig _config; public CookieVerificationCodeStore(ISimpleCaptchaModuleConfig config) { _config = config; } public void Clear(string storeKey) { Check.NotNullOrWhiteSpace(storeKey, nameof(storeKey)); var valiCodeCookie = HttpContext.Current.Request.Cookies[storeKey]; if (valiCodeCookie == null || valiCodeCookie.Value.IsNullOrWhiteSpace()) { return; } valiCodeCookie.Expires = DateTime.UtcNow.AddDays(-1).ToLocalTime(); HttpContext.Current.Response.Cookies.Add(valiCodeCookie); } public string Find(string storeKey) { var valiCodeCookie = HttpContext.Current.Request.Cookies[storeKey]; if (valiCodeCookie == null || valiCodeCookie.Value.IsNullOrWhiteSpace()) { return string.Empty; } if (_config.CookieCodeStoreSecretKey.IsNullOrWhiteSpace()) { return valiCodeCookie.Value; } return SimpleStringCipher.Instance.Decrypt(valiCodeCookie.Value, _config.CookieCodeStoreSecretKey); } public void Save(string storeKey, string verificationCode) { var cookieValue = verificationCode; if (!_config.CookieCodeStoreSecretKey.IsNullOrWhiteSpace()) { cookieValue = SimpleStringCipher.Instance.Encrypt(verificationCode, _config.CookieCodeStoreSecretKey); } var codeCookie = new HttpCookie(storeKey, cookieValue); codeCookie.Path = "/"; codeCookie.HttpOnly = true; codeCookie.Expires = DateTime.UtcNow.AddMinutes(5).ToLocalTime(); HttpContext.Current.Response.Cookies.Add(codeCookie); } } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/Web/SimpleCaptcha/VerificationCodeStores/SessionVerificationCodeStore.cs ================================================ using System.Web; using Abp.UI; namespace Abp.Web.SimpleCaptcha.VerificationCodeStores { public class SessionVerificationCodeStore : IVerificationCodeStore { public void Clear(string storeKey) { Check.NotNullOrWhiteSpace(storeKey, nameof(storeKey)); if (HttpContext.Current.Session == null) { return; } HttpContext.Current.Session.Remove(storeKey); } public string Find(string storeKey) { Check.NotNullOrWhiteSpace(storeKey, nameof(storeKey)); if (HttpContext.Current.Session == null) { throw new UserFriendlyException("HttpContext.Current.Session is null! "); } if (HttpContext.Current.Session[storeKey] == null) { return string.Empty; } return HttpContext.Current.Session[storeKey].ToString(); } public void Save(string storeKey, string verificationCode) { Check.NotNullOrWhiteSpace(storeKey, nameof(storeKey)); Check.NotNullOrWhiteSpace(verificationCode, nameof(verificationCode)); if (HttpContext.Current.Session == null) { throw new UserFriendlyException("HttpContext.Current.Session is null! "); } HttpContext.Current.Session[storeKey] = verificationCode; } } } ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/app.config ================================================  ================================================ FILE: src2/Abplus.Web.SimpleCaptcha/packages.config ================================================  ================================================ FILE: src2/Abplus.WebApiClient/Abplus.WebApiClient.csproj ================================================  Debug AnyCPU {548FB369-D982-466A-B53E-18D6CA0298D8} Library Properties Abp Abplus.WebApiClient v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 bin\Release\Abplus.WebApiClient.XML ..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\packages\Abp.Web.3.7.2\lib\net461\Abp.Web.dll ..\..\packages\Abp.Web.Api.3.7.2\lib\net461\Abp.Web.Api.dll ..\..\packages\Abp.Web.Common.3.7.2\lib\netstandard2.0\Abp.Web.Common.dll ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.6\lib\net45\System.Net.Http.Formatting.dll ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.6\lib\net45\System.Web.Http.dll ..\..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.6\lib\net45\System.Web.Http.WebHost.dll ..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Abplus.WebApiClient/Abplus.WebApiClient.nuspec ================================================ $id$ $version$ $title$ personball personball https://raw.githubusercontent.com/personball/abplus/master/LICENSE https://github.com/personball/abplus https://raw.githubusercontent.com/personball/abplus/master/abplus_icon.png false Abp plus, an extension for Abp Framework. Copyright 2017 ================================================ FILE: src2/Abplus.WebApiClient/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.InteropServices; using Abp; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.WebApiClient")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.WebApiClient")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("548fb369-d982-466a-b53e-18d6ca0298d8")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(AbplusConsts.CurrentVersion)] [assembly: AssemblyFileVersion(AbplusConsts.CurrentVersion)] ================================================ FILE: src2/Abplus.WebApiClient/WebApiClient/AbplusWebApiClient.cs ================================================ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using Abp.Dependency; using Abp.Extensions; using Abp.Json; using Castle.Core.Logging; namespace Abp.WebApiClient { public class AbplusWebApiClient : IAbplusWebApiClient, ITransientDependency { public static ConcurrentDictionary clientDictionary { get; set; } public static int DefaultTimeoutInSeconds { get; set; } public string BaseUrl { get; set; } public TimeSpan Timeout { get; set; } public ILogger Logger { get; set; } public Collection Cookies { get; private set; } public ICollection RequestHeaders { get; private set; } public ICollection ResponseHeaders { get; private set; } static AbplusWebApiClient() { clientDictionary = new ConcurrentDictionary(); DefaultTimeoutInSeconds = 90; } public AbplusWebApiClient() { Timeout = TimeSpan.FromSeconds(DefaultTimeoutInSeconds); Logger = NullLogger.Instance; } public async Task GetAsync(string url, int? timeout = null) { await GetAsync(url, timeout); } public async Task GetAsync(string url, int? timeout = null, bool? hasErrorCodeIf500 = null) { return await RequestAsync(url, null, timeout, HttpRequestMethod.GET, hasErrorCodeIf500); } public async Task PostAsync(string url, int? timeout = null) { await PostAsync(url, timeout); } public async Task PostAsync(string url, object input, int? timeout = null) { await PostAsync(url, input, timeout); } public async Task PostAsync(string url, int? timeout = null) where TResult : class { return await PostAsync(url, null, timeout); } public async Task PostAsync(string url, object input, int? timeout = null) where TResult : class { return await RequestAsync(url, input, timeout, HttpRequestMethod.POST, null); } public async Task PostAsync(string url, object input, int? timeout = default(int?), bool? hasErrorCodeIf500 = null) { return await RequestAsync(url, input, timeout, HttpRequestMethod.POST, hasErrorCodeIf500); } private async Task RequestAsync( string url, object input, int? timeoutInMilliseconds = null, HttpRequestMethod method = HttpRequestMethod.POST, bool? hasErrorCodeIf500 = null) { if (!hasErrorCodeIf500.HasValue) { hasErrorCodeIf500 = false; } //httpclient 实例 var uri = new Uri(url); timeoutInMilliseconds = timeoutInMilliseconds.HasValue ? timeoutInMilliseconds : DefaultTimeoutInSeconds * 1000; var dictKey = uri.Scheme + "|" + uri.Host + "|" + uri.Port + "|" + timeoutInMilliseconds; dictKey = dictKey.ToLower(); HttpClient client; if (!clientDictionary.Keys.Contains(dictKey) || clientDictionary[dictKey] == null) { client = new HttpClient(); client.Timeout = TimeSpan.FromMilliseconds(timeoutInMilliseconds.Value); if (method == HttpRequestMethod.POST) { //POST client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); } if (clientDictionary.Keys.Contains(dictKey)) { clientDictionary.TryUpdate(dictKey, client, null); } else { clientDictionary.TryAdd(dictKey, client); } var sp = ServicePointManager.FindServicePoint(uri); sp.ConnectionLeaseTimeout = (int)Math.Floor(Timeout.TotalMilliseconds * 2); } else { client = clientDictionary[dictKey]; } if (input == null) { input = new object(); } if (method == HttpRequestMethod.GET) { //GET using (var response = await client.GetAsync(url)) { var info = string.Empty; var strReturn = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode && !hasErrorCodeIf500.Value) { info = string.Format("RemoteApiCallFailed\r\n GET Url:{0}\r\n Response:{1}", url, strReturn); Logger.Error(info); throw new AbplusWebApiClientRemoteCallException(info); } info = string.Format("RemoteApiCallSuccess\r\n GET Url:{0}\r\n Response:{1}", url, strReturn); Logger.Info(info); return strReturn.ToObject(); } } else { var strInput = input.ToJsonString(); using (var requestContent = new StringContent(strInput, Encoding.UTF8, "application/json")) { using (var response = await client.PostAsync(url, requestContent)) { var info = string.Empty; var strReturn = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode && !hasErrorCodeIf500.Value) { info = string.Format("RemoteApiCallFailed\r\n POST Url:{0}\r\n,Input:{1}\r\n Response:{2}", url, input.ToJsonString(), strReturn); throw new AbplusWebApiClientRemoteCallException(info); } info = info = string.Format("RemoteApiCallSuccess\r\n POST Url:{0}\r\n,Input:{1}\r\n Response:{2}", url, input.ToJsonString(), strReturn); Logger.Info(info); return strReturn.ToObject(); } } } } /// /// /// public enum HttpRequestMethod { /// /// HttpPost /// POST = 0, /// /// HttpGET /// GET = 1 } } } ================================================ FILE: src2/Abplus.WebApiClient/WebApiClient/AbplusWebApiClientModule.cs ================================================ using System.Reflection; using Abp.Modules; namespace Abp.WebApiClient { public class AbplusWebApiClientModule : AbpModule { public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } } } ================================================ FILE: src2/Abplus.WebApiClient/WebApiClient/AbplusWebApiClientRemoteCallException.cs ================================================ using System; using System.Runtime.Serialization; namespace Abp.WebApiClient { /// /// /// public class AbplusWebApiClientRemoteCallException : AbpException { /// /// Creates a new object. /// public AbplusWebApiClientRemoteCallException() { } /// /// Creates a new object. /// public AbplusWebApiClientRemoteCallException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) { } /// /// Creates a new object. /// /// public AbplusWebApiClientRemoteCallException(string message) : base(message) { } /// /// /// /// /// public AbplusWebApiClientRemoteCallException(string message, Exception ex) : base(message, ex) { } } } ================================================ FILE: src2/Abplus.WebApiClient/WebApiClient/IAbplusWebApiClient.cs ================================================ using System.Threading.Tasks; using Abp.WebApi.Client; namespace Abp.WebApiClient { /// /// 扩展IAbpWebApiClient /// public interface IAbplusWebApiClient : IAbpWebApiClient { Task GetAsync(string url, int? timeout = null); Task GetAsync(string url, int? timeout = null, bool? hasErrorCodeIf500 = null); Task PostAsync(string url, object input, int? timeout = null, bool? hasErrorCodeIf500 = null); } } ================================================ FILE: src2/Abplus.WebApiClient/app.config ================================================  ================================================ FILE: src2/Abplus.WebApiClient/packages.config ================================================  ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/Abplus.WebApiVersionRoute.Sample.csproj ================================================  Debug AnyCPU 2.0 {9B3DE552-D101-4449-BFDE-EC8A5C149C2B} {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} Library Properties Abplus.WebApiVersionRoute.Sample Abplus.WebApiVersionRoute.Sample v4.6.1 true true full false bin\ DEBUG;TRACE prompt 4 pdbonly true bin\ TRACE prompt 4 ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll ..\..\..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.4\lib\net45\System.Net.Http.Formatting.dll ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.4\lib\net45\System.Web.Http.dll ..\..\..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.4\lib\net45\System.Web.Http.WebHost.dll Global.asax Web.config Web.config {84d80055-6a95-4de3-b1e7-68b88838f2be} Abplus.Web.Api 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) True True 22070 / http://localhost:22044/ False False False 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/App_Start/WebApiConfig.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; namespace Abplus.WebApiVersionRoute.Sample { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服务 // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } } } ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/Controllers/ValueController.cs ================================================ using System.Threading.Tasks; using System.Web.Http; using Abplus.WebApiVersionRoute.RoutingConstraints; namespace Abplus.WebApiVersionRoute.Sample.Controllers { public class ValueController : ApiController { /// /// Access With HttpHeader "Abplus-ApiVersion:1" /// /// [HttpGet] [VersionedRoute("api/value/byApiVersion", 1)] public async Task byApiVersion1() { return "ApiVersion1"; } /// /// Access With HttpHeader "Abplus-ApiVersion:2" /// /// [HttpGet] [VersionedRoute("api/value/byApiVersion", 2)] public async Task byApiVersion2() { return "ApiVersion2"; } /// /// Access With HttpHeader "Abplus-SysCode:H5" /// /// [HttpGet] [VersionedRoute("api/value/bySysCode", 1, SysCode.H5)] public async Task bySysCodeH5() { return "OnlySysCodeH5"; } /// /// Access With HttpHeader "Abplus-SysCode:IPhone" or "Abplus-SysCode:Andriod" /// /// [HttpGet] [VersionedRoute("api/value/bySysCode", 1, SysCode.IPhone|SysCode.Android)] public async Task bySysCodeNotH5() { return "SysCode.IPhone|SysCode.Andriod"; } /// /// Access With HttpHeader "Abplus-ClientVersion:1.1.1" or "Abplus-ClientVersion:1.1.0" (with value less than 1.1.2) /// /// [HttpGet] [VersionedRoute("api/value/byVersionRangeString", 1, SysCode.H5,"*-1.1.1")] public async Task byVersionRangeStringLessThan112() { return "byVersionRangeStringLessThan112"; } /// /// Access With HttpHeader "Abplus-ClientVersion:1.1.3" (with version between 1.1.2 and 1.9.0) /// /// [HttpGet] [VersionedRoute("api/value/byVersionRangeString", 1, SysCode.H5, "1.1.2-1.9.0")] public async Task byVersionRangeString112To190() { return "byVersionRangeString111To222"; } /// /// Access With HttpHeader "Abplus-ClientVersion:1.9.1" /// /// [HttpGet] [VersionedRoute("api/value/byVersionRangeString", 1, SysCode.H5, "1.9.1")] public async Task byVersionRangeStringOnly191() { return "byVersionRangeStringOnly191"; } /// /// Access With HttpHeader "Abplus-ClientVersion:1.9.2" or "Abplus-ClientVersion:1.9.3" /// /// [HttpGet] [VersionedRoute("api/value/byVersionRangeString", 1, SysCode.H5, "1.9.2", "1.9.3")] public async Task byVersionRangeString192And193() { return "byVersionRangeString192And193"; } /// /// Access With HttpHeader "Abplus-ClientVersion:1.9.4" (with version greater than 1.9.4) /// /// [HttpGet] [VersionedRoute("api/value/byVersionRangeString", 1, SysCode.H5, "1.9.4-*")] public async Task byVersionRangeStringGreaterThan193() { return "byVersionRangeStringGreaterThan193"; } /// /// Access With HttpHeaders /// "Abplus-ClientVersion:1.9.4" /// "Abplus-SysCode:IPhone" /// "Abplus-ApiVersion:2" /// /// [HttpGet] [VersionedRoute("api/value/byVersionRangeString", 2, SysCode.IPhone, "1.9.4")] public async Task byApiSysCodeVersionRange() { return "ApiVersion2-IPhone-194"; } } } ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/Global.asax ================================================ <%@ Application Codebehind="Global.asax.cs" Inherits="Abplus.WebApiVersionRoute.Sample.WebApiApplication" Language="C#" %> ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/Global.asax.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Routing; namespace Abplus.WebApiVersionRoute.Sample { public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); } } } ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的常规信息通过下列特性集 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.WebApiVersionRoute.Sample")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.WebApiVersionRoute.Sample")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // 将 ComVisible 设置为 false 会使此程序集中的类型 // 对 COM 组件不可见。如果需要 // 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID [assembly: Guid("9b3de552-d101-4449-bfde-ec8a5c149c2b")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 内部版本号 // 修订版本 // // 可以指定所有值,也可以使用“修订号”和“内部版本号”的默认值, // 方法是按如下所示使用 "*": [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/Web.Debug.config ================================================ ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/Web.Release.config ================================================ ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/Web.config ================================================  ================================================ FILE: src2/Samples/Abplus.WebApiVersionRoute.Sample/packages.config ================================================  ================================================ FILE: src2/Samples/Sample.MqMessages/MqMessages/TestMqMessage.cs ================================================ using System; namespace Sample.MqMessages { public class TestMqMessage { public string Name { get; set; } public string Value { get; set; } public DateTime Time { get; set; } } } ================================================ FILE: src2/Samples/Sample.MqMessages/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Sample.MqMessages")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Sample.MqMessages")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("94e6d468-2d45-4ec7-af1b-aac884db467f")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src2/Samples/Sample.MqMessages/Sample.MqMessages.csproj ================================================  Debug AnyCPU {94E6D468-2D45-4EC7-AF1B-AAC884DB467F} Library Properties Sample Sample.MqMessages v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/App.config ================================================  ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/Handlers/TestHandler.cs ================================================ using System.Threading.Tasks; using Castle.Core.Logging; using Rebus.Handlers; using Sample.MqMessages; using Abp.MqMessages; namespace Sample.Handlers { public class TestHandler : IHandleMessages { public ILogger Logger { get; set; } public IMqMessagePublisher Publisher { get; set; } public TestHandler() { Publisher = NullMqMessagePublisher.Instance; } public async Task Handle(TestMqMessage message) { var msg = $"{Logger.GetType()}:{message.Name},{message.Value},{message.Time}"; Logger.Debug(msg); await Publisher.PublishAsync(msg);//send it again! } } } ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/NLog.config ================================================ ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/NLog.xsd ================================================  Watch config file for changes and reload automatically. Print internal NLog messages to the console. Default value is: false Print internal NLog messages to the console error output. Default value is: false Write internal NLog messages to the specified file. Log level threshold for internal log messages. Default value is: Info. Global log level threshold for application log messages. Messages below this level won't be logged.. Throw an exception when there is an internal error. Default value is: false. Throw an exception when there is a configuration error. If not set, determined by throwExceptions. Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false. Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false. Write timestamps for internal NLog messages. Default value is: true. Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false. Perform mesage template parsing and formatting of LogEvent messages (true = Always, false = Never, empty = Auto Detect). Default value is: empty. Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes). Prefix for targets/layout renderers/filters/conditions loaded from this assembly. Load NLog extensions from the specified file (*.dll) Load NLog extensions from the specified assembly. Assembly name should be fully qualified. Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name* Comma separated list of levels that this rule matches. Minimum level that this rule matches. Maximum level that this rule matches. Level that this rule matches. Comma separated list of target names. Ignore further rules if this one matches. Enable or disable logging rule. Disabled rules are ignored. Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file. Ignore any errors in the include file. Variable name. Variable value. Name of the target. Number of log events that should be processed in a batch by the lazy writer thread. Limit of full s to write before yielding into Performance is better when writing many small batches, than writing a single large batch Action to be taken when the lazy writer thread request queue count exceeds the set limit. Limit on the number of requests in the lazy writer thread request queue. Time in milliseconds to sleep between batches. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Delay the flush until the LogEvent has been confirmed as written Condition expression. Log events who meet this condition will cause a flush on the wrapped target. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Number of log events to be buffered. Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes. Action to take if the buffer overflows. Indicates whether to use sliding timeout. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Encoding to be used. Instance of that is used to format log messages. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Action that should be taken if the will be more connections than . Maximum queue size. Maximum current connections. 0 = no maximum. Indicates whether to keep connection open whenever possible. Size of the connection cache (number of connections which are kept alive). Network address. Action that should be taken if the message is larger than maxMessageSize. NDLC item separator. NDC item separator. Indicates whether to include NLog-specific extensions to log4j schema. Indicates whether to include source info (file name and line number) in the information sent over the network. Indicates whether to include contents of the stack. Indicates whether to include stack contents. Indicates whether to include dictionary contents. Indicates whether to include dictionary contents. Indicates whether to include call site (class and method name) in the information sent over the network. Option to include all properties from the log events AppInfo field. By default it's the friendly name of the current AppDomain. Renderer for log4j:event logger-xml-attribute (Default ${logger}) Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Layout that should be use to calcuate the value for the parameter. Viewer parameter name. Name of the target. Text to be rendered. Header. Footer. Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) The encoding for writing messages to the . Indicates whether the error stream (stderr) should be used instead of the output stream (stdout). Indicates whether to use default row highlighting rules. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Condition that must be met in order to set the specified foreground and background color. Background color. Foreground color. Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used. Indicates whether to ignore case when comparing texts. Regular expression to be matched. You must specify either text or regex. Text to be matched. You must specify either text or regex. Indicates whether to match whole words only. Background color. Foreground color. Name of the target. Text to be rendered. Header. Footer. Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) The encoding for writing messages to the . Indicates whether to send the log messages to the standard error instead of the standard output. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this. Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string. Name of the database provider. Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string. Indicates whether to keep the database connection open between the log events. Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string. Name of the connection string (as specified in <connectionStrings> configuration section. Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase. Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string. Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Text of the SQL command to be run on each log level. Type of the SQL command to be run on each log level. Type of the command. Connection string to run the command against. If not provided, connection string from the target is used. Indicates whether to ignore failures. Command text. Layout that should be use to calcuate the value for the parameter. Database parameter name. Database parameter precision. Database parameter scale. Database parameter size. Name of the target. Text to be rendered. Header. Footer. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Layout that renders event Category. Optional entrytype. When not set, or when not convertable to then determined by Layout that renders event ID. Name of the Event Log to write to. This can be System, Application or any user-defined name. Name of the machine on which Event Log service is running. Maximum Event log size in kilobytes. If null, the value won't be set. Default is 512 Kilobytes as specified by Eventlog API Message length limit to write to the Event Log. Value to be used as the event Source. Action to take if the message is larger than the option. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Indicates whether to return to the first target after any successful write. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Text to be rendered. Header. Footer. File encoding. Line ending mode. Indicates whether to compress archive files into the zip archive format. Way file archives are numbered. Name of the file to be used for an archive. Is the an absolute or relative path? Indicates whether to automatically archive log files every time the specified time passes. Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose: Maximum number of archive files that should be kept. Indicates whether the footer should be written only when the file is archived. Maximum number of log filenames that should be stored as existing. Name of the file to write to. Value specifying the date format to use when archiving files. Indicates whether to archive old log file on startup. Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong. Indicates whether to create directories if they do not exist. Indicates whether to delete old log file on startup. File attributes (Windows only). Indicates whether to write BOM (byte order mark) in created files Indicates whether to enable log file(s) to be deleted. Indicates whether to replace file contents on each write instead of appending log message at the end. Value indicationg whether file creation calls should be synchronized by a system global mutex. Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation. Is the an absolute or relative path? Indicates whether concurrent writes to the log file by multiple processes on the same host. Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write Delay in milliseconds to wait before attempting to write to the file again. Indicates whether concurrent writes to the log file by multiple processes on different network hosts. Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger). Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Log file buffer size in bytes. Indicates whether to automatically flush the file buffers after each log message. Number of times the write is appended on the file before NLog discards the log message. Indicates whether to keep log file open instead of opening and closing it on each logging event. Name of the target. Condition expression. Log events who meet this condition will be forwarded to the wrapped target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Windows domain name to change context to. Required impersonation level. Type of the logon provider. Logon Type. User account password. Indicates whether to revert to the credentials of the process instead of impersonating another user. Username to change context to. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Interval in which messages will be written up to the number of messages. Maximum allowed number of messages written per . Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Endpoint address. Name of the endpoint configuration in WCF configuration file. Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply) Client ID. Indicates whether to include per-event properties in the payload sent to the server. Indicates whether to use binary message encoding. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Layout that should be use to calculate the value for the parameter. Name of the parameter. Type of the parameter. Type of the parameter. Obsolete alias for Name of the target. Text to be rendered. Header. Footer. Indicates whether NewLine characters in the body should be replaced with tags. Priority used for sending mails. Encoding to be used for sending e-mail. BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). Indicates whether to add new lines between log entries. Indicates whether to send message as HTML instead of plain text. Sender's email address (e.g. joe@domain.com). Mail message body (repeated for each log message send in one mail). Mail subject. Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Indicates the SMTP client timeout. SMTP Server to be used for sending. SMTP Authentication mode. Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic"). Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic"). Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server. Port number that SMTP Server is listening on. Indicates whether the default Settings from System.Net.MailSettings should be used. Folder where applications save mail messages to be processed by the local SMTP server. Specifies how outgoing email messages will be handled. Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Class name. Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Encoding to be used. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Network address. Size of the connection cache (number of connections which are kept alive). Indicates whether to keep connection open whenever possible. Maximum current connections. 0 = no maximum. Maximum queue size. Action that should be taken if the will be more connections than . Action that should be taken if the message is larger than maxMessageSize. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Encoding to be used. Instance of that is used to format log messages. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Action that should be taken if the will be more connections than . Maximum queue size. Maximum current connections. 0 = no maximum. Indicates whether to keep connection open whenever possible. Size of the connection cache (number of connections which are kept alive). Network address. Action that should be taken if the message is larger than maxMessageSize. NDLC item separator. NDC item separator. Indicates whether to include NLog-specific extensions to log4j schema. Indicates whether to include source info (file name and line number) in the information sent over the network. Indicates whether to include contents of the stack. Indicates whether to include stack contents. Indicates whether to include dictionary contents. Indicates whether to include dictionary contents. Indicates whether to include call site (class and method name) in the information sent over the network. Option to include all properties from the log events AppInfo field. By default it's the friendly name of the current AppDomain. Renderer for log4j:event logger-xml-attribute (Default ${logger}) Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Indicates whether to perform layout calculation. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Indicates whether performance counter should be automatically created. Name of the performance counter category. Counter help text. Name of the performance counter. Performance counter type. The value by which to increment the counter. Performance counter instance name. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Default filter to be applied when no specific rule matches. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Condition to be tested. Resulting filter to be applied when the condition matches. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Number of times to repeat each log message. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Number of retries that should be attempted on the wrapped target in case of a failure. Time to wait between retries in milliseconds. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Always use independent of Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8. Web service method name. Only used with Soap. Web service namespace. Only used with Soap. Protocol to be used when calling web service. Custom proxy address, include port separated by a colon Encoding. Web service URL. Value whether escaping be done according to the old NLog style (Very non-standard) Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs) Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in parameters) Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see and ). (optional) root namespace of the XML document, if POST of XML document chosen. (see and ). Proxy configuration when calling web service Footer layout. Header layout. Body layout (can be repeated multiple times). Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom'). Column delimiter. Quote Character. Quoting mode. Indicates whether CVS should include header. Layout of the column. Name of the column. List of property names to exclude when is true Option to include all properties from the log event (as JSON) Indicates whether to include contents of the dictionary. Indicates whether to include contents of the dictionary. Option to render the empty object value {} Option to suppress the extra spaces in the output json How far should the JSON serializer follow object references before backing off Layout that will be rendered as the attribute's value. Name of the attribute. Determines wether or not this attribute will be Json encoded. Indicates whether to escape non-ascii characters Whether an attribute with empty value should be included in the output Footer layout. Header layout. Body layout (can be repeated multiple times). Option to include all properties from the log events Indicates whether to include contents of the dictionary. Indicates whether to include contents of the dictionary. Indicates whether to include contents of the stack. Indicates whether to include contents of the stack. Layout text. Action to be taken when filter matches. Condition expression. Action to be taken when filter matches. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Substring to be matched. Action to be taken when filter matches. String to compare the layout to. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Action to be taken when filter matches. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Substring to be matched. Action to be taken when filter matches. String to compare the layout to. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Action to be taken when filter matches. Default number of unique filter values to expect, will automatically increase if needed Applies the configured action to the initial logevent that starts the timeout period. Used to configure that it should ignore all events until timeout. Layout to be used to filter log messages. Max number of unique filter values to expect simultaneously Max length of filter values, will truncate if above limit How long before a filter expires, and logging is accepted again Default buffer size for the internal buffers Reuse internal buffers, and doesn't have to constantly allocate new buffers Append FilterCount to the when an event is no longer filtered Insert FilterCount value into when an event is no longer filtered ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/Program.cs ================================================ using System; using Topshelf; namespace Sample.RebusRabbitMqConsumer { class Program { static int Main() { return (int)HostFactory.Run(x => { x.UseAssemblyInfoForServiceInfo(); x.Service(s => { s.ConstructUsing(() => new SampleRebusRabbitMqConsumerBootstrap()); s.WhenStarted(v => v.Start()); s.WhenStopped(v => v.Stop()); s.BeforeStartingService(_ => { Console.WriteLine("Processor is starting"); }); s.BeforeStoppingService(_ => { Console.WriteLine("Processor is stopping"); }); }); // x.StartAutomatically(); x.SetStartTimeout(TimeSpan.FromSeconds(10)); x.SetStopTimeout(TimeSpan.FromSeconds(10)); x.EnableServiceRecovery(r => { r.RestartService(1); //r.RunProgram(7, "ping google.com"); r.RestartComputer(5, "message"); r.OnCrashOnly(); r.SetResetPeriod(2); }); //x.AddCommandLineSwitch("throwonstart", v => throwOnStart = v); //x.AddCommandLineSwitch("throwonstop", v => throwOnStop = v); //x.AddCommandLineSwitch("throwunhandled", v => throwUnhandled = v); x.OnException((exception) => { }); }); } } } ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Sample.RebusRabbitMqConsumer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Sample.RebusRabbitMqConsumer")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("96002b54-90ba-4cfe-af91-149035703a98")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/Sample.RebusRabbitMqConsumer.csproj ================================================  Debug AnyCPU {96002B54-90BA-4CFE-AF91-149035703A98} Exe Properties Sample Sample.RebusRabbitMqConsumer v4.6.1 512 true AnyCPU true full false bin\Debug\ DEBUG;TRACE prompt 4 AnyCPU pdbonly true bin\Release\ TRACE prompt 4 ..\..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\..\packages\Abplus.0.1.7.6\lib\net461\Abplus.dll ..\..\..\packages\Abplus.MqMessages.RebusCore.0.1.6.3\lib\net461\Abplus.MqMessages.RebusCore.dll ..\..\..\packages\Abplus.MqMessages.RebusRabbitMqConsumer.0.1.6.3\lib\net461\Abplus.MqMessages.RebusRabbitMqConsumer.dll ..\..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\..\packages\Castle.Core-NLog.3.3.0\lib\net45\Castle.Services.Logging.NLogIntegration.dll True ..\..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.2.0.0\lib\net461\Microsoft.Diagnostics.Tracing.EventSource.dll ..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\..\packages\NLog.4.5.6\lib\net45\NLog.dll ..\..\..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll ..\..\..\packages\Rebus.4.2.1\lib\net45\Rebus.dll ..\..\..\packages\Rebus.Castle.Windsor.4.0.0\lib\net45\Rebus.CastleWindsor.dll ..\..\..\packages\Rebus.NewtonsoftJson.3.1.5\lib\NET45\Rebus.NewtonsoftJson.dll ..\..\..\packages\Rebus.NLog.5.0.0\lib\net45\Rebus.NLog.dll ..\..\..\packages\Rebus.RabbitMq.4.4.2\lib\net452\Rebus.RabbitMq.dll ..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll ..\..\..\packages\Topshelf.4.0.4\lib\net452\Topshelf.dll ..\..\..\packages\Topshelf.NLog.4.0.4\lib\net452\Topshelf.NLog.dll PreserveNewest Designer Designer {94E6D468-2D45-4EC7-AF1B-AAC884DB467F} Sample.MqMessages 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/SampleRebusRabbitMqConsumerBootstrap.cs ================================================ using Abp; namespace Sample { public class SampleRebusRabbitMqConsumerBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/SampleRebusRabbitMqConsumerModule.cs ================================================ using System.Reflection; using Abp.Configuration.Startup; using Abp.Modules; using Abp.MqMessages.Consumers; using Castle.Facilities.Logging; using Castle.Services.Logging.NLogIntegration; using Rebus.NLog.Config; namespace Sample { [DependsOn(typeof(RebusRabbitMqConsumerModule))] public class SampleRebusRabbitMqConsumerModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAbplusRebusRabbitMqConsumer() .UseLogging(c => c.NLog()) .ConnectTo("amqp://dev:dev@rabbitmq.local.jk724.cn/dev_host") .UseQueue(Assembly.GetExecutingAssembly().GetName().Name) .RegisterHandlerInAssemblys(Assembly.GetExecutingAssembly()); } public override void Initialize() { base.Initialize(); } public override void PostInitialize() { Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); } } } ================================================ FILE: src2/Samples/Sample.RebusRabbitMqConsumer/packages.config ================================================  ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/App.config ================================================  ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/BackgroundWorks/TestWorker.cs ================================================ using System; using Abp.Dependency; using Abp.MqMessages; using Abp.Threading.BackgroundWorkers; using Abp.Threading.Timers; using Sample.MqMessages; namespace Sample.BackgroundWorks { public class TestWorker : PeriodicBackgroundWorkerBase, ISingletonDependency { private readonly IMqMessagePublisher _publisher; public TestWorker(AbpTimer timer, IMqMessagePublisher publisher) : base(timer) { _publisher = publisher; Timer.Period = 3000;//one minute Timer.RunOnStart = true; } protected override void DoWork() { Logger.Info($"TestWork Done! Time:{DateTime.Now}"); _publisher.Publish(new TestMqMessage { Name = "TestWork", Value = "BlaBlaBlaBlaBlaBla", Time = DateTime.Now }); } } } ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/NLog.config ================================================ ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/NLog.xsd ================================================  Watch config file for changes and reload automatically. Print internal NLog messages to the console. Default value is: false Print internal NLog messages to the console error output. Default value is: false Write internal NLog messages to the specified file. Log level threshold for internal log messages. Default value is: Info. Global log level threshold for application log messages. Messages below this level won't be logged.. Throw an exception when there is an internal error. Default value is: false. Throw an exception when there is a configuration error. If not set, determined by throwExceptions. Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false. Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false. Write timestamps for internal NLog messages. Default value is: true. Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false. Perform mesage template parsing and formatting of LogEvent messages (true = Always, false = Never, empty = Auto Detect). Default value is: empty. Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes). Prefix for targets/layout renderers/filters/conditions loaded from this assembly. Load NLog extensions from the specified file (*.dll) Load NLog extensions from the specified assembly. Assembly name should be fully qualified. Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name* Comma separated list of levels that this rule matches. Minimum level that this rule matches. Maximum level that this rule matches. Level that this rule matches. Comma separated list of target names. Ignore further rules if this one matches. Enable or disable logging rule. Disabled rules are ignored. Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file. Ignore any errors in the include file. Variable name. Variable value. Name of the target. Number of log events that should be processed in a batch by the lazy writer thread. Limit of full s to write before yielding into Performance is better when writing many small batches, than writing a single large batch Action to be taken when the lazy writer thread request queue count exceeds the set limit. Limit on the number of requests in the lazy writer thread request queue. Time in milliseconds to sleep between batches. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Delay the flush until the LogEvent has been confirmed as written Condition expression. Log events who meet this condition will cause a flush on the wrapped target. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Number of log events to be buffered. Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes. Action to take if the buffer overflows. Indicates whether to use sliding timeout. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Encoding to be used. Instance of that is used to format log messages. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Action that should be taken if the will be more connections than . Maximum queue size. Maximum current connections. 0 = no maximum. Indicates whether to keep connection open whenever possible. Size of the connection cache (number of connections which are kept alive). Network address. Action that should be taken if the message is larger than maxMessageSize. NDLC item separator. NDC item separator. Indicates whether to include NLog-specific extensions to log4j schema. Indicates whether to include source info (file name and line number) in the information sent over the network. Indicates whether to include contents of the stack. Indicates whether to include stack contents. Indicates whether to include dictionary contents. Indicates whether to include dictionary contents. Indicates whether to include call site (class and method name) in the information sent over the network. Option to include all properties from the log events AppInfo field. By default it's the friendly name of the current AppDomain. Renderer for log4j:event logger-xml-attribute (Default ${logger}) Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Layout that should be use to calcuate the value for the parameter. Viewer parameter name. Name of the target. Text to be rendered. Header. Footer. Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) The encoding for writing messages to the . Indicates whether the error stream (stderr) should be used instead of the output stream (stdout). Indicates whether to use default row highlighting rules. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Condition that must be met in order to set the specified foreground and background color. Background color. Foreground color. Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used. Indicates whether to ignore case when comparing texts. Regular expression to be matched. You must specify either text or regex. Text to be matched. You must specify either text or regex. Indicates whether to match whole words only. Background color. Foreground color. Name of the target. Text to be rendered. Header. Footer. Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) The encoding for writing messages to the . Indicates whether to send the log messages to the standard error instead of the standard output. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this. Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string. Name of the database provider. Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string. Indicates whether to keep the database connection open between the log events. Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string. Name of the connection string (as specified in <connectionStrings> configuration section. Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase. Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string. Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Text of the SQL command to be run on each log level. Type of the SQL command to be run on each log level. Type of the command. Connection string to run the command against. If not provided, connection string from the target is used. Indicates whether to ignore failures. Command text. Layout that should be use to calcuate the value for the parameter. Database parameter name. Database parameter precision. Database parameter scale. Database parameter size. Name of the target. Text to be rendered. Header. Footer. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Layout that renders event Category. Optional entrytype. When not set, or when not convertable to then determined by Layout that renders event ID. Name of the Event Log to write to. This can be System, Application or any user-defined name. Name of the machine on which Event Log service is running. Maximum Event log size in kilobytes. If null, the value won't be set. Default is 512 Kilobytes as specified by Eventlog API Message length limit to write to the Event Log. Value to be used as the event Source. Action to take if the message is larger than the option. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Indicates whether to return to the first target after any successful write. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Text to be rendered. Header. Footer. File encoding. Line ending mode. Indicates whether to compress archive files into the zip archive format. Way file archives are numbered. Name of the file to be used for an archive. Is the an absolute or relative path? Indicates whether to automatically archive log files every time the specified time passes. Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose: Maximum number of archive files that should be kept. Indicates whether the footer should be written only when the file is archived. Maximum number of log filenames that should be stored as existing. Name of the file to write to. Value specifying the date format to use when archiving files. Indicates whether to archive old log file on startup. Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong. Indicates whether to create directories if they do not exist. Indicates whether to delete old log file on startup. File attributes (Windows only). Indicates whether to write BOM (byte order mark) in created files Indicates whether to enable log file(s) to be deleted. Indicates whether to replace file contents on each write instead of appending log message at the end. Value indicationg whether file creation calls should be synchronized by a system global mutex. Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation. Is the an absolute or relative path? Indicates whether concurrent writes to the log file by multiple processes on the same host. Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write Delay in milliseconds to wait before attempting to write to the file again. Indicates whether concurrent writes to the log file by multiple processes on different network hosts. Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger). Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Log file buffer size in bytes. Indicates whether to automatically flush the file buffers after each log message. Number of times the write is appended on the file before NLog discards the log message. Indicates whether to keep log file open instead of opening and closing it on each logging event. Name of the target. Condition expression. Log events who meet this condition will be forwarded to the wrapped target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Windows domain name to change context to. Required impersonation level. Type of the logon provider. Logon Type. User account password. Indicates whether to revert to the credentials of the process instead of impersonating another user. Username to change context to. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Interval in which messages will be written up to the number of messages. Maximum allowed number of messages written per . Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Endpoint address. Name of the endpoint configuration in WCF configuration file. Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply) Client ID. Indicates whether to include per-event properties in the payload sent to the server. Indicates whether to use binary message encoding. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Layout that should be use to calculate the value for the parameter. Name of the parameter. Type of the parameter. Type of the parameter. Obsolete alias for Name of the target. Text to be rendered. Header. Footer. Indicates whether NewLine characters in the body should be replaced with tags. Priority used for sending mails. Encoding to be used for sending e-mail. BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). Indicates whether to add new lines between log entries. Indicates whether to send message as HTML instead of plain text. Sender's email address (e.g. joe@domain.com). Mail message body (repeated for each log message send in one mail). Mail subject. Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com). Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Indicates the SMTP client timeout. SMTP Server to be used for sending. SMTP Authentication mode. Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic"). Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic"). Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server. Port number that SMTP Server is listening on. Indicates whether the default Settings from System.Net.MailSettings should be used. Folder where applications save mail messages to be processed by the local SMTP server. Specifies how outgoing email messages will be handled. Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Class name. Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Encoding to be used. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Network address. Size of the connection cache (number of connections which are kept alive). Indicates whether to keep connection open whenever possible. Maximum current connections. 0 = no maximum. Maximum queue size. Action that should be taken if the will be more connections than . Action that should be taken if the message is larger than maxMessageSize. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Encoding to be used. Instance of that is used to format log messages. End of line value if a newline is appended at the end of log message . Maximum message size in bytes. Indicates whether to append newline at the end of log message. Action that should be taken if the will be more connections than . Maximum queue size. Maximum current connections. 0 = no maximum. Indicates whether to keep connection open whenever possible. Size of the connection cache (number of connections which are kept alive). Network address. Action that should be taken if the message is larger than maxMessageSize. NDLC item separator. NDC item separator. Indicates whether to include NLog-specific extensions to log4j schema. Indicates whether to include source info (file name and line number) in the information sent over the network. Indicates whether to include contents of the stack. Indicates whether to include stack contents. Indicates whether to include dictionary contents. Indicates whether to include dictionary contents. Indicates whether to include call site (class and method name) in the information sent over the network. Option to include all properties from the log events AppInfo field. By default it's the friendly name of the current AppDomain. Renderer for log4j:event logger-xml-attribute (Default ${logger}) Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Indicates whether to perform layout calculation. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Indicates whether performance counter should be automatically created. Name of the performance counter category. Counter help text. Name of the performance counter. Performance counter type. The value by which to increment the counter. Performance counter instance name. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Default filter to be applied when no specific rule matches. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Condition to be tested. Resulting filter to be applied when the condition matches. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Number of times to repeat each log message. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Number of retries that should be attempted on the wrapped target in case of a failure. Time to wait between retries in milliseconds. Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Layout used to format log messages. Always use independent of Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Name of the target. Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8. Web service method name. Only used with Soap. Web service namespace. Only used with Soap. Protocol to be used when calling web service. Custom proxy address, include port separated by a colon Encoding. Web service URL. Value whether escaping be done according to the old NLog style (Very non-standard) Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs) Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in parameters) Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see and ). (optional) root namespace of the XML document, if POST of XML document chosen. (see and ). Proxy configuration when calling web service Footer layout. Header layout. Body layout (can be repeated multiple times). Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom'). Column delimiter. Quote Character. Quoting mode. Indicates whether CVS should include header. Layout of the column. Name of the column. List of property names to exclude when is true Option to include all properties from the log event (as JSON) Indicates whether to include contents of the dictionary. Indicates whether to include contents of the dictionary. Option to render the empty object value {} Option to suppress the extra spaces in the output json How far should the JSON serializer follow object references before backing off Layout that will be rendered as the attribute's value. Name of the attribute. Determines wether or not this attribute will be Json encoded. Indicates whether to escape non-ascii characters Whether an attribute with empty value should be included in the output Footer layout. Header layout. Body layout (can be repeated multiple times). Option to include all properties from the log events Indicates whether to include contents of the dictionary. Indicates whether to include contents of the dictionary. Indicates whether to include contents of the stack. Indicates whether to include contents of the stack. Layout text. Action to be taken when filter matches. Condition expression. Action to be taken when filter matches. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Substring to be matched. Action to be taken when filter matches. String to compare the layout to. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Action to be taken when filter matches. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Substring to be matched. Action to be taken when filter matches. String to compare the layout to. Indicates whether to ignore case when comparing strings. Layout to be used to filter log messages. Action to be taken when filter matches. Default number of unique filter values to expect, will automatically increase if needed Applies the configured action to the initial logevent that starts the timeout period. Used to configure that it should ignore all events until timeout. Layout to be used to filter log messages. Max number of unique filter values to expect simultaneously Max length of filter values, will truncate if above limit How long before a filter expires, and logging is accepted again Default buffer size for the internal buffers Reuse internal buffers, and doesn't have to constantly allocate new buffers Append FilterCount to the when an event is no longer filtered Insert FilterCount value into when an event is no longer filtered ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/Program.cs ================================================ using System; using Topshelf; namespace Sample.RebusRabbitMqPublisher { class Program { static int Main() { return (int)HostFactory.Run(x => { x.UseAssemblyInfoForServiceInfo(); x.Service(s => { s.ConstructUsing(() => new SampleRebusRabbitMqPublisherBootstrap()); s.WhenStarted(v => v.Start()); s.WhenStopped(v => v.Stop()); s.BeforeStartingService(_ => { Console.WriteLine("Processor is starting"); }); s.BeforeStoppingService(_ => { Console.WriteLine("Processor is stopping"); }); }); // x.StartAutomatically(); x.SetStartTimeout(TimeSpan.FromSeconds(10)); x.SetStopTimeout(TimeSpan.FromSeconds(10)); x.EnableServiceRecovery(r => { r.RestartService(1); //r.RunProgram(7, "ping google.com"); r.RestartComputer(5, "message"); r.OnCrashOnly(); r.SetResetPeriod(2); }); //x.AddCommandLineSwitch("throwonstart", v => throwOnStart = v); //x.AddCommandLineSwitch("throwonstop", v => throwOnStop = v); //x.AddCommandLineSwitch("throwunhandled", v => throwUnhandled = v); x.OnException((exception) => { }); }); } } } ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Sample.RebusRabbitMqPublisher")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Sample.RebusRabbitMqPublisher")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("db9b68cd-6868-4e94-9a94-6a9e70d7c48f")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/Sample.RebusRabbitMqPublisher.csproj ================================================  Debug AnyCPU {DB9B68CD-6868-4E94-9A94-6A9E70D7C48F} Exe Properties Sample Sample.RebusRabbitMqPublisher v4.6.1 512 true AnyCPU true full false bin\Debug\ DEBUG;TRACE prompt 4 AnyCPU pdbonly true bin\Release\ TRACE prompt 4 ..\..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\..\packages\Abplus.0.1.7.6\lib\net461\Abplus.dll ..\..\..\packages\Abplus.MqMessages.RebusCore.0.1.6.3\lib\net461\Abplus.MqMessages.RebusCore.dll ..\..\..\packages\Abplus.MqMessages.RebusRabbitMqPublisher.0.1.6.3\lib\net461\Abplus.MqMessages.RebusRabbitMqPublisher.dll ..\..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\..\packages\Castle.Core-NLog.3.3.0\lib\net45\Castle.Services.Logging.NLogIntegration.dll True ..\..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.2.0.0\lib\net461\Microsoft.Diagnostics.Tracing.EventSource.dll ..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\..\packages\NLog.4.5.6\lib\net45\NLog.dll ..\..\..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll ..\..\..\packages\Rebus.5.0.0-b05\lib\net45\Rebus.dll ..\..\..\packages\Rebus.Castle.Windsor.4.0.0\lib\net45\Rebus.CastleWindsor.dll ..\..\..\packages\Rebus.NLog.5.0.0\lib\net45\Rebus.NLog.dll ..\..\..\packages\Rebus.RabbitMq.4.4.2\lib\net452\Rebus.RabbitMq.dll ..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll ..\..\..\packages\Topshelf.4.0.4\lib\net452\Topshelf.dll ..\..\..\packages\Topshelf.NLog.4.0.4\lib\net452\Topshelf.NLog.dll PreserveNewest Designer {94E6D468-2D45-4EC7-AF1B-AAC884DB467F} Sample.MqMessages 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/SampleRebusRabbitMqPublisherBootstrap.cs ================================================ using System.Configuration; using Abp; using NLog; using NLog.Config; namespace Sample { public class SampleRebusRabbitMqPublisherBootstrap { private static readonly AbpBootstrapper _bs = AbpBootstrapper.Create(); public void Start() { //LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); _bs.Initialize(); } public void Stop() { _bs.Dispose(); } } } ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/SampleRebusRabbitMqPublisherModule.cs ================================================ using System.Reflection; using Abp.Configuration.Startup; using Abp.Modules; using Abp.MqMessages.Publishers; using Abp.Threading.BackgroundWorkers; using Castle.Facilities.Logging; using Castle.Services.Logging.NLogIntegration; using Rebus.NLog.Config; using Sample.BackgroundWorks; namespace Sample { [DependsOn(typeof(RebusRabbitMqPublisherModule))] public class SampleRebusRabbitMqPublisherModule : AbpModule { public override void PreInitialize() { Configuration.Modules.UseAbplusRebusRabbitMqPublisher() .UseLogging(c => c.NLog()) .ConnectionTo("amqp://dev:dev@rabbitmq.local.jk724.cn/dev_host"); Configuration.BackgroundJobs.IsJobExecutionEnabled = true; } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } public override void PostInitialize() { Abp.Dependency.IocManager.Instance.IocContainer.AddFacility(f => f.LogUsing().WithConfig("nlog.config")); var workManager = IocManager.Resolve(); workManager.Add(IocManager.Resolve()); } } } ================================================ FILE: src2/Samples/Sample.RebusRabbitMqPublisher/packages.config ================================================  ================================================ FILE: src2/Tests/Abplus.Tests/Abplus.Tests.csproj ================================================  Debug AnyCPU {336022E3-D481-4D09-9B97-305441FF6301} Library Properties Abplus.Tests Abplus.Tests v4.6.1 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\..\..\packages\Abp.3.7.2\lib\netstandard2.0\Abp.dll ..\..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll ..\..\..\packages\Castle.LoggingFacility.4.1.0\lib\net45\Castle.Facilities.Logging.dll ..\..\..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll ..\..\..\packages\JetBrains.Annotations.11.1.0\lib\net20\JetBrains.Annotations.dll ..\..\..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Caching.Memory.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\..\..\packages\Microsoft.Extensions.Options.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll ..\..\..\packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True ..\..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True ..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll True ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll True ..\..\..\packages\Nito.AsyncEx.Context.1.1.0\lib\net46\Nito.AsyncEx.Context.dll ..\..\..\packages\Nito.AsyncEx.Coordination.1.0.2\lib\net46\Nito.AsyncEx.Coordination.dll ..\..\..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll True ..\..\..\packages\Nito.AsyncEx.Tasks.1.1.0\lib\net46\Nito.AsyncEx.Tasks.dll ..\..\..\packages\Nito.Collections.Deque.1.0.4\lib\netstandard2.0\Nito.Collections.Deque.dll ..\..\..\packages\Nito.Disposables.1.2.3\lib\netstandard2.0\Nito.Disposables.dll ..\..\..\packages\Shouldly.3.0.0\lib\net451\Shouldly.dll ..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll ..\..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll ..\..\..\packages\System.Configuration.ConfigurationManager.4.5.0\lib\net461\System.Configuration.ConfigurationManager.dll ..\..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll True ..\..\..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll True ..\..\..\packages\System.Linq.Dynamic.Core.1.0.8.9\lib\net46\System.Linq.Dynamic.Core.dll ..\..\..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll ..\..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ..\..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll True ..\..\..\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll True ..\..\..\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll True ..\..\..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll ..\..\..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll True ..\..\..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll ..\..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll ..\..\..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll True ..\..\..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll True ..\..\..\packages\System.Xml.XPath.XmlDocument.4.3.0\lib\net46\System.Xml.XPath.XmlDocument.dll ..\..\..\packages\TimeZoneConverter.2.4.1\lib\net45\TimeZoneConverter.dll ..\..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll True ..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll ..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll ..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll {1de8d8d1-987d-4a9c-aec5-ff0a9914bbd4} Abplus 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 ================================================ FILE: src2/Tests/Abplus.Tests/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("Abplus.Tests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Abplus.Tests")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //将 ComVisible 设置为 false 将使此程序集中的类型 //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, //请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("336022e3-d481-4d09-9b97-305441ff6301")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: src2/Tests/Abplus.Tests/TimeRanges/TimeRange_Tests.cs ================================================ using System; using Abp.TimeRanges; using Shouldly; using Xunit; namespace Abplus.Tests.TimeRanges { public class TimeRange_Tests { [Fact] public void 时间区间起点不应大于等于终点() { Should.Throw(() => { var from = DateTime.Now; var to = DateTime.Now.AddMinutes(-5); var tr = new TimeRange(from, to); }); } [Fact] public void 时间区间相交情况A() { var from = DateTime.Now; var to = from.AddMinutes(5); var trA = new TimeRange(from, to); var trB = new TimeRange(to, to.AddMinutes(5)); var res = trA.IsIntersect(trB); res.ShouldBe(true); var trC = new TimeRange(from.AddMinutes(4), to.AddMinutes(5)); var res2 = trA.IsIntersect(trC); res2.ShouldBe(true); var trD = new TimeRange(to.AddMinutes(1), to.AddMinutes(5)); var res3 = trA.IsIntersect(trD); res3.ShouldBe(false); } [Fact] public void 时间区间相交情况B() { var from = DateTime.Now; var to = from.AddMinutes(5); var trA = new TimeRange(from, to); var trB = new TimeRange(from, to); var res = trA.IsIntersect(trB); res.ShouldBe(true); var trC = new TimeRange(from.AddMinutes(-1), to.AddMinutes(1)); var res2 = trA.IsIntersect(trC); res2.ShouldBe(true); } [Fact] public void 时间区间相交情况C() { var from = DateTime.Now; var to = from.AddMinutes(5); var trA = new TimeRange(from, to); var trB = new TimeRange(from.AddMinutes(-5), from); var res = trA.IsIntersect(trB); res.ShouldBe(true); var trC = new TimeRange(from.AddMinutes(-5), from.AddMinutes(1)); var res2 = trA.IsIntersect(trC); res2.ShouldBe(true); var trD = new TimeRange(from.AddMinutes(-5), from.AddMinutes(-1)); var res3 = trA.IsIntersect(trD); res3.ShouldBe(false); } } } ================================================ FILE: src2/Tests/Abplus.Tests/app.config ================================================  ================================================ FILE: src2/Tests/Abplus.Tests/packages.config ================================================