├── .gitattributes
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── APIBlox.AspNetCore.CommandsQueriesControllersOhMy
├── APIBlox.AspNetCore.CommandsQueriesControllersOhMy.csproj
├── AssemblyInfo.cs
├── Extensions
│ └── ComposedTemplatesExtensions.cs
└── Templates
│ ├── DeleteBy
│ ├── ActionContent.txt
│ ├── CtorArgs.txt
│ ├── CtorBody.txt
│ ├── Fields.txt
│ └── Namespaces.txt
│ ├── PatchBy
│ ├── ActionContent.txt
│ ├── CtorArgs.txt
│ ├── CtorBody.txt
│ ├── Fields.txt
│ └── Namespaces.txt
│ ├── Post
│ ├── ActionContent.txt
│ ├── CtorArgs.txt
│ ├── CtorBody.txt
│ ├── Fields.txt
│ ├── Methods.txt
│ └── Namespaces.txt
│ ├── PostAccepted
│ ├── ActionContent.txt
│ ├── CtorArgs.txt
│ ├── CtorBody.txt
│ ├── Fields.txt
│ └── Namespaces.txt
│ ├── PutBy
│ ├── ActionContent.txt
│ ├── CtorArgs.txt
│ ├── CtorBody.txt
│ ├── Fields.txt
│ └── Namespaces.txt
│ ├── QueryAll
│ ├── ActionContent.txt
│ ├── CtorArgs.txt
│ ├── CtorBody.txt
│ ├── Fields.txt
│ └── Namespaces.txt
│ └── QueryBy
│ ├── ActionContent.txt
│ ├── CtorArgs.txt
│ ├── CtorBody.txt
│ ├── Fields.txt
│ └── Namespaces.txt
├── APIBlox.AspNetCore.DynamicControllers
├── .gitattributes
├── .gitignore
├── APIBlox.AspNetCore.DynamicControllers.csproj
├── APIBlox.AspNetCore.DynamicControllers.csproj.DotSettings
├── AssemblyInfo.cs
├── Contracts
│ └── IComposedTemplate.cs
├── DynamicControllerFactory.cs
├── Exceptions
│ └── TemplateCompilationException.cs
├── Extensions
│ ├── MvcBuilderExtensions.cs
│ └── ServiceCollectionExtensions.cs
├── Filters
│ └── PostLocationHeaderResultFilter.cs
├── Templates
│ └── DynamicController.txt
└── Types
│ ├── DynamicAction.cs
│ ├── DynamicComments.cs
│ ├── DynamicController.cs
│ ├── DynamicControllerComposedTemplate.cs
│ └── DynamicControllerTemplateOptions.cs
├── APIBlox.AspNetCore
├── .gitattributes
├── .gitignore
├── APIBlox.AspNetCore.csproj
├── APIBlox.AspNetCore.csproj.DotSettings
├── ActionResults
│ ├── ProblemResult.cs
│ └── ValidationFailureResult.cs
├── AssemblyInfo.cs
├── Attributes
│ └── FromQueryWithAlternateNamesAttribute.cs
├── Constants.cs
├── Contracts
│ ├── IFilteredQuery.cs
│ ├── IOrderedQuery.cs
│ ├── IPaginationMetadataBuilder.cs
│ ├── IPaginationQuery.cs
│ ├── IProjectedQuery.cs
│ ├── IQuery.cs
│ └── IResource.cs
├── Conventions
│ └── RouteTokensConvention.cs
├── Enums
│ └── CommonStatusCodes.cs
├── Exceptions
│ └── HandledRequestException.cs
├── Extensions
│ ├── ApplicationBuilderExtensions.cs
│ ├── CollectionExtensions.cs
│ ├── ErrorExtensions.cs
│ ├── HandlerResponseExtensions.cs
│ ├── HttpContextExtensions.cs
│ ├── MvcBuilderExtensions.cs
│ ├── QueryableExtensions.cs
│ ├── RequestErrorObjectExtensions.cs
│ └── ServiceCollectionExtensions.cs
├── Filters
│ ├── Action Filters
│ │ ├── ETagActionFilter.cs
│ │ ├── EnsurePaginationResponseResultActionFilter.cs
│ │ ├── EnsureResponseResultActionFilter.cs
│ │ └── ValidateResourceActionFilter.cs
│ ├── Authorization Filters
│ │ └── ProblemResultAuthorizationFilter.cs
│ └── Exception Filters
│ │ └── OperationCanceledExceptionFilter.cs
├── Middleware
│ ├── ServerFaultsMiddleware.cs
│ └── SimulateWaitTimeMiddleware.cs
├── ModelBinders
│ ├── FromQueryWithAlterenateNamesBinderProvider.cs
│ └── FromQueryWithAlternateNamesBinder.cs
├── Services
│ ├── PaginationMetadata.cs
│ └── PaginationMetadataBuilder.cs
└── Types
│ ├── Errors
│ ├── DynamicErrorObject.cs
│ ├── RequestErrorObject.cs
│ └── ServerErrorObject.cs
│ ├── FilteredOrderedQuery.cs
│ ├── FilteredPaginationQuery.cs
│ ├── FilteredProjectedOrderedPaginationQuery.cs
│ ├── FilteredProjectedOrderedQuery.cs
│ ├── FilteredProjectedPaginationQuery.cs
│ ├── FilteredProjectedQuery.cs
│ ├── FilteredQuery.cs
│ ├── HandlerResponse.cs
│ ├── OrderedPaginationQuery.cs
│ ├── OrderedQuery.cs
│ ├── PaginationQuery.cs
│ ├── ProjectedOrderedPaginationQuery.cs
│ ├── ProjectedOrderedQuery.cs
│ ├── ProjectedPaginationQuery.cs
│ ├── ProjectedQuery.cs
│ └── Query.cs
├── APIBlox.NetCore.CommandsAndQueries
├── .gitattributes
├── .gitignore
├── APIBlox.NetCore.CommandsAndQueries.csproj
├── AssemblyInfo.cs
├── Contracts
│ ├── ICommandHandler.cs
│ └── IQueryHandler.cs
├── Decorators
│ ├── Commands
│ │ ├── MetricsCommandHandlerDecorator.cs
│ │ ├── RetryCommandHandlerDecorator.cs
│ │ └── TransactionScopeCommandHandlerDecorator.cs
│ └── Queries
│ │ └── MetricsQueryHandlerDecorator.cs
└── Extensions
│ └── ServiceCollectionExtensions.cs
├── APIBlox.NetCore.Common
├── .gitattributes
├── .gitignore
├── APIBlox.NetCore.Common.csproj
├── AssemblyInfo.cs
├── Extensions
│ ├── EnumExtensions.cs
│ ├── EnumerableExtensions.cs
│ ├── ExpressionExtensions.cs
│ ├── StringCompressionExtensions.cs
│ ├── StringExtensions.cs
│ ├── StructExtensions.cs
│ ├── TypeExtensions.cs
│ └── XmlDocumentationExtensions.cs
└── Types
│ ├── DynamicDataObject.cs
│ ├── JsonBits
│ ├── AliasContractResolver.cs
│ ├── CamelCasePopulateNonPublicSettersContractResolver.cs
│ ├── CamelCaseSettings.cs
│ ├── EmptyStringToNullConverter.cs
│ └── PopulateNonPublicSettersContractResolver.cs
│ └── SimpleMapper.cs
├── APIBlox.NetCore.DomainEvents
├── .gitattributes
├── .gitignore
├── APIBlox.NetCore.DomainEvents.csproj
├── AssemblyInfo.cs
├── Contracts
│ ├── IDomainEvent.cs
│ ├── IDomainEventHandler.cs
│ ├── IDomainEventsDispatcher.cs
│ └── IQueuedDomainEventsDispatcher.cs
├── Dispatchers
│ ├── DispatcherBase.cs
│ ├── DomainEventsDispatcher.cs
│ └── QueuedDomainEventsDispatcher.cs
├── Domain Events Notes.txt
├── Extensions
│ └── ServiceCollectionExtensions.cs
└── Handlers
│ ├── DomainEventHandlerBase.cs
│ └── DomainEventHandlerWrapper.cs
├── APIBlox.NetCore.EventStore.CosmosDb
├── APIBlox.NetCore.EventStore.CosmosDb.csproj
├── AssemblyInfo.cs
├── CosmosDbRepository.cs
├── DbCollection.cs
├── DbCollectionFactory.cs
├── Extensions
│ └── ServiceCollectionExtensions.cs
├── Options
│ ├── CosmosDbCollectionProperties.cs
│ └── CosmosDbOptions.cs
└── bulkInsert.js
├── APIBlox.NetCore.EventStore.EfCore
├── APIBlox.NetCore.EventStore.EfCore.csproj
├── AssemblyInfo.cs
├── DocEx.cs
├── EfCoreSqlRepository.cs
├── EventStoreDbContext.cs
├── EventStoreDocumentMap.cs
├── Extensions
│ └── ServiceCollectionExtensions.cs
├── Migrations
│ ├── EventStoreDbContextModelSnapshot.cs
│ ├── InitialCreate.Designer.cs
│ └── InitialCreate.cs
├── Options
│ └── EfCoreSqlOptions.cs
└── appsettings.json
├── APIBlox.NetCore.EventStore.MongoDb
├── APIBlox.NetCore.EventStore.MongoDb.csproj
├── AssemblyInfo.cs
├── CollectionContext.cs
├── Extensions
│ └── ServiceCollectionExtensions.cs
├── MongoDbRepository.cs
└── Options
│ ├── MongoDbCollectionProperties.cs
│ └── MongoDbOptions.cs
├── APIBlox.NetCore.EventStore.RavenDb
├── APIBlox.NetCore.EventStore.RavenDb.csproj
├── AssemblyInfo.cs
├── Extensions
│ └── ServiceCollectionExtensions.cs
├── Options
│ ├── RavenDbCollectionProperties.cs
│ └── RavenDbOptions.cs
├── RavenDbRepository.cs
└── StoreContext.cs
├── APIBlox.NetCore.EventStore
├── APIBlox.NetCore.EventStore.csproj
├── AssemblyInfo.cs
├── Contracts
│ ├── IEventStoreJsonSerializerSettings.cs
│ ├── IEventStoreRepository.cs
│ ├── IEventStoreService.cs
│ └── IReadOnlyEventStoreService.cs
├── Documents
│ ├── DocumentTypes.cs
│ ├── EventDocument.cs
│ ├── EventStoreDocument.cs
│ ├── RootDocument.cs
│ └── SnapshotDocument.cs
├── EventSourcedJsonSerializerSettings.cs
├── EventStoreService.cs
├── Exceptions
│ ├── EventStoreAccessException.cs
│ ├── EventStoreConcurrencyException.cs
│ └── EventStoreNotFoundException.cs
├── Extensions
│ └── ServiceCollectionExtensions.cs
├── Models
│ ├── EventModel.cs
│ ├── EventStreamModel.cs
│ └── SnapshotModel.cs
└── ReadOnlyEventStoreService.cs
├── APIBlox.NetCore
├── .gitattributes
├── .gitignore
├── APIBlox.NetCore.csproj
├── AssemblyInfo.cs
├── Attributes
│ ├── InjectableServiceAttribute.cs
│ └── MetadataAttribute.cs
├── Contracts
│ └── IDependencyInvertedConfiguration.cs
├── Extensions
│ ├── LoggerExtensions.cs
│ ├── Options
│ │ ├── ConfigureOptionsWithDependency.cs
│ │ └── ConfigureOptionsWithDependencyContainer.cs
│ └── ServiceCollectionExtensions
│ │ ├── Other.cs
│ │ └── ServiceDecoration.cs
└── Types
│ ├── AssemblyResolver.cs
│ ├── PathParser.cs
│ └── ResourceReader.cs
├── ApiBlox.AspNetCore.DynamicControllers
└── APIBlox.AspNetCore.DynamicControllers.csproj
├── ApiBlox.AspNetCore
└── APIBlox.AspNetCore.csproj
├── ApiBlox.NetCore.Common
└── APIBlox.NetCore.Common.csproj
├── ApiBlox.NetCore
└── APIBlox.NetCore.csproj
├── CODE_OF_CONDUCT.md
├── Directory.Build.props
├── Examples
├── APIBlox Features
│ ├── .gitattributes
│ ├── .gitignore
│ └── Examples.Features
│ │ ├── Configuration
│ │ └── SwaggerConfig.cs
│ │ ├── Contracts
│ │ └── IRandomNumberGeneratorService.cs
│ │ ├── Controllers
│ │ └── ExamplesController.cs
│ │ ├── Examples.Features.csproj
│ │ ├── Examples.Features.xml
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── launchSettings.json
│ │ ├── Resources
│ │ └── ExampleRequestObject.cs
│ │ ├── Services
│ │ └── RandomNumberGeneratorService.cs
│ │ ├── Startup.cs
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.Production.json
│ │ └── appsettings.json
├── CQRS
│ ├── .gitattributes
│ ├── .gitignore
│ └── Examples.Cqrs
│ │ ├── Commands
│ │ ├── SimplePostCommand.cs
│ │ └── SimplePostCommandDecorator.cs
│ │ ├── Configuration
│ │ ├── DecoratorsConfig.cs
│ │ └── SwaggerConfig.cs
│ │ ├── Controllers
│ │ └── CqrsController.cs
│ │ ├── Examples.Cqrs.csproj
│ │ ├── Examples.Cqrs.xml
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── launchSettings.json
│ │ ├── Queries
│ │ ├── NoInputsQueryHandler.cs
│ │ └── RequiresInputQueryQueryHandler.cs
│ │ ├── Resources
│ │ └── ExampleRequestObject.cs
│ │ ├── Startup.cs
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
├── Clean Architecture
│ ├── Application Layer
│ │ ├── .gitattributes
│ │ └── .gitignore
│ ├── Cross-Cutting Concerns
│ │ ├── .gitattributes
│ │ └── .gitignore
│ ├── Domain Layer
│ │ ├── .gitattributes
│ │ └── .gitignore
│ ├── Infrastructure Layer
│ │ ├── .gitattributes
│ │ └── .gitignore
│ ├── Persistance Layer
│ │ ├── .gitattributes
│ │ └── .gitignore
│ └── Presentation Layer
│ │ ├── .gitattributes
│ │ └── .gitignore
├── Domain Events
│ ├── .gitattributes
│ ├── .gitignore
│ └── Examples.DomainEvents
│ │ ├── Configuration
│ │ └── SwaggerConfig.cs
│ │ ├── Contracts
│ │ └── ILameRepository.cs
│ │ ├── Controllers
│ │ └── NonQueuedDomainEventsController.cs
│ │ ├── EventBits
│ │ ├── RequestObjectCreatedEvent.cs
│ │ └── RequestObjectCreatedEventHandler.cs
│ │ ├── Examples.DomainEvents.csproj
│ │ ├── Examples.DomainEvents.csproj.DotSettings
│ │ ├── Examples.DomainEvents.xml
│ │ ├── InfrastructureAndDomainBits
│ │ ├── DomainModels
│ │ │ └── DomainObject.cs
│ │ └── LameRepository.cs
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── launchSettings.json
│ │ ├── Resources
│ │ └── ExampleRequestObject.cs
│ │ ├── Startup.cs
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
├── Dynamic Controllers
│ ├── .gitattributes
│ ├── .gitignore
│ └── Examples.DynamicControllers
│ │ ├── CmdQueryHandlers
│ │ ├── ChildByIdRequestCommandHandler.cs
│ │ ├── ChildByIdRequestHandlers.cs
│ │ ├── ChildPatchRequestCommandHandler.cs
│ │ ├── ChildPostRequestCommandHandler.cs
│ │ ├── ChildPutRequestCommandHandler.cs
│ │ └── ChildrenRequestQueryHandler.cs
│ │ ├── Configuration
│ │ ├── Children.cs
│ │ ├── Parents.cs
│ │ └── SwaggerConfig.cs
│ │ ├── Contracts
│ │ ├── IChildRequest.cs
│ │ └── IRandomNumberGeneratorService.cs
│ │ ├── Examples.DynamicControllers.csproj
│ │ ├── Examples.DynamicControllers.xml
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── launchSettings.json
│ │ ├── Resources
│ │ ├── AllRequest.cs
│ │ ├── ByIdRequest.cs
│ │ ├── ChildByIdRequest.cs
│ │ ├── ChildPatchRequest.cs
│ │ ├── ChildPostRequest.cs
│ │ ├── ChildPutRequest.cs
│ │ ├── ChildRequest.cs
│ │ ├── ChildResponse.cs
│ │ ├── ParentPostRequest.cs
│ │ ├── ParentRequest.cs
│ │ ├── ParentResponse.cs
│ │ └── PersonModel.cs
│ │ ├── Services
│ │ └── RandomNumberGeneratorService.cs
│ │ ├── Startup.cs
│ │ ├── StartupBase.cs
│ │ ├── Testme.cs
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.json
│ │ └── swaggerGen.dat
└── Event Sourcing
│ └── Examples.EventSourcing
│ ├── AggregateModels
│ ├── Aggregate.cs
│ ├── CosmosAggregate.cs
│ ├── EfCoreSqlAggregate.cs
│ ├── MongoAggregate.cs
│ └── RavenAggregate.cs
│ ├── Configuration
│ └── SwaggerConfig.cs
│ ├── Controllers
│ ├── EventSourcingController.cs
│ ├── EventSourcingCosmosDbController.cs
│ ├── EventSourcingEfCoreController.cs
│ ├── EventSourcingMongoDbController.cs
│ └── EventSourcingRavenDbController.cs
│ ├── Events
│ ├── SomeValueAdded.cs
│ └── SomeValueChanged.cs
│ ├── Examples.EventSourcing.csproj
│ ├── Examples.EventSourcing.csproj.DotSettings
│ ├── Examples.EventSourcing.xml
│ ├── Program.cs
│ ├── Properties
│ └── launchSettings.json
│ ├── Resources
│ └── AggregateResource.cs
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
├── Kill Assets.Json.cmd
├── Kill Bin and Obj.cmd
├── LICENSE
├── SlnTests
├── APIBlox.AspNetCore.OpenApi
│ └── BuilderTests.cs
├── APIBlox.AspNetCore
│ ├── DynamicControllerTests.cs
│ └── PaginationTests.cs
├── APIBlox.NetCore.EventStore
│ └── InMemoryRepoTests.cs
├── APIBlox.NetCore
│ ├── PathParserTests.cs
│ ├── ServiceCollectionExtensionsNetCoreOtherTests.cs
│ └── SimpleMapperTests.cs
└── SlnTests.csproj
├── api-blox.sln
├── logo-blue-large.png
├── logo-blue-small.png
├── readme.md
├── releaseNotes.md
└── response-objects.md
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | labels:
5 |
6 | ---
7 |
8 | **Describe the bug**
9 | A clear and concise description of what the bug is.
10 |
11 | **To Reproduce**
12 | Steps to reproduce the behavior:
13 | 1. Go to '...'
14 | 2. Click on '....'
15 | 3. Scroll down to '....'
16 | 4. See error
17 |
18 | **Expected behavior**
19 | A clear and concise description of what you expected to happen.
20 |
21 | **Screenshots**
22 | If applicable, add screenshots to help explain your problem.
23 |
24 | **Desktop (please complete the following information):**
25 | - OS: [e.g. iOS]
26 | - Browser [e.g. chrome, safari]
27 | - Version [e.g. 22]
28 |
29 | **Smartphone (please complete the following information):**
30 | - Device: [e.g. iPhone6]
31 | - OS: [e.g. iOS8.1]
32 | - Browser [e.g. stock browser, safari]
33 | - Version [e.g. 22]
34 |
35 | **Additional context**
36 | Add any other context about the problem here.
37 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | labels:
5 |
6 | ---
7 |
8 | **Is your feature request related to a problem? Please describe.**
9 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
10 |
11 | **Describe the solution you'd like**
12 | A clear and concise description of what you want to happen.
13 |
14 | **Describe alternatives you've considered**
15 | A clear and concise description of any alternative solutions or features you've considered.
16 |
17 | **Additional context**
18 | Add any other context or screenshots about the feature request here.
19 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/DeleteBy/ActionContent.txt:
--------------------------------------------------------------------------------
1 | [ACTION_COMMENTS]
2 | [RESPONSE_TYPES_COMMENTS]
3 | /// The cancellation token.
4 | [PARAMS_COMMENTS]
5 | [HttpDelete("[ACTION_ROUTE]")]
6 | [Produces("application/json", "application/problem+json")]
7 | [Consumes("application/json")]
8 | [ProducesErrorResponseType(typeof(RequestErrorObject))]
9 | [RESPONSE_TYPES]
10 | public async Task [CONTROLLER_NAME]DeleteBy[REQ_OBJECT](
11 | [FromServices]ICommandHandler<[REQ_OBJECT], HandlerResponse> handler,
12 | [ACTION_PARAMS]
13 | CancellationToken cancellationToken
14 | )
15 | {
16 | var ret = await handler.HandleAsync(
17 | [NEW_REQ_OBJECT],
18 | cancellationToken
19 | );
20 |
21 | if (ret is null)
22 | throw new ArgumentException($"You must return a {nameof(HandlerResponse)} instance!");
23 |
24 | if (ret.HasErrors)
25 | return new ProblemResult(ret.Error);
26 |
27 | return ret.HasErrors
28 | ? (IActionResult) new ProblemResult(ret.Error)
29 | : NoContent();
30 | }
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/DeleteBy/CtorArgs.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/DeleteBy/CtorBody.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/DeleteBy/Fields.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/DeleteBy/Namespaces.txt:
--------------------------------------------------------------------------------
1 | System
2 | System.Threading
3 | System.Threading.Tasks
4 | Microsoft.AspNetCore.Http
5 | Microsoft.AspNetCore.Mvc
6 | APIBlox.NetCore.Contracts
7 | APIBlox.AspNetCore.ActionResults
8 | APIBlox.AspNetCore.Contracts
9 | APIBlox.AspNetCore.Types
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PatchBy/ActionContent.txt:
--------------------------------------------------------------------------------
1 | [ACTION_COMMENTS]
2 | [RESPONSE_TYPES_COMMENTS]
3 | /// The cancellation token.
4 | [PARAMS_COMMENTS]
5 | [HttpPatch("[ACTION_ROUTE]")]
6 | [Produces("application/json", "application/problem+json")]
7 | [Consumes("application/json","application/json-patch+json")]
8 | [ProducesErrorResponseType(typeof(RequestErrorObject))]
9 | [RESPONSE_TYPES]
10 | public async Task [CONTROLLER_NAME]PatchBy[REQ_OBJECT](
11 | [FromServices]ICommandHandler<[REQ_OBJECT], HandlerResponse> handler,
12 | [ACTION_PARAMS]
13 | CancellationToken cancellationToken
14 | )
15 | {
16 | var ret = await handler.HandleAsync(
17 | [NEW_REQ_OBJECT],
18 | cancellationToken
19 | );
20 |
21 | if (ret is null)
22 | throw new ArgumentException($"You must return a {nameof(HandlerResponse)} instance!");
23 |
24 | return ret.HasErrors
25 | ? (IActionResult) new ProblemResult(ret.Error)
26 | : NoContent();
27 | }
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PatchBy/CtorArgs.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PatchBy/CtorBody.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PatchBy/Fields.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PatchBy/Namespaces.txt:
--------------------------------------------------------------------------------
1 | System
2 | System.Threading
3 | System.Threading.Tasks
4 | Microsoft.AspNetCore.Http
5 | Microsoft.AspNetCore.JsonPatch
6 | Microsoft.AspNetCore.Mvc
7 | APIBlox.NetCore.Contracts
8 | APIBlox.AspNetCore.ActionResults
9 | APIBlox.AspNetCore.Contracts
10 | APIBlox.AspNetCore.Types
11 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/Post/ActionContent.txt:
--------------------------------------------------------------------------------
1 | [ACTION_COMMENTS]
2 | [RESPONSE_TYPES_COMMENTS]
3 | /// The cancellation token.
4 | [PARAMS_COMMENTS]
5 | [HttpPost("[ACTION_ROUTE]")]
6 | [Produces("application/json", "application/problem+json")]
7 | [Consumes("application/json")]
8 | [ProducesErrorResponseType(typeof(RequestErrorObject))]
9 | [RESPONSE_TYPES]
10 | public async Task [CONTROLLER_NAME]Post[REQ_OBJECT](
11 | [FromServices]ICommandHandler<[REQ_OBJECT], HandlerResponse> handler,
12 | [ACTION_PARAMS]
13 | CancellationToken cancellationToken
14 | )
15 | {
16 | var ret = await handler.HandleAsync(
17 | [NEW_REQ_OBJECT],
18 | cancellationToken
19 | );
20 |
21 | if (ret is null)
22 | throw new ArgumentException($"You must return a {nameof(HandlerResponse)} instance!");
23 |
24 | var errorResult = ret.HasErrors ? new ProblemResult(ret.Error) : null;
25 |
26 | if (errorResult is null && ret.Result is null)
27 | throw new NullReferenceException(
28 | "When responding to a POST you must either set an error or pass some results!"
29 | );
30 |
31 | if (errorResult is not null)
32 | return errorResult;
33 |
34 | var id = FindId(ret.Result);
35 |
36 | return Equals(id, -1) ? Ok(ret.Result) : CreatedAtRoute(new {id}, ret.Result);
37 | }
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/Post/CtorArgs.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/Post/CtorBody.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/Post/Fields.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/Post/Methods.txt:
--------------------------------------------------------------------------------
1 | private object FindId(object result)
2 | {
3 | try
4 | {
5 | var t = result.GetType();
6 | var props = t.GetProperties();
7 |
8 | var id = props.FirstOrDefault(p => p.Name.EqualsEx("Id"));
9 |
10 | if (id is null)
11 | foreach (var pi in props)
12 | return FindId(t.GetProperty(pi.Name).GetValue(result, null));
13 | else
14 | return t.GetProperty(id.Name).GetValue(result, null);
15 | }
16 | catch (Exception ex)
17 | {
18 | _log.LogWarning(() => $"Could not determine ID for CreatedAtRoute result! Ex: {ex.Message}");
19 |
20 | return -1;
21 | }
22 |
23 | return -1;
24 | }
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/Post/Namespaces.txt:
--------------------------------------------------------------------------------
1 | System
2 | System.Linq
3 | System.Threading
4 | System.Threading.Tasks
5 | Microsoft.AspNetCore.Http
6 | Microsoft.AspNetCore.Mvc
7 | Microsoft.Extensions.Logging
8 | APIBlox.NetCore.Contracts
9 | APIBlox.NetCore.Extensions
10 | APIBlox.AspNetCore.ActionResults
11 | APIBlox.AspNetCore.Contracts
12 | APIBlox.AspNetCore.Types
13 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PostAccepted/ActionContent.txt:
--------------------------------------------------------------------------------
1 | [ACTION_COMMENTS]
2 | [RESPONSE_TYPES_COMMENTS]
3 | /// The cancellation token.
4 | [PARAMS_COMMENTS]
5 | [HttpPost("[ACTION_ROUTE]")]
6 | [Produces("application/json", "application/problem+json")]
7 | [Consumes("application/json")]
8 | [ProducesErrorResponseType(typeof(RequestErrorObject))]
9 | [RESPONSE_TYPES]
10 | public async Task [CONTROLLER_NAME]PostAccepted[REQ_OBJECT](
11 | [FromServices]ICommandHandler<[REQ_OBJECT], HandlerResponse> handler,
12 | [ACTION_PARAMS]
13 | CancellationToken cancellationToken
14 | )
15 | {
16 | var ret = await handler.HandleAsync(
17 | [NEW_REQ_OBJECT],
18 | cancellationToken
19 | );
20 |
21 | if (ret is null)
22 | throw new ArgumentException($"You must return a {nameof(HandlerResponse)} instance!");
23 |
24 | var errorResult = ret.HasErrors
25 | ? new ProblemResult(ret.Error)
26 | : null;
27 |
28 | if (errorResult is not null)
29 | return errorResult;
30 |
31 | return ret.Result is null ? Accepted() : Accepted(ret.Result);
32 | }
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PostAccepted/CtorArgs.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PostAccepted/CtorBody.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PostAccepted/Fields.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PostAccepted/Namespaces.txt:
--------------------------------------------------------------------------------
1 | System
2 | System.Threading
3 | System.Threading.Tasks
4 | Microsoft.AspNetCore.Http
5 | Microsoft.AspNetCore.Mvc
6 | APIBlox.NetCore.Contracts
7 | APIBlox.AspNetCore.ActionResults
8 | APIBlox.AspNetCore.Contracts
9 | APIBlox.AspNetCore.Types
10 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PutBy/ActionContent.txt:
--------------------------------------------------------------------------------
1 | [ACTION_COMMENTS]
2 | [RESPONSE_TYPES_COMMENTS]
3 | /// The cancellation token.
4 | [PARAMS_COMMENTS]
5 | [HttpPut("[ACTION_ROUTE]")]
6 | [Produces("application/json", "application/problem+json")]
7 | [Consumes("application/json")]
8 | [ProducesErrorResponseType(typeof(RequestErrorObject))]
9 | [RESPONSE_TYPES]
10 | public async Task [CONTROLLER_NAME]PutBy[REQ_OBJECT](
11 | [FromServices]ICommandHandler<[REQ_OBJECT], HandlerResponse> handler,
12 | [ACTION_PARAMS]
13 | CancellationToken cancellationToken
14 | )
15 | {
16 | var ret = await handler.HandleAsync(
17 | [NEW_REQ_OBJECT],
18 | cancellationToken
19 | );
20 |
21 | if (ret is null)
22 | throw new ArgumentException($"You must return a {nameof(HandlerResponse)} instance!");
23 |
24 | return ret.HasErrors
25 | ? (IActionResult) new ProblemResult(ret.Error)
26 | : NoContent();
27 | }
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PutBy/CtorArgs.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PutBy/CtorBody.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PutBy/Fields.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/PutBy/Namespaces.txt:
--------------------------------------------------------------------------------
1 | System
2 | System.Threading
3 | System.Threading.Tasks
4 | Microsoft.AspNetCore.Http
5 | Microsoft.AspNetCore.Mvc
6 | APIBlox.NetCore.Contracts
7 | APIBlox.AspNetCore.ActionResults
8 | APIBlox.AspNetCore.Contracts
9 | APIBlox.AspNetCore.Types
10 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryAll/ActionContent.txt:
--------------------------------------------------------------------------------
1 | [ACTION_COMMENTS]
2 | [RESPONSE_TYPES_COMMENTS]
3 | /// The cancellation token.
4 | [PARAMS_COMMENTS]
5 | [HttpGet("[ACTION_ROUTE]")]
6 | [Produces("application/json", "application/problem+json")]
7 | [Consumes("application/json")]
8 | [ProducesErrorResponseType(typeof(RequestErrorObject))]
9 | [RESPONSE_TYPES]
10 | public async Task [CONTROLLER_NAME]QueryAll[REQ_OBJECT](
11 | [FromServices]IQueryHandler<[REQ_OBJECT], HandlerResponse> handler,
12 | [ACTION_PARAMS]
13 | CancellationToken cancellationToken
14 | )
15 | {
16 | var ret = await handler.HandleAsync(
17 | [NEW_REQ_OBJECT],
18 | cancellationToken
19 | );
20 |
21 | if (ret is null)
22 | throw new ArgumentException($"You must return a {nameof(HandlerResponse)} instance!");
23 |
24 | if (ret.HasErrors)
25 | return new ProblemResult(ret.Error);
26 |
27 | if (ret.Result is null)
28 | throw new ArgumentNullException(
29 | nameof(HandlerResponse.Result),
30 | "When responding to a GET you must either set an error or pass a result!"
31 | );
32 |
33 | return Ok(ret.Result);
34 | }
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryAll/CtorArgs.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryAll/CtorBody.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryAll/Fields.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryAll/Namespaces.txt:
--------------------------------------------------------------------------------
1 | System
2 | System.Threading
3 | System.Threading.Tasks
4 | Microsoft.AspNetCore.Http
5 | Microsoft.AspNetCore.Mvc
6 | APIBlox.NetCore.Contracts
7 | APIBlox.AspNetCore.ActionResults
8 | APIBlox.AspNetCore.Contracts
9 | APIBlox.AspNetCore.Types
10 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryBy/ActionContent.txt:
--------------------------------------------------------------------------------
1 | [ACTION_COMMENTS]
2 | [RESPONSE_TYPES_COMMENTS]
3 | /// The cancellation token.
4 | [PARAMS_COMMENTS]
5 | [HttpGet("[ACTION_ROUTE]")]
6 | [Produces("application/json", "application/problem+json")]
7 | [Consumes("application/json")]
8 | [ProducesErrorResponseType(typeof(RequestErrorObject))]
9 | [RESPONSE_TYPES]
10 | public async Task [CONTROLLER_NAME]QueryBy[REQ_OBJECT](
11 | [FromServices]IQueryHandler<[REQ_OBJECT], HandlerResponse> handler,
12 | [ACTION_PARAMS]
13 | CancellationToken cancellationToken
14 | )
15 | {
16 | var ret = await handler.HandleAsync(
17 | [NEW_REQ_OBJECT],
18 | cancellationToken
19 | );
20 |
21 | if (ret is null)
22 | throw new ArgumentException($"You must return a {nameof(HandlerResponse)} instance!");
23 |
24 | if (ret.HasErrors)
25 | return new ProblemResult(ret.Error);
26 |
27 | if (ret.Result is null)
28 | throw new ArgumentNullException(
29 | nameof(HandlerResponse.Result),
30 | "When responding to a GET you must either set an error or pass a result!"
31 | );
32 |
33 | return Ok(ret.Result);
34 | }
35 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryBy/CtorArgs.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryBy/CtorBody.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryBy/Fields.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.CommandsQueriesControllersOhMy/Templates/QueryBy/Namespaces.txt:
--------------------------------------------------------------------------------
1 | System
2 | System.Threading
3 | System.Threading.Tasks
4 | Microsoft.AspNetCore.Http
5 | Microsoft.AspNetCore.Mvc
6 | APIBlox.NetCore.Contracts
7 | APIBlox.AspNetCore.ActionResults
8 | APIBlox.AspNetCore.Contracts
9 | APIBlox.AspNetCore.Types
10 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.DynamicControllers/APIBlox.AspNetCore.DynamicControllers.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.AspNetCore
8 |
9 | Simple dynamic controllers package that puts the focus on resources.
10 |
11 | APIBlox.AspNetCore.DynamicControllers
12 |
13 | APIBlox.AspNetCore.DynamicControllers
14 |
15 | APIBlox.AspNetCore.DynamicControllers
16 |
17 | latest
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | all
40 | runtime; build; native; contentfiles; analyzers
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.DynamicControllers/APIBlox.AspNetCore.DynamicControllers.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.DynamicControllers/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.DynamicControllers/Contracts/IComposedTemplate.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Types;
2 |
3 | namespace APIBlox.AspNetCore.Contracts
4 | {
5 | ///
6 | /// Interface IComposedTemplate
7 | ///
8 | public interface IComposedTemplate
9 | {
10 | ///
11 | /// Gets the action.
12 | ///
13 | /// The action.
14 | DynamicAction Action { get; }
15 |
16 | ///
17 | /// Gets or sets the name.
18 | ///
19 | /// The name.
20 | string Name { get; set; }
21 |
22 | ///
23 | /// Gets the route.
24 | ///
25 | /// The route.
26 | string Route { get; }
27 |
28 | ///
29 | /// Gets the namespace.
30 | ///
31 | /// The namespace.
32 | string Namespace { get; }
33 |
34 | ///
35 | /// Gets the comments.
36 | ///
37 | /// The comments.
38 | string Comments { get; set; }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.DynamicControllers/Exceptions/TemplateCompilationException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace APIBlox.AspNetCore.Exceptions
5 | {
6 | ///
7 | ///
8 | /// Class TemplateCompilationException.
9 | ///
10 | [Serializable]
11 | public class TemplateCompilationException : Exception
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | /// The compilation errors.
17 | public TemplateCompilationException(IEnumerable compilationErrors)
18 | : base($"Compilation Errors: \n{string.Join(Environment.NewLine, compilationErrors)}")
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.DynamicControllers/Extensions/MvcBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore;
2 |
3 | // ReSharper disable once CheckNamespace
4 | namespace Microsoft.Extensions.DependencyInjection
5 | {
6 | ///
7 | /// Class MvcBuilderExtensions.
8 | ///
9 | public static class MvcBuilderExtensions
10 | {
11 | ///
12 | /// Adds the post location header result filter.
13 | ///
14 | /// The builder.
15 | /// IMvcBuilder.
16 | public static IMvcBuilder AddPostLocationHeaderResultFilter(
17 | this IMvcBuilder builder
18 | )
19 | {
20 | return builder.AddFilter(order: 100);
21 | }
22 |
23 | ///
24 | /// Adds the post location header result filter.
25 | ///
26 | /// The builder.
27 | /// IMvcCoreBuilder.
28 | public static IMvcCoreBuilder AddPostLocationHeaderResultFilter(
29 | this IMvcCoreBuilder builder
30 | )
31 | {
32 | return builder.AddFilter(order: 100);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.DynamicControllers/Templates/DynamicController.txt:
--------------------------------------------------------------------------------
1 | [NAMESPACES]
2 |
3 | namespace [CONTROLLERS_NAMESPACE].Controllers
4 | {
5 | ///
6 | [CONTROLLER_REQ_OBJ_SUMMARY]
7 | ///
8 | [Route("[CONTROLLER_ROUTE]")]
9 | [ApiController]
10 | public sealed class [CONTROLLER_NAME] : ControllerBase
11 | {
12 | [FIELDS]
13 |
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | public [CONTROLLER_NAME](
18 | [CTOR_ARGS]
19 | )
20 | {
21 | _log = loggerFactory.CreateLogger<[CONTROLLER_NAME]>();
22 |
23 | [CTOR_BODY]
24 | }
25 |
26 | [ACTIONS]
27 |
28 |
29 | [METHODS]
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore.DynamicControllers/Types/DynamicComments.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using APIBlox.NetCore.Extensions;
3 |
4 | namespace APIBlox.AspNetCore.Types
5 | {
6 | ///
7 | /// Class DynamicComments.
8 | ///
9 | public class DynamicComments
10 | {
11 | private const string RemarksTemplate = @"
12 | ///
13 | /// @remarks
14 | ///
15 | ";
16 |
17 | private const string SummaryTemplate = @"
18 | ///
19 | /// @summary
20 | ///
21 | ";
22 |
23 | ///
24 | /// Gets or sets the summary.
25 | ///
26 | /// The summary.
27 | public string Summary { get; set; }
28 |
29 | ///
30 | /// Gets or sets the remarks.
31 | ///
32 | /// The remarks.
33 | public string Remarks { get; set; }
34 |
35 | ///
36 | /// Returns a that represents this instance.
37 | ///
38 | /// A that represents this instance.
39 | public override string ToString()
40 | {
41 | var summary = Summary.IsEmptyNullOrWhiteSpace()
42 | ? null
43 | : SummaryTemplate.Replace("@summary", Summary.Replace(Environment.NewLine, "\n/// "));
44 | var remarks = Remarks.IsEmptyNullOrWhiteSpace()
45 | ? null
46 | : RemarksTemplate.Replace("@remarks", Remarks.Replace(Environment.NewLine, "\n/// "));
47 |
48 | return $"{summary}{remarks}";
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/APIBlox.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.AspNetCore
8 |
9 | AspNetCore bits.
10 |
11 | APIBlox.AspNetCore
12 |
13 | APIBlox.AspNetCore
14 |
15 | APIBlox.AspNetCore
16 |
17 | latest
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | all
36 | runtime; build; native; contentfiles; analyzers
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/APIBlox.AspNetCore.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.AspNetCore
2 | {
3 | ///
4 | /// Class Constants.
5 | ///
6 | public static class Constants
7 | {
8 | ///
9 | /// Class ResponseTypes.
10 | ///
11 | public static class ResponseTypes
12 | {
13 | ///
14 | /// The error response content type
15 | ///
16 | public const string ErrorResponseContentType = "application/problem+json";
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Contracts/IFilteredQuery.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.AspNetCore.Contracts
2 | {
3 | ///
4 | /// Interface IFilteredQuery
5 | ///
6 | public interface IFilteredQuery : IQuery
7 | {
8 | ///
9 | /// Gets or sets the filter.
10 | ///
11 | /// The filter.
12 | string Filter { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Contracts/IOrderedQuery.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.AspNetCore.Contracts
2 | {
3 | ///
4 | /// Interface IOrderedQuery
5 | ///
6 | public interface IOrderedQuery : IQuery
7 | {
8 | ///
9 | /// Gets or sets the order by.
10 | ///
11 | /// The order by.
12 | string OrderBy { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Contracts/IPaginationMetadataBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using APIBlox.AspNetCore.Services;
3 | using Microsoft.AspNetCore.Mvc.Filters;
4 |
5 | namespace APIBlox.AspNetCore.Contracts
6 | {
7 | internal interface IPaginationMetadataBuilder
8 | {
9 | PaginationMetadata Build(int resultCount, ActionExecutingContext context);
10 |
11 | List Routes { get; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Contracts/IPaginationQuery.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.AspNetCore.Contracts
2 | {
3 | ///
4 | ///
5 | /// Interface IPaginationQuery
6 | ///
7 | public interface IPaginationQuery : IQuery
8 | {
9 | ///
10 | /// Gets or sets the running count.
11 | ///
12 | /// The running count.
13 | int? RunningCount { get; set; }
14 |
15 | ///
16 | /// Gets or sets the skip.
17 | ///
18 | /// The skip.
19 | int? Skip { get; set; }
20 |
21 | ///
22 | /// Gets or sets the top.
23 | ///
24 | /// The top.
25 | int? Top { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Contracts/IProjectedQuery.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.AspNetCore.Contracts
2 | {
3 | ///
4 | /// Interface IProjectedQuery
5 | ///
6 | public interface IProjectedQuery : IQuery
7 | {
8 | ///
9 | /// Gets or sets the select.
10 | ///
11 | /// The select.
12 | string Select { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Contracts/IQuery.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.AspNetCore.Contracts
2 | {
3 | ///
4 | /// Marker Interface IQuery
5 | ///
6 | public interface IQuery
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Contracts/IResource.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.AspNetCore.Contracts
2 | {
3 | ///
4 | /// Marker interface
5 | ///
6 | public interface IResource
7 | {
8 | }
9 |
10 | ///
11 | ///
12 | /// Interface IResource
13 | ///
14 | /// The type of the t id.
15 | ///
16 | public interface IResource : IResource
17 | {
18 | ///
19 | /// Gets or sets the Id.
20 | ///
21 | /// The Id.
22 | TId Id { get; set; }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Exceptions/HandledRequestException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using APIBlox.AspNetCore.Types;
3 |
4 | namespace APIBlox.AspNetCore.Exceptions
5 | {
6 | ///
7 | ///
8 | /// Class HandledRequestException.
9 | ///
10 | ///
11 | public class HandledRequestException : Exception
12 | {
13 | ///
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | /// The request error object.
18 | public HandledRequestException(RequestErrorObject requestErrorObject)
19 | {
20 | RequestErrorObject = requestErrorObject;
21 | }
22 |
23 | ///
24 | /// Gets the request error object.
25 | ///
26 | /// The request error object.
27 | public RequestErrorObject RequestErrorObject { get; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Extensions/ErrorExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using APIBlox.AspNetCore.Types;
4 |
5 | namespace APIBlox.AspNetCore.Extensions
6 | {
7 | ///
8 | /// Class ErrorExtensions.
9 | ///
10 | [DebuggerStepThrough]
11 | public static class ErrorExtensions
12 | {
13 | internal static DynamicErrorObject ToDynamicDataObject(this Exception ex, bool noThrow)
14 | {
15 | var ret = new DynamicErrorObject("Error Details", ex.Message)
16 | {
17 | NoThrow = noThrow
18 | };
19 |
20 | dynamic d = ret;
21 |
22 | d.Type = ex.GetType().Name;
23 |
24 | if (ex.InnerException is null)
25 | return ret;
26 |
27 | ret.Title = "Please refer to the error property for additional information.";
28 | ret.Errors.Add(ex.InnerException.ToDynamicDataObject(noThrow));
29 |
30 | return ret;
31 | }
32 |
33 | ///
34 | /// Builds an from an exception along with all inner exceptions.
35 | ///
36 | /// The ex.
37 | /// DynamicErrorObject.
38 | public static DynamicErrorObject ToDynamicDataObject(this Exception ex)
39 | {
40 | var ret = new DynamicErrorObject("Error Details", ex.Message);
41 | dynamic d = ret;
42 |
43 | d.Type = ex.GetType().Name;
44 |
45 | if (ex.InnerException is null)
46 | return ret;
47 |
48 | ret.Title = "Please refer to the error property for additional information.";
49 | ret.Errors.Add(ex.InnerException.ToDynamicDataObject());
50 |
51 | return ret;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Filters/Action Filters/ValidateResourceActionFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using APIBlox.AspNetCore.ActionResults;
3 | using Microsoft.AspNetCore.Mvc.Filters;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace APIBlox.AspNetCore.Filters
7 | {
8 | internal class ValidateResourceActionFilter : IAsyncActionFilter
9 | {
10 | private readonly ILogger _log;
11 |
12 | public ValidateResourceActionFilter(ILoggerFactory loggerFactory)
13 | {
14 | _log = loggerFactory.CreateLogger();
15 | }
16 |
17 | public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
18 | {
19 | if (context.ModelState.IsValid)
20 | {
21 | _log.LogInformation(() => $"Validation succeeded for {context.Result}");
22 |
23 | await next().ConfigureAwait(false);
24 |
25 | return;
26 | }
27 |
28 | _log.LogWarning(() => $"Validation failed for {context}, returning new ValidationFailureResult");
29 |
30 | context.Result = new ValidationFailureResult();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Filters/Exception Filters/OperationCanceledExceptionFilter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using Microsoft.AspNetCore.Mvc;
4 | using Microsoft.AspNetCore.Mvc.Filters;
5 | using Microsoft.Extensions.Logging;
6 |
7 | // ReSharper disable once CheckNamespace
8 | namespace APIBlox.AspNetCore
9 | {
10 | internal class OperationCanceledExceptionFilter : IAsyncExceptionFilter
11 | {
12 | private readonly ILogger _log;
13 |
14 | public OperationCanceledExceptionFilter(ILoggerFactory loggerFactory)
15 | {
16 | _log = loggerFactory.CreateLogger();
17 | }
18 |
19 | public Task OnExceptionAsync(ExceptionContext context)
20 | {
21 | if (context.Exception is not OperationCanceledException)
22 | {
23 | _log.LogInformation(() => $"Skipping execute, exception is of type {context.Exception.GetType()}");
24 |
25 | return Task.CompletedTask;
26 | }
27 |
28 | _log.LogInformation(() => $"Request {context.HttpContext.Request.Path} was cancelled.");
29 |
30 | context.ExceptionHandled = true;
31 |
32 | // Client Closed Request, this is a non-standard status code used by NGINX
33 | context.Result = new StatusCodeResult(499);
34 |
35 | return Task.CompletedTask;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/ModelBinders/FromQueryWithAlterenateNamesBinderProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using APIBlox.AspNetCore.Attributes;
4 | using Microsoft.AspNetCore.Mvc.ModelBinding;
5 | using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
6 | using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
7 |
8 | namespace APIBlox.AspNetCore.ModelBinders
9 | {
10 | internal class FromQueryWithAlternateNamesBinderProvider : IModelBinderProvider
11 | {
12 | public IModelBinder GetBinder(ModelBinderProviderContext context)
13 | {
14 | if (context == null)
15 | throw new ArgumentNullException(nameof(context));
16 |
17 | return IsIQuery(context)
18 | ? new BinderTypeModelBinder(typeof(FromQueryAlternateNamesBinder))
19 | : null;
20 | }
21 |
22 | private static bool IsIQuery(ModelBinderProviderContext c)
23 | {
24 | var attrs = ((DefaultModelMetadata)c.Metadata).Attributes.Attributes;
25 |
26 | return attrs is not null && attrs.Any(pa => pa.GetType() == typeof(FromQueryWithAlternateNamesAttribute));
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Services/PaginationMetadata.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.AspNetCore.Services
2 | {
3 | ///
4 | /// Class PaginationMetadata.
5 | ///
6 | public class PaginationMetadata
7 | {
8 | ///
9 | /// Gets or sets the count for this result.
10 | ///
11 | /// The count.
12 | public long? ResultCount { get; set; }
13 |
14 | ///
15 | /// Gets or sets the next.
16 | ///
17 | /// The next.
18 | public string Next { get; set; }
19 |
20 | ///
21 | /// Gets or sets the previous.
22 | ///
23 | /// The previous.
24 | public string Previous { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/Errors/ServerErrorObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using APIBlox.NetCore.Extensions;
5 | using Microsoft.Extensions.Logging;
6 |
7 | namespace APIBlox.AspNetCore.Types
8 | {
9 | internal class ServerErrorObject : RequestErrorObject
10 | {
11 | public ServerErrorObject(string title, string detail, int status, string instance, string referenceId)
12 | : base(title, detail, status, instance)
13 | {
14 | ReferenceId = referenceId;
15 | }
16 |
17 | private string ReferenceId { get; }
18 |
19 | public override IEnumerable GetDynamicMemberNames()
20 | {
21 | if (ReferenceId.IsEmptyNullOrWhiteSpace())
22 | {
23 | var msg = $"Although {GetType().Name}.{nameof(ReferenceId)} " +
24 | "is not required by RFC7807, we still want it!";
25 |
26 | if (NoThrow)
27 | Logger.LogWarning(() => msg);
28 | else
29 | throw new ArgumentException(msg, nameof(ReferenceId));
30 | }
31 | else
32 | {
33 | Properties.TryAdd("ReferenceId", ReferenceId);
34 | }
35 |
36 | if (Errors is not null && Errors.Any())
37 | Properties.TryAdd("Errors", Errors);
38 |
39 | return base.GetDynamicMemberNames();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/FilteredOrderedQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class FilteredOrderedQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to FilteredQuery, OrderBy = $OrderBy, SortBy, $SortBy, Sort, $Sort
16 | ///
17 | ///
18 | public class FilteredOrderedQuery : FilteredQuery, IOrderedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public FilteredOrderedQuery()
24 | {
25 | Map.TryAdd("OrderBy", new[] { "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort" });
26 | }
27 |
28 | ///
29 | /// Sets the order by. Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("orderBy", "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort" )]
32 | public string OrderBy { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!OrderBy.IsEmptyNullOrWhiteSpace())
43 | qb.Add("orderBy", OrderBy);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/FilteredPaginationQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class FilteredPaginationQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to PaginationQuery, Filter = $Where, Where, $Filter
16 | ///
17 | ///
18 | public class FilteredPaginationQuery : PaginationQuery, IFilteredQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public FilteredPaginationQuery()
24 | {
25 | Map.TryAdd("Filter", new[] { "$Where", "Where", "$Filter" });
26 | }
27 |
28 | ///
29 | /// Sets the filter (where). Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("filter", "$Where", "Where", "$Filter")]
32 | public string Filter { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!Filter.IsEmptyNullOrWhiteSpace())
43 | qb.Add("filter", Filter);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/FilteredProjectedOrderedQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class FilteredProjectedOrderedQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to FilteredQuery, Select = $Select, Project, $Project
16 | ///
17 | ///
18 | public class FilteredProjectedOrderedQuery : FilteredQuery, IProjectedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public FilteredProjectedOrderedQuery()
24 | {
25 | Map.TryAdd("Select", new[] {"$Select", "Project", "$Project"});
26 | }
27 |
28 | ///
29 | /// Sets the select (projection). Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("select", "$Select", "Project", "$Project" )]
32 | public string Select { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!Select.IsEmptyNullOrWhiteSpace())
43 | qb.Add("select", Select);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/FilteredProjectedPaginationQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class FilteredProjectedPaginationQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to FilteredPaginationQuery, Select = $Select, Project, $Project
16 | ///
17 | ///
18 | public class FilteredProjectedPaginationQuery : FilteredPaginationQuery, IProjectedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public FilteredProjectedPaginationQuery()
24 | {
25 | Map.TryAdd("Select", new[] { "$Select", "Project", "$Project" });
26 | }
27 |
28 | ///
29 | /// Sets the select (projection). Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("select", "$Select", "Project", "$Project")]
32 | public string Select { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!Select.IsEmptyNullOrWhiteSpace())
43 | qb.Add("select", Select);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/FilteredProjectedQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class FilteredProjectedQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to FilteredQuery, Select = $Select, Project, $Project
16 | ///
17 | ///
18 | public class FilteredProjectedQuery : FilteredQuery, IProjectedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public FilteredProjectedQuery()
24 | {
25 | Map.TryAdd("Select", new[] { "$Select", "Project", "$Project" });
26 | }
27 |
28 | ///
29 | /// Sets the select (projection). Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("select", "$Select", "Project", "$Project")]
32 | public string Select { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!Select.IsEmptyNullOrWhiteSpace())
43 | qb.Add("select", Select);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/FilteredQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class FilteredQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates to Filter = $Where, Where, $Filter
16 | ///
17 | ///
18 | public class FilteredQuery : Query, IFilteredQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public FilteredQuery()
24 | {
25 | Map.TryAdd("Filter", new[] { "$Where", "Where", "$Filter" });
26 | }
27 |
28 | ///
29 | /// Sets the filter (where). Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("filter", "$Where", "$WHERE", "$whERE", "$Where", "Where", "$Filter")]
32 | public string Filter { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!Filter.IsEmptyNullOrWhiteSpace())
43 | qb.Add("filter", Filter);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/HandlerResponse.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using APIBlox.AspNetCore.Enums;
3 |
4 | namespace APIBlox.AspNetCore.Types
5 | {
6 | ///
7 | /// Class HandlerResponse.
8 | ///
9 | [DebuggerStepThrough]
10 | public sealed class HandlerResponse
11 | {
12 | ///
13 | /// Gets the , I can be set
14 | /// using
15 | ///
16 | /// The error.
17 | public RequestErrorObject Error { get; internal set; }
18 |
19 | ///
20 | /// Gets a value indicating whether this instance has errors.
21 | ///
22 | ///
23 | /// true if the is not null OR a Status that is NOT
24 | /// ;
25 | /// otherwise,false.
26 | ///
27 | public bool HasErrors => Error is not null || Status != CommonStatusCodes.Status200Ok;
28 |
29 | ///
30 | /// Gets or sets the result.
31 | ///
32 | /// The result.
33 | public dynamic Result { get; set; }
34 |
35 | ///
36 | /// Gets or sets the status.
37 | ///
38 | /// The status.
39 | public CommonStatusCodes Status { get; set; } = CommonStatusCodes.Status200Ok;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/OrderedPaginationQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class OrderedPaginationQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to PaginationQuery, OrderBy = $OrderBy, SortBy, $SortBy, Sort, $Sort
16 | ///
17 | ///
18 | public class OrderedPaginationQuery : PaginationQuery, IOrderedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public OrderedPaginationQuery()
24 | {
25 | Map.TryAdd("OrderBy", new[] { "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort" });
26 | }
27 |
28 | ///
29 | /// Sets the order by. Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("orderBy", "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort")]
32 | public string OrderBy { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!OrderBy.IsEmptyNullOrWhiteSpace())
43 | qb.Add("orderBy", OrderBy);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/OrderedQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class OrderedQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates to OrderBy = $OrderBy, SortBy, $SortBy, Sort, $Sort
16 | ///
17 | ///
18 | public class OrderedQuery : Query, IOrderedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public OrderedQuery()
24 | {
25 | Map.TryAdd("OrderBy", new[] { "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort" });
26 | }
27 |
28 | ///
29 | /// Sets the order by. Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("orderBy", "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort")]
32 | public string OrderBy { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!OrderBy.IsEmptyNullOrWhiteSpace())
43 | qb.Add("orderBy", OrderBy);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/ProjectedOrderedPaginationQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class ProjectedOrderedPaginationQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to ProjectedPaginationQuery, OrderBy = $OrderBy, SortBy, $SortBy, Sort, $Sort
16 | ///
17 | ///
18 | public class ProjectedOrderedPaginationQuery : ProjectedPaginationQuery, IOrderedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public ProjectedOrderedPaginationQuery()
24 | {
25 | Map.TryAdd("OrderBy", new[] { "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort" });
26 | }
27 |
28 | ///
29 | /// Sets the order by. Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("orderBy", "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort")]
32 | public string OrderBy { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!OrderBy.IsEmptyNullOrWhiteSpace())
43 | qb.Add("orderBy", OrderBy);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/ProjectedOrderedQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class ProjectedOrderedQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to ProjectedQuery, OrderBy = $OrderBy, SortBy, $SortBy, Sort, $Sort
16 | ///
17 | ///
18 | public class ProjectedOrderedQuery : ProjectedQuery, IOrderedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public ProjectedOrderedQuery()
24 | {
25 | Map.TryAdd("OrderBy", new[] { "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort" });
26 | }
27 |
28 | ///
29 | /// Sets the order by. Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("orderBy", "$OrderBy", "SortBy", "$SortBy", "Sort", "$Sort")]
32 | public string OrderBy { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!OrderBy.IsEmptyNullOrWhiteSpace())
43 | qb.Add("orderBy", OrderBy);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/ProjectedPaginationQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class ProjectedPaginationQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates In addition to ProjectedQuery, Select = $Select, Project, $Project
16 | ///
17 | ///
18 | public class ProjectedPaginationQuery : PaginationQuery, IProjectedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public ProjectedPaginationQuery()
24 | {
25 | Map.TryAdd("Select", new[] { "$Select", "Project", "$Project" });
26 | }
27 |
28 | ///
29 | /// Sets the select (projection). Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("select", "$Select", "Project", "$Project")]
32 | public string Select { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!Select.IsEmptyNullOrWhiteSpace())
43 | qb.Add("select", Select);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.AspNetCore/Types/ProjectedQuery.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Attributes;
2 | using APIBlox.AspNetCore.Contracts;
3 | using APIBlox.NetCore.Extensions;
4 | using Microsoft.AspNetCore.Http.Extensions;
5 |
6 | namespace APIBlox.AspNetCore.Types
7 | {
8 | ///
9 | /// Class ProjectedQuery.
10 | ///
11 | /// Be sure to also call the AddFromQueryWithAlternateNamesBinder Mvc/MvcCore
12 | /// builder extension method to allow alternate names to be used.
13 | ///
14 | ///
15 | /// Alternates to Select = $Select, Project, $Project
16 | ///
17 | ///
18 | public class ProjectedQuery : Query, IProjectedQuery
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public ProjectedQuery()
24 | {
25 | Map.TryAdd("Select", new[] { "$Select", "Project", "$Project" });
26 | }
27 |
28 | ///
29 | /// Sets the select (projection). Usage is determined by the API itself, please seek external documentation.
30 | ///
31 | [FromQueryWithAlternateNames("select", "$Select", "Project", "$Project")]
32 | public string Select { get; set; }
33 |
34 | ///
35 | /// Builds the query.
36 | ///
37 | /// QueryBuilder.
38 | protected override QueryBuilder BuildQuery()
39 | {
40 | var qb = base.BuildQuery();
41 |
42 | if (!Select.IsEmptyNullOrWhiteSpace())
43 | qb.Add("select", Select);
44 |
45 | return qb;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.CommandsAndQueries/APIBlox.NetCore.CommandsAndQueries.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.NetCore
8 |
9 | APIBlox.NetCore.CommandsAndQueries
10 |
11 | Simple CQRS implementation that utilizes the decorator pattern.
12 |
13 | APIBlox.NetCore.CommandsAndQueries
14 |
15 | APIBlox.NetCore.CommandsAndQueries
16 |
17 | latest
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | all
28 | runtime; build; native; contentfiles; analyzers
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.CommandsAndQueries/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.CommandsAndQueries/Contracts/IQueryHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 |
4 | namespace APIBlox.NetCore.Contracts
5 | {
6 | ///
7 | /// Interface IQueryHandler, used when your QUERY requires input parameters, IE: GetSomething(requirements)
8 | ///
9 | /// The type of the query.
10 | /// The type of the result.
11 | public interface IQueryHandler
12 | {
13 | ///
14 | /// Handles the specified query.
15 | ///
16 | /// The query.
17 | /// The cancellation token.
18 | /// Task{TResult}.
19 | Task HandleAsync(TRequestQuery query, CancellationToken cancellationToken);
20 | }
21 |
22 | ///
23 | /// Interface IQueryHandler, used when your QUERY does not require input parameters, IE: GetAll()
24 | ///
25 | /// The type of the result.
26 | public interface IQueryHandler
27 | {
28 | ///
29 | /// Handles the specified cancellation token.
30 | ///
31 | /// The cancellation token.
32 | /// Task{TResult}.
33 | Task HandleAsync(CancellationToken cancellationToken);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.Common/APIBlox.NetCore.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.NetCore
8 |
9 | Cross-Cutting.NetCore bits.
10 |
11 | APIBlox.NetCore.Common
12 |
13 | APIBlox.NetCore.Common
14 |
15 | APIBlox.NetCore.Common
16 |
17 | latest
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.Common/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.Common/Extensions/EnumExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 |
4 | namespace APIBlox.NetCore.Extensions
5 | {
6 | ///
7 | /// Class EnumExtensions.
8 | ///
9 | [DebuggerStepThrough]
10 | public static class EnumExtensions
11 | {
12 | ///
13 | /// Gets the type of the attribute of.
14 | ///
15 | ///
16 | /// The enum value.
17 | /// T.
18 | public static T GetAttributeOfType(this Enum enumVal)
19 | where T : Attribute
20 | {
21 | var type = enumVal.GetType();
22 | var memInfo = type.GetMember(enumVal.ToString());
23 | var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
24 |
25 | return attributes.Length > 0
26 | ? (T) attributes[0]
27 | : null;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.Common/Extensions/ExpressionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace APIBlox.NetCore.Extensions
4 | {
5 | ///
6 | /// Class ExpressionExtensions.
7 | ///
8 | public static class ExpressionExtensions
9 | {
10 | ///
11 | /// Simplified AndAlso expression generation.
12 | ///
13 | /// The type of the t delegate.
14 | /// The left.
15 | /// The right.
16 | /// Expression<TDelegate>.
17 | public static Expression AndAlso(this Expression left, Expression right)
18 | {
19 | return Expression.Lambda(Expression.AndAlso(left, right), left.Parameters);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.Common/Extensions/StructExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Extensions
2 | {
3 | ///
4 | /// Class NumberExtensions.
5 | ///
6 | public static class StructExtensions
7 | {
8 | ///
9 | /// Determines whether [is null or zero] [the specified value].
10 | ///
11 | ///
12 | /// The value.
13 | /// true if [is null or zero] [the specified value]; otherwise, false.
14 | public static bool IsNullOrZero(this T? value)
15 | where T : struct
16 | {
17 | return !value.HasValue || Equals(value, default(T));
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.Common/Types/JsonBits/CamelCaseSettings.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Newtonsoft.Json.Serialization;
3 |
4 | namespace APIBlox.NetCore.Types.JsonBits
5 | {
6 | ///
7 | ///
8 | /// Class CamelCaseSettings.
9 | /// Implements the
10 | ///
11 | public class CamelCaseSettings : JsonSerializerSettings
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | public CamelCaseSettings()
17 | {
18 | ContractResolver = new CamelCasePropertyNamesContractResolver();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/APIBlox.NetCore.DomainEvents.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 |
6 | APIBlox.NetCore
7 |
8 | Simple domain events.
9 |
10 | APIBlox.NetCore.DomainEvents
11 |
12 | APIBlox.NetCore.DomainEvents
13 |
14 | APIBlox.NetCore.DomainEvents
15 |
16 | latest
17 |
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/Contracts/IDomainEvent.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Contracts
2 | {
3 | ///
4 | /// Marker Interface
5 | ///
6 | /// Important characteristics of events is that since an event is something that happened in the past,
7 | /// it should not change. Therefore it must be an immutable class. It's name should also be of the past tense.
8 | ///
9 | ///
10 | public interface IDomainEvent
11 | {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/Contracts/IDomainEventHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 |
4 | namespace APIBlox.NetCore.Contracts
5 | {
6 | ///
7 | /// Interface IDomainEventHandler
8 | ///
9 | /// The type of the t domain event.
10 | public interface IDomainEventHandler
11 | where TDomainEvent : IDomainEvent
12 | {
13 | ///
14 | /// Handles the event asynchronous.
15 | ///
16 | /// The domain event.
17 | /// The cancellation token.
18 | /// Task.
19 | Task HandleEventAsync(TDomainEvent domainEvent, CancellationToken cancellationToken = default);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/Contracts/IDomainEventsDispatcher.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace APIBlox.NetCore.Contracts
4 | {
5 | ///
6 | /// Interface IDomainEventsDispatcher
7 | ///
8 | public interface IDomainEventsDispatcher
9 | {
10 | ///
11 | /// Publishes all events asynchronously.
12 | ///
13 | /// The type of the t domain event.
14 | /// The events.
15 | /// Task.
16 | Task PublishEventsAsync(params TDomainEvent[] events)
17 | where TDomainEvent : class, IDomainEvent;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/Contracts/IQueuedDomainEventsDispatcher.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace APIBlox.NetCore.Contracts
4 | {
5 | ///
6 | /// Interface IQueuedDomainEventsDispatcher
7 | ///
8 | public interface IQueuedDomainEventsDispatcher
9 | {
10 | ///
11 | /// Adds an event to the queue.
12 | ///
13 | /// The type of the t domain event.
14 | /// The domain event.
15 | /// Task.
16 | void AddEvent(TDomainEvent domainEvent)
17 | where TDomainEvent : class, IDomainEvent;
18 |
19 | ///
20 | /// Publishes all events, either one at a time or using .
21 | ///
22 | /// if set to true [when all].
23 | /// Task.
24 | Task PublishEventsAsync(bool whenAll = true);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/Dispatchers/DispatcherBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using APIBlox.NetCore.Contracts;
6 | using Microsoft.Extensions.DependencyInjection;
7 |
8 | // ReSharper disable once CheckNamespace
9 | namespace APIBlox.NetCore
10 | {
11 | internal abstract class DispatcherBase
12 | {
13 | private readonly IServiceProvider _serviceProvider;
14 |
15 | protected DispatcherBase(
16 | IServiceProvider serviceProvider
17 | )
18 | {
19 | _serviceProvider = serviceProvider;
20 | }
21 |
22 | protected Task ExecuteHandlers(IDomainEvent de, Action callback)
23 | {
24 | // Find the correct handlers, that has a generic arg that matches the event type.
25 | // Create a wrapper to prevent from invoking magic string methods.
26 | var deType = de.GetType();
27 | var handlerType = typeof(IDomainEventHandler<>).MakeGenericType(deType);
28 | var handlerWrapperType = typeof(DomainEventHandlerWrapper<>).MakeGenericType(deType);
29 | var handlers = _serviceProvider.GetServices(handlerType).ToList();
30 |
31 | var wrapped = handlers.Select(h =>
32 | (DomainEventHandlerBase) Activator.CreateInstance(handlerWrapperType, h)
33 | );
34 |
35 | var tasks = new List();
36 |
37 | foreach (var dh in wrapped)
38 | {
39 | var t = dh?.HandleEventAsync(de);
40 | tasks.Add(t);
41 | callback(t);
42 | }
43 |
44 | Task.WaitAll(tasks.ToArray());
45 |
46 | return Task.CompletedTask;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/Domain Events Notes.txt:
--------------------------------------------------------------------------------
1 | From: https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/domain-events-design-implementation
2 |
3 | It is important to understand that this event-based communication is not implemented directly within the aggregates; you need to implement
4 | domain event handlers. Handling the domain events is an application concern. The domain model layer should only focus on the domain logic—things
5 | that a domain expert would understand, not application infrastructure like handlers and side-effect persistence actions using repositories.
6 | Therefore, the application layer level is where you should have domain event handlers triggering actions when a domain event is raised.
7 |
8 |
9 | I don't get it, accepted practice is to put events (creating) in entities. What if your application isnt using
10 | events for whatever reason? now theres functionality that is unnecessary.
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/Handlers/DomainEventHandlerBase.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.NetCore.Contracts;
4 |
5 | // ReSharper disable once CheckNamespace
6 | namespace APIBlox.NetCore
7 | {
8 | internal abstract class DomainEventHandlerBase
9 | {
10 | ///
11 | /// Handles the event asynchronous.
12 | ///
13 | /// The domain event.
14 | /// The cancellation token.
15 | /// Task.
16 | public abstract Task HandleEventAsync(IDomainEvent domainEvent, CancellationToken cancellationToken = default);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.DomainEvents/Handlers/DomainEventHandlerWrapper.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.NetCore.Contracts;
4 |
5 | // ReSharper disable once CheckNamespace
6 | namespace APIBlox.NetCore
7 | {
8 | internal class DomainEventHandlerWrapper : DomainEventHandlerBase
9 | where TDomainEvent : IDomainEvent
10 | {
11 | private readonly IDomainEventHandler _handler;
12 |
13 | public DomainEventHandlerWrapper(IDomainEventHandler handler)
14 | {
15 | _handler = handler;
16 | }
17 |
18 | public override Task HandleEventAsync(IDomainEvent domainEvent, CancellationToken cancellationToken = default)
19 | {
20 | return _handler.HandleEventAsync((TDomainEvent) domainEvent, cancellationToken);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.CosmosDb/APIBlox.NetCore.EventStore.CosmosDb.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 |
6 | APIBlox.NetCore
7 |
8 | CosmosDB backing for APIBlox.NetCore.EventStore.
9 |
10 | APIBlox.NetCore.EventStore.CosmosDb
11 |
12 | APIBlox.NetCore.EventStore.CosmosDb
13 |
14 | APIBlox.NetCore.EventStore.CosmosDb
15 |
16 | latest
17 |
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | PreserveNewest
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.CosmosDb/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.CosmosDb/DbCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using APIBlox.NetCore.Options;
3 |
4 | namespace APIBlox.NetCore
5 | {
6 | internal class DbCollection
7 | {
8 | public int DatabaseThroughput { get; set; }
9 |
10 | public string DatabaseId { get; set; }
11 |
12 | public string CollectionId { get; set; }
13 |
14 | public Uri DocumentCollectionUri { get; set; }
15 |
16 | public CosmosDbCollectionProperties ColProps { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.CosmosDb/Options/CosmosDbCollectionProperties.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Microsoft.Azure.Documents;
3 |
4 | namespace APIBlox.NetCore.Options
5 | {
6 | ///
7 | /// Class CollectionProperties.
8 | ///
9 | public class CosmosDbCollectionProperties
10 | {
11 | ///
12 | /// Gets or sets the models.
13 | ///
14 | public List Models { get; set; }
15 |
16 | ///
17 | /// Gets or sets the unique key policy.
18 | ///
19 | public UniqueKeyPolicy UniqueKeyPolicy { get; set; } = new();
20 |
21 | ///
22 | /// Gets or sets the offer throughput.
23 | ///
24 | public int OfferThroughput { get; set; } = -1;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.CosmosDb/Options/CosmosDbOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Microsoft.Azure.Documents.Client;
3 |
4 | namespace APIBlox.NetCore.Options
5 | {
6 | ///
7 | /// Class CosmosDbOptions.
8 | ///
9 | public class CosmosDbOptions
10 | {
11 | ///
12 | /// Gets or sets the endpoint.
13 | ///
14 | public string Endpoint { get; set; }
15 |
16 | ///
17 | /// Gets or sets the key.
18 | ///
19 | public string Key { get; set; }
20 |
21 | ///
22 | /// Gets or sets the database identifier.
23 | ///
24 | public string DatabaseId { get; set; }
25 |
26 | ///
27 | /// Gets or sets the connection policy.
28 | ///
29 | public ConnectionPolicy ConnectionPolicy { get; set; }
30 |
31 | ///
32 | /// Gets or sets the offer throughput.
33 | ///
34 | public int OfferThroughput { get; set; } = 400;
35 |
36 | ///
37 | /// Gets or sets the collection properties.
38 | ///
39 | public Dictionary CollectionProperties { get; set; } =
40 | new Dictionary();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.EfCore/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.EfCore/DocEx.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Documents;
2 |
3 | namespace APIBlox.NetCore
4 | {
5 | internal class DocEx : EventStoreDocument
6 | {
7 | public new string Data { get; set; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.EfCore/EventStoreDocumentMap.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 |
4 | namespace APIBlox.NetCore
5 | {
6 | internal class EventStoreDocumentMap
7 | {
8 | private readonly EntityTypeBuilder _builder;
9 |
10 | public EventStoreDocumentMap(EntityTypeBuilder builder)
11 | {
12 | _builder = builder;
13 | }
14 |
15 | public void Map()
16 | {
17 | _builder.ToTable("EventStoreDocuments");
18 |
19 | _builder.HasKey(p => p.Id);
20 |
21 | _builder.HasIndex(p => p.StreamId);
22 |
23 | //_builder.Ignore(p => p.Data);
24 | _builder.Property(p => p.Data);
25 |
26 | _builder.Property(p => p.DataType).HasMaxLength(1024);
27 | _builder.Property(p => p.DocumentType).HasMaxLength(255);
28 |
29 | // _builder.Property(p => p.SortOrder);
30 | _builder.Property(p => p.StreamId).IsRequired().HasMaxLength(255);
31 | _builder.Property(p => p.TimeStamp).IsRequired();
32 | _builder.Property(p => p.Version).IsRequired();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.EfCore/Migrations/EventStoreDbContextModelSnapshot.cs:
--------------------------------------------------------------------------------
1 | //
2 |
3 | using Microsoft.EntityFrameworkCore;
4 | using Microsoft.EntityFrameworkCore.Infrastructure;
5 | using Microsoft.EntityFrameworkCore.Metadata;
6 |
7 | namespace APIBlox.NetCore.Migrations
8 | {
9 | [DbContext(typeof(EventStoreDbContext))]
10 | internal class EventStoreDbContextModelSnapshot : ModelSnapshot
11 | {
12 | protected override void BuildModel(ModelBuilder modelBuilder)
13 | {
14 | #pragma warning disable 612, 618
15 | modelBuilder
16 | .HasAnnotation("ProductVersion", "2.2.0-rtm-35687")
17 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
18 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
19 |
20 | modelBuilder.Entity("APIBlox.NetCore.Documents.EventStoreDocument",
21 | b =>
22 | {
23 | b.Property("Id").ValueGeneratedOnAdd();
24 | b.Property("DataEx");
25 | b.Property("DataType").HasMaxLength(1024);
26 | b.Property("DocumentType").HasMaxLength(255);
27 | b.Property("StreamId").IsRequired().HasMaxLength(255);
28 | b.Property("TimeStamp");
29 | b.Property("Version");
30 | b.HasKey("Id");
31 | b.HasIndex("StreamId");
32 | b.ToTable("EventStoreDocuments");
33 | }
34 | );
35 | #pragma warning restore 612, 618
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.EfCore/Migrations/InitialCreate.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | using APIBlox.NetCore;
3 | using Microsoft.EntityFrameworkCore;
4 | using Microsoft.EntityFrameworkCore.Infrastructure;
5 | using Microsoft.EntityFrameworkCore.Metadata;
6 | using Microsoft.EntityFrameworkCore.Migrations;
7 |
8 | namespace APIBlox.NetCore.Migrations
9 | {
10 | [DbContext(typeof(EventStoreDbContext))]
11 | [Migration("InitialCreate")]
12 | partial class InitialCreate
13 | {
14 | protected override void BuildTargetModel(ModelBuilder modelBuilder)
15 | {
16 | #pragma warning disable 612, 618
17 | modelBuilder
18 | .HasAnnotation("ProductVersion", "2.2.0-rtm-35687")
19 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
20 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
21 |
22 | modelBuilder.Entity("APIBlox.NetCore.Documents.EventStoreDocument", b =>
23 | {
24 | b.Property("Id").ValueGeneratedOnAdd();
25 | b.Property("Data");
26 | b.Property("DataType").HasMaxLength(1024);
27 | b.Property("DocumentType").HasMaxLength(255);
28 | b.Property("StreamId").IsRequired().HasMaxLength(255);
29 | b.Property("TimeStamp");
30 | b.Property("Version");
31 | b.HasKey("Id");
32 | b.HasIndex("StreamId");
33 | b.ToTable("EventStoreDocuments");
34 | });
35 | #pragma warning restore 612, 618
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.EfCore/Migrations/InitialCreate.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore.Migrations;
2 |
3 | namespace APIBlox.NetCore.Migrations
4 | {
5 | internal partial class InitialCreate : Migration
6 | {
7 | protected override void Down(MigrationBuilder migrationBuilder)
8 | {
9 | migrationBuilder.DropTable(
10 | "EventStoreDocuments"
11 | );
12 | }
13 |
14 | protected override void Up(MigrationBuilder migrationBuilder)
15 | {
16 | migrationBuilder.CreateTable(
17 | "EventStoreDocuments",
18 | table => new
19 | {
20 | Id = table.Column(),
21 | StreamId = table.Column(maxLength: 255),
22 | DocumentType = table.Column(maxLength: 255),
23 | DataType = table.Column(maxLength: 1024, nullable: true),
24 | DataEx = table.Column(nullable: true),
25 | Version = table.Column(),
26 | TimeStamp = table.Column()
27 | },
28 | constraints: table => { table.PrimaryKey("PK_EventStoreDocuments", x => x.Id); }
29 | );
30 |
31 | migrationBuilder.CreateIndex(
32 | "IX_EventStoreDocuments_StreamId",
33 | "EventStoreDocuments",
34 | "StreamId"
35 | );
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.EfCore/Options/EfCoreSqlOptions.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Options
2 | {
3 | ///
4 | /// Class EfCoreSqlOptions.
5 | ///
6 | public class EfCoreSqlOptions
7 | {
8 | ///
9 | /// Gets or sets the CNN string.
10 | ///
11 | /// The CNN string.
12 | public string CnnString { get; set; }
13 |
14 | ///
15 | /// Gets or sets a value indicating whether [enable detailed errors].
16 | ///
17 | /// true if [enable detailed errors]; otherwise, false.
18 | public bool EnableDetailedErrors { get; set; }
19 |
20 | ///
21 | /// Gets or sets a value indicating whether [enable sensitive data logging].
22 | ///
23 | /// true if [enable sensitive data logging]; otherwise, false.
24 | public bool EnableSensitiveDataLogging { get; set; }
25 |
26 | ///
27 | /// Gets or sets a value indicating whether [configure warnings].
28 | ///
29 | /// true if [configure warnings]; otherwise, false.
30 | public bool ConfigureWarnings { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.EfCore/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "EfCoreSqlOptions": {
3 | "CnnString": "Server=.\\sql2017;Database=EventStoreEfCore;Trusted_Connection=True;",
4 | "EnableDetailedErrors": true,
5 | "EnableSensitiveDataLogging": true,
6 | "ConfigureWarnings": true
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.MongoDb/APIBlox.NetCore.EventStore.MongoDb.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 |
6 | APIBlox.NetCore
7 |
8 | MongoDB backing for APIBlox.NetCore.EventStore.
9 |
10 | APIBlox.NetCore.EventStore.MongoDb
11 |
12 | APIBlox.NetCore.EventStore.MongoDb
13 |
14 | APIBlox.NetCore.EventStore.MongoDb
15 |
16 | latest
17 |
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.MongoDb/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.MongoDb/Options/MongoDbCollectionProperties.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Options
2 | {
3 | ///
4 | /// Class MongoDbCollectionProperties.
5 | ///
6 | public class MongoDbCollectionProperties
7 | {
8 | ///
9 | /// Gets or sets the indexes.
10 | ///
11 | /// The indexes.
12 | public string[] Indexes { get; set; } = new string[0];
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.MongoDb/Options/MongoDbOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace APIBlox.NetCore.Options
4 | {
5 | ///
6 | /// Class MongoDbOptions.
7 | ///
8 | public class MongoDbOptions
9 | {
10 | ///
11 | /// Gets or sets the connection string.
12 | ///
13 | /// The connection string.
14 | public string CnnString { get; set; }
15 |
16 | ///
17 | /// Gets or sets the database identifier.
18 | ///
19 | /// The database identifier.
20 | public string DatabaseId { get; set; }
21 |
22 | ///
23 | /// Gets or sets the collection properties.
24 | ///
25 | /// The collection properties.
26 | public Dictionary CollectionProperties { get; set; } =
27 | new Dictionary();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.RavenDb/APIBlox.NetCore.EventStore.RavenDb.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 |
6 | APIBlox.NetCore
7 |
8 | RavenDb backing for APIBlox.NetCore.EventStore.
9 |
10 | APIBlox.NetCore.EventStore.RavenDb
11 |
12 | APIBlox.NetCore.EventStore.RavenDb
13 |
14 | APIBlox.NetCore.EventStore.RavenDb
15 |
16 | latest
17 |
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.RavenDb/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.RavenDb/Options/RavenDbCollectionProperties.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Options
2 | {
3 | ///
4 | /// Class RavenDbCollectionProperties.
5 | ///
6 | public class RavenDbCollectionProperties
7 | {
8 | ///
9 | /// Gets or sets the indexes.
10 | ///
11 | /// The indexes.
12 | public string[] Indexes { get; set; } = new string[0];
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore.RavenDb/Options/RavenDbOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace APIBlox.NetCore.Options
4 | {
5 | ///
6 | /// Class RavenDbOptions.
7 | ///
8 | public class RavenDbOptions
9 | {
10 | ///
11 | /// Gets or sets the database identifier.
12 | ///
13 | /// The database identifier.
14 | public string DatabaseId { get; set; }
15 |
16 | ///
17 | /// Gets or sets the collection properties.
18 | ///
19 | /// The collection properties.
20 | public Dictionary CollectionProperties { get; set; } =
21 | new Dictionary();
22 |
23 | ///
24 | /// Gets or sets the urls.
25 | ///
26 | /// The urls.
27 | public string[] Urls { get; set; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/APIBlox.NetCore.EventStore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 |
6 | APIBlox.NetCore
7 |
8 | Simple data backing agnostic event store.
9 |
10 | APIBlox.NetCore.EventStore
11 |
12 | APIBlox.NetCore.EventStore
13 |
14 | APIBlox.NetCore.EventStore
15 |
16 | latest
17 |
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Contracts/IEventStoreJsonSerializerSettings.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace APIBlox.NetCore.Contracts
7 | {
8 | ///
9 | /// Marker Interface
10 | ///
11 | public interface IEventStoreJsonSerializerSettings
12 | {
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Documents/DocumentTypes.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Documents
2 | {
3 | ///
4 | /// Enum DocumentType
5 | ///
6 | public enum DocumentType
7 | {
8 | ///
9 | /// The root
10 | ///
11 | Root = 1,
12 |
13 | ///
14 | /// The event
15 | ///
16 | Event,
17 |
18 | ///
19 | /// The snapshot
20 | ///
21 | Snapshot
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Documents/EventDocument.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Documents
2 | {
3 | internal class EventDocument : EventStoreDocument
4 | {
5 | public override string Id => $"{StreamId}-{Version}";
6 |
7 | public override DocumentType DocumentType => DocumentType.Event;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Documents/RootDocument.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Documents
2 | {
3 | internal class RootDocument : EventStoreDocument
4 | {
5 | public override string Id => StreamId;
6 |
7 | public override DocumentType DocumentType => DocumentType.Root;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Documents/SnapshotDocument.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Documents
2 | {
3 | internal class SnapshotDocument : EventStoreDocument
4 | {
5 | public override string Id => $"{StreamId}-{Version}-S";
6 |
7 | public override DocumentType DocumentType => DocumentType.Snapshot;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/EventSourcedJsonSerializerSettings.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 | using APIBlox.NetCore.Types.JsonBits;
3 | using Newtonsoft.Json;
4 | using Newtonsoft.Json.Serialization;
5 |
6 | namespace APIBlox.NetCore
7 | {
8 | internal class EventSourcedJsonSerializerSettings : JsonSerializerSettings, IEventStoreJsonSerializerSettings
9 | {
10 | public EventSourcedJsonSerializerSettings(IContractResolver contractResolver = null)
11 | {
12 | ContractResolver = contractResolver ?? new PopulateNonPublicSettersContractResolver();
13 | }
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Exceptions/EventStoreAccessException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace APIBlox.NetCore.Exceptions
4 | {
5 | ///
6 | /// Class EventStoreAccessException.
7 | /// Implements the
8 | ///
9 | public class EventStoreAccessException : Exception
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The message that describes the error.
15 | public EventStoreAccessException(string message)
16 | : base(message)
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// The error message that explains the reason for the exception.
24 | ///
25 | /// The exception that is the cause of the current exception, or a null reference (
26 | /// in Visual Basic) if no inner exception is specified.
27 | ///
28 | public EventStoreAccessException(string message, Exception innerException)
29 | : base(message, innerException)
30 | {
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Exceptions/EventStoreConcurrencyException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace APIBlox.NetCore.Exceptions
4 | {
5 | ///
6 | ///
7 | /// Class EventStoreConcurrencyException.
8 | ///
9 | ///
10 | public class EventStoreConcurrencyException : Exception
11 |
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | /// The message that describes the error.
17 | public EventStoreConcurrencyException(string message)
18 | : base(message)
19 | {
20 | }
21 |
22 | ///
23 | /// Initializes a new instance of the class.
24 | ///
25 | /// The error message that explains the reason for the exception.
26 | ///
27 | /// The exception that is the cause of the current exception, or a null reference (Nothing in
28 | /// Visual Basic) if no inner exception is specified.
29 | ///
30 | public EventStoreConcurrencyException(string message, Exception innerException)
31 | : base(message, innerException)
32 | {
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Exceptions/EventStoreNotFoundException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace APIBlox.NetCore.Exceptions
4 | {
5 | ///
6 | /// Class EventStoreNotFoundException.
7 | ///
8 | ///
9 | public class EventStoreNotFoundException : Exception
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The message that describes the error.
15 | public EventStoreNotFoundException(string message)
16 | : base(message)
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// The error message that explains the reason for the exception.
24 | ///
25 | /// The exception that is the cause of the current exception, or a null reference (Nothing in
26 | /// Visual Basic) if no inner exception is specified.
27 | ///
28 | public EventStoreNotFoundException(string message, Exception innerException)
29 | : base(message, innerException)
30 | {
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Models/EventModel.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Models
2 | {
3 | ///
4 | /// Class EventModel.
5 | ///
6 | public class EventModel
7 | {
8 | ///
9 | /// Gets or sets the data.
10 | ///
11 | /// The data.
12 | public object Data { get; set; }
13 |
14 | ///
15 | /// Gets or sets the type of the data.
16 | ///
17 | /// The type of the data.
18 | public string DataType { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Models/EventStreamModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace APIBlox.NetCore.Models
4 | {
5 | ///
6 | /// Class EventStreamModel.
7 | ///
8 | public class EventStreamModel
9 | {
10 | ///
11 | /// Gets or sets the events.
12 | ///
13 | /// The events.
14 | public EventModel[] Events { get; set; }
15 |
16 | ///
17 | /// Gets or sets the snapshot.
18 | ///
19 | /// The snapshot.
20 | public SnapshotModel Snapshot { get; set; }
21 |
22 | ///
23 | /// Gets or sets the stream identifier.
24 | ///
25 | /// The stream identifier.
26 | public string StreamId { get; set; }
27 |
28 | ///
29 | /// Gets or sets the version.
30 | ///
31 | /// The version.
32 | public long Version { get; set; }
33 |
34 | ///
35 | /// Gets or sets the time stamp.
36 | ///
37 | /// The time stamp.
38 | public DateTimeOffset TimeStamp { get; set; }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/APIBlox.NetCore.EventStore/Models/SnapshotModel.cs:
--------------------------------------------------------------------------------
1 | namespace APIBlox.NetCore.Models
2 | {
3 | ///
4 | /// Class SnapshotModel.
5 | ///
6 | public class SnapshotModel
7 | {
8 | ///
9 | /// Gets or sets the data.
10 | ///
11 | /// The data.
12 | public object Data { get; set; }
13 |
14 | ///
15 | /// Gets or sets the type of the data.
16 | ///
17 | /// The type of the data.
18 | public string DataType { get; set; }
19 |
20 | ///
21 | /// Gets or sets the version.
22 | ///
23 | /// The version.
24 | public long Version { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/APIBlox.NetCore/APIBlox.NetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.NetCore
8 |
9 | .NetCore bits.
10 |
11 | APIBlox.NetCore
12 |
13 | APIBlox.NetCore
14 |
15 | APIBlox.NetCore
16 |
17 | latest
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | all
33 | runtime; build; native; contentfiles; analyzers
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/APIBlox.NetCore/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Sln Tests")]
4 | [assembly: InternalsVisibleTo("SlnTests")]
5 | [assembly:
6 | InternalsVisibleTo(
7 | "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"
8 | )]
9 |
--------------------------------------------------------------------------------
/APIBlox.NetCore/Attributes/InjectableServiceAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Extensions.DependencyInjection;
3 |
4 | namespace APIBlox.NetCore.Attributes
5 | {
6 | ///
7 | /// Attribute that should be applied to any and all services that are dependencies.
8 | ///
9 | /// Service LifeTime defaults to
10 | ///
11 | ///
12 | ///
13 | ///
14 | [AttributeUsage(AttributeTargets.Class)]
15 | public class InjectableServiceAttribute : Attribute
16 | {
17 | ///
18 | /// Gets or sets the service lifetime. Defaults to
19 | ///
20 | ///
21 | public ServiceLifetime ServiceLifetime { get; set; } = ServiceLifetime.Scoped;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/APIBlox.NetCore/Contracts/IDependencyInvertedConfiguration.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Attributes;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace APIBlox.NetCore.Contracts
7 | {
8 | ///
9 | /// Interface IDependencyInvertedConfiguration for assemblies that contain services that follow the
10 | /// Dependency Inversion Principal, and do not or can not be created
11 | /// solely using the
12 | ///
13 | ///
14 | /// Dependency Inversion Principal:
15 | /// ...Implementations depend on abstractions, not vice versa... IE: application layer
16 | /// holds the contract (abstraction) but persistence layer has the implementation, therefore
17 | /// the application layer would NEVER have a reference to the persistence assembly, using DIP, the
18 | /// flow however would appear that the application layer DOES have a reference to the persistence assembly.
19 | ///
20 | public interface IDependencyInvertedConfiguration
21 | {
22 | ///
23 | /// Configures services
24 | ///
25 | /// The services.
26 | /// The configuration.
27 | /// The logger factory.
28 | /// The environment.
29 | ///
30 | void Configure(
31 | IServiceCollection services, IConfiguration configuration,
32 | ILoggerFactory loggerFactory, string environment
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/APIBlox.NetCore/Extensions/Options/ConfigureOptionsWithDependency.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | // ReSharper disable once CheckNamespace
4 | namespace Microsoft.Extensions.Options
5 | {
6 | ///
7 | /// Class ConfigureOptionsWithDependency.
8 | ///
9 | /// The type of the t options.
10 | /// The type of the t dependent.
11 | ///
12 | public class ConfigureOptionsWithDependency
13 | {
14 | ///
15 | /// Gets or sets the action.
16 | ///
17 | /// The action.
18 | ///
19 | public Action Action { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ApiBlox.AspNetCore.DynamicControllers/APIBlox.AspNetCore.DynamicControllers.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.AspNetCore
8 |
9 | Simple dynamic controllers package that puts the focus on resources.
10 |
11 | APIBlox.AspNetCore.DynamicControllers
12 |
13 | APIBlox.AspNetCore.DynamicControllers
14 |
15 | APIBlox.AspNetCore.DynamicControllers
16 |
17 | latest
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | all
40 | runtime; build; native; contentfiles; analyzers
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/ApiBlox.AspNetCore/APIBlox.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.AspNetCore
8 |
9 | AspNetCore bits.
10 |
11 | APIBlox.AspNetCore
12 |
13 | APIBlox.AspNetCore
14 |
15 | APIBlox.AspNetCore
16 |
17 | latest
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | all
36 | runtime; build; native; contentfiles; analyzers
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ApiBlox.NetCore.Common/APIBlox.NetCore.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.NetCore
8 |
9 | Cross-Cutting.NetCore bits.
10 |
11 | APIBlox.NetCore.Common
12 |
13 | APIBlox.NetCore.Common
14 |
15 | APIBlox.NetCore.Common
16 |
17 | latest
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/ApiBlox.NetCore/APIBlox.NetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 |
7 | APIBlox.NetCore
8 |
9 | .NetCore bits.
10 |
11 | APIBlox.NetCore
12 |
13 | APIBlox.NetCore
14 |
15 | APIBlox.NetCore
16 |
17 | latest
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | all
33 | runtime; build; native; contentfiles; analyzers
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | Slacquer
4 | Slacquers Building Blox
5 | false
6 | true
7 | true
8 | true
9 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
10 | https://github.com/Slacquer/api-blox/blob/master/logo-blue-small.png?raw=true
11 | Public Production Release
12 | https://github.com/Slacquer/api-blox
13 | true
14 |
15 | GPL-3.0-or-later
16 |
17 | 0.0.0
18 | dynamic-controllers;controller;netcore2;api-rest;cqrs;aspnetcore;asp-net-core;dependency-injection;inversion-of-control;ioc;ioc-container;event-sourcing;cqrs
19 | https://github.com/Slacquer/api-blox
20 | Slacquers Building Blox
21 | 0.0.0.0
22 | 0.0.0.0
23 | GIT
24 |
25 |
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/Configuration/SwaggerConfig.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.OpenApi.Models;
3 | using Swashbuckle.AspNetCore.Swagger;
4 |
5 | // ReSharper disable once CheckNamespace
6 | namespace Microsoft.Extensions.DependencyInjection
7 | {
8 | internal static class SwaggerConfig
9 | {
10 | public static IServiceCollection AddSwaggerExampleFeatures(this IServiceCollection services, string siteTitle, string version)
11 | {
12 | return services.AddSwaggerGen(c =>
13 | {
14 | c.SwaggerDoc(version,
15 | new OpenApiInfo
16 | {
17 | Title = siteTitle,
18 | Version = version
19 | }
20 | );
21 | c.IncludeXmlComments(@".\Examples.Features.xml", true);
22 | }
23 | );
24 | }
25 |
26 | public static IApplicationBuilder UseSwaggerExampleFeatures(this IApplicationBuilder app, string siteTitle, string version)
27 | {
28 | return app.UseSwagger()
29 | .UseSwaggerUI(s =>
30 | s.SwaggerEndpoint($"/swagger/{version}/swagger.json",
31 | $"{siteTitle} {version}"
32 | )
33 | );
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/Contracts/IRandomNumberGeneratorService.cs:
--------------------------------------------------------------------------------
1 | namespace Examples.Contracts
2 | {
3 | ///
4 | /// Interface IRandomNumberGeneratorService
5 | ///
6 | public interface IRandomNumberGeneratorService
7 | {
8 | ///
9 | /// Generates the number.
10 | ///
11 | /// System.Int32.
12 | int GenerateNumber(int max);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace Examples
7 | {
8 | internal class Program
9 | {
10 | public static void Main(string[] args)
11 | {
12 | StartupLogger = LoggerFactory.Create(a => a.AddConsole());
13 |
14 | CreateHostBuilder(args).Build().Run();
15 | }
16 |
17 | public static ILoggerFactory StartupLogger { get; private set; }
18 |
19 | private static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:52094",
7 | "sslPort": 44365
8 | }
9 | },
10 | "$schema": "http://json.schemastore.org/launchsettings.json",
11 | "profiles": {
12 | "Examples.Features": {
13 | "commandName": "Project",
14 | "launchUrl": "swagger",
15 | "environmentVariables": {
16 | "ASPNETCORE_ENVIRONMENT": "Development"
17 | },
18 | "applicationUrl": "http://localhost:5000"
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/Resources/ExampleRequestObject.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace Examples.Resources
4 | {
5 | ///
6 | /// Class ExampleRequestObject.
7 | ///
8 | public class ExampleRequestObject
9 | {
10 | ///
11 | /// Gets the parent value id.
12 | ///
13 | /// The action filter will populate private properties from query and route params.
14 | ///
15 | ///
16 | /// The parent value id.
17 | public int ValueId { get; private set; } // We can either do this or add FromRoute/FromQuery explicitly.
18 |
19 | ///
20 | /// Gets or sets the cool new value. I am required, so if
21 | /// you omit me, then the APIBlox ValidateResourceActionFilter will kick in resulting in an 400.
22 | ///
23 | /// The cool new value.
24 | [Required]
25 | public string CoolNewValue { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/Services/RandomNumberGeneratorService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using APIBlox.NetCore.Attributes;
3 | using Examples.Contracts;
4 | using Microsoft.Extensions.DependencyInjection;
5 |
6 | namespace Examples.Services
7 | {
8 | ///
9 | /// Class RandomNumberGeneratorService.
10 | ///
11 | ///
12 | [InjectableService(ServiceLifetime = ServiceLifetime.Singleton)]
13 | public class RandomNumberGeneratorService : IRandomNumberGeneratorService
14 | {
15 | private static readonly Random Rnd = new((int) (DateTime.Now.Ticks % 100));
16 |
17 | ///
18 | /// Generates the number.
19 | ///
20 | /// System.Int32.
21 | public int GenerateNumber(int max)
22 | {
23 | return Rnd.Next(1, max);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | },
9 | "ExampleTokens": {
10 | "Version": "1",
11 | "environment": "Dev"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/appsettings.Production.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | },
9 | "ExampleTokens": {
10 | "Version": "1",
11 | "environment": "Dev"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Examples/APIBlox Features/Examples.Features/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Commands/SimplePostCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.AspNetCore.Types;
4 | using APIBlox.NetCore.Attributes;
5 | using APIBlox.NetCore.Contracts;
6 | using Examples.Resources;
7 |
8 | namespace Examples.Commands
9 | {
10 | [InjectableService]
11 | internal class SimplePostCommand : ICommandHandler
12 | {
13 | public Task HandleAsync(ExampleRequestObject requestCommand, CancellationToken cancellationToken)
14 | {
15 | // This implementation does NOT return anything (other than the task object obviously).
16 |
17 | var res = new HandlerResponse().SetErrorTo400BadRequest("Some Big Fat Error!");
18 | res.Result = requestCommand.SomeValue;
19 |
20 | return Task.FromResult(res);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Commands/SimplePostCommandDecorator.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.AspNetCore.Types;
4 | using APIBlox.NetCore.Contracts;
5 | using Examples.Resources;
6 |
7 | namespace Examples.Commands
8 | {
9 | // Not needed as we must explicitly wrap decorators.
10 | //[InjectableService]
11 | internal class SimplePostCommandDecorator : ICommandHandler
12 | {
13 | private readonly ICommandHandler _thingWeAreDecorating;
14 |
15 | public SimplePostCommandDecorator(ICommandHandler thingWeAreDecorating)
16 | {
17 | _thingWeAreDecorating = thingWeAreDecorating;
18 | }
19 |
20 | public async Task HandleAsync(ExampleRequestObject requestCommand, CancellationToken cancellationToken)
21 | {
22 | // Do some kind of test or perhaps domain validation, prior to letting the actual command handler deal with it.
23 | // If validation failed, we could short circuit the process by NOT calling the decorated handler.
24 | var ret = await _thingWeAreDecorating.HandleAsync(requestCommand, cancellationToken);
25 |
26 | // Do something after the handler has dealt with it.
27 |
28 | return ret;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Configuration/DecoratorsConfig.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Decorators.Commands;
2 | using APIBlox.NetCore.Extensions;
3 | using Examples.Commands;
4 | using Microsoft.Extensions.Logging;
5 |
6 | // ReSharper disable once CheckNamespace
7 | namespace Microsoft.Extensions.DependencyInjection
8 | {
9 | internal static class DecoratorsConfig
10 | {
11 | public static IServiceCollection AddCqrsDecorators(this IServiceCollection services, ILoggerFactory loggerFactory)
12 | {
13 | services.AddCommandHandlerDecoration(loggerFactory,
14 |
15 | //
16 | // Nothing more than a stopwatch. Ideally (my opinion) an API
17 | // call should never take more than 3 seconds.
18 | typeof(MetricsCommandHandlerDecorator<,>),
19 |
20 | //
21 | // This one is still a work in progress and is most likely
22 | // more valuable when combined with domain events.
23 | typeof(TransactionScopeCommandHandlerDecorator<,>),
24 | typeof(SimplePostCommandDecorator)
25 | );
26 |
27 | return services;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Configuration/SwaggerConfig.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.OpenApi.Models;
3 | using Swashbuckle.AspNetCore.Swagger;
4 |
5 | // ReSharper disable once CheckNamespace
6 | namespace Microsoft.Extensions.DependencyInjection
7 | {
8 | internal static class SwaggerConfig
9 | {
10 | public static IServiceCollection AddSwaggerExampleFeatures(this IServiceCollection services, string siteTitle, string version)
11 | {
12 | return services.AddSwaggerGen(c =>
13 | {
14 | c.SwaggerDoc(version,
15 | new OpenApiInfo
16 | {
17 | Title = siteTitle,
18 | Version = version
19 | }
20 | );
21 | c.IncludeXmlComments(@".\Examples.Cqrs.xml", true);
22 | }
23 | );
24 | }
25 |
26 | public static IApplicationBuilder UseSwaggerExampleFeatures(this IApplicationBuilder app, string siteTitle, string version)
27 | {
28 | return app.UseSwagger()
29 | .UseSwaggerUI(s =>
30 | s.SwaggerEndpoint($"/swagger/{version}/swagger.json",
31 | $"{siteTitle} {version}"
32 | )
33 | );
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Examples.Cqrs.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | Examples
6 | latest
7 |
8 | .\Examples.Cqrs.xml
9 |
10 |
11 |
12 |
13 | TRACE;UseAPIBlox
14 |
15 |
16 |
17 | TRACE;UseAPIBlox1
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace Examples
7 | {
8 | internal class Program
9 | {
10 | public static void Main(string[] args)
11 | {
12 | StartupLogger = LoggerFactory.Create(a => a.AddConsole());
13 |
14 | CreateHostBuilder(args).Build().Run();
15 | }
16 |
17 | public static ILoggerFactory StartupLogger { get; private set; }
18 |
19 | private static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:51384",
7 | "sslPort": 44338
8 | }
9 | },
10 | "$schema": "http://json.schemastore.org/launchsettings.json",
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchBrowser": true,
15 | "launchUrl": "api/values",
16 | "environmentVariables": {
17 | "ASPNETCORE_ENVIRONMENT": "Development"
18 | }
19 | },
20 | "Examples.Cqrs": {
21 | "commandName": "Project",
22 | "launchUrl": "swagger",
23 | "environmentVariables": {
24 | "ASPNETCORE_ENVIRONMENT": "Development"
25 | },
26 | "applicationUrl": "https://localhost:5001;http://localhost:5000"
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Queries/NoInputsQueryHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using APIBlox.NetCore.Attributes;
5 | using APIBlox.NetCore.Contracts;
6 |
7 | namespace Examples.Queries
8 | {
9 | [InjectableService]
10 | internal class NoInputsQueryHandler : IQueryHandler>
11 | {
12 | public Task> HandleAsync(CancellationToken cancellationToken)
13 | {
14 | var lst = new List {"a", "b", "c"};
15 |
16 | return Task.FromResult>(lst);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Queries/RequiresInputQueryQueryHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.NetCore.Attributes;
4 | using APIBlox.NetCore.Contracts;
5 |
6 | namespace Examples.Queries
7 | {
8 | [InjectableService]
9 | internal class RequiresInputQueryQueryHandler : IQueryHandler
10 | {
11 | public Task HandleAsync(int query, CancellationToken cancellationToken)
12 | {
13 | return Task.FromResult(query * 100);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/Resources/ExampleRequestObject.cs:
--------------------------------------------------------------------------------
1 | namespace Examples.Resources
2 | {
3 | ///
4 | /// Class ExampleRequestObject.
5 | ///
6 | public class ExampleRequestObject
7 | {
8 | ///
9 | /// Gets or sets some value.
10 | ///
11 | /// Some value.
12 | public int SomeValue { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/Examples/CQRS/Examples.Cqrs/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/Configuration/SwaggerConfig.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.OpenApi.Models;
3 |
4 | // ReSharper disable once CheckNamespace
5 | namespace Microsoft.Extensions.DependencyInjection
6 | {
7 | internal static class SwaggerConfig
8 | {
9 | public static IServiceCollection AddSwaggerExampleFeatures(this IServiceCollection services, string siteTitle, string version)
10 | {
11 | return services.AddSwaggerGen(c =>
12 | {
13 | c.SwaggerDoc(version,
14 | new OpenApiInfo
15 | {
16 | Title = siteTitle,
17 | Version = version
18 | }
19 | );
20 | c.IncludeXmlComments(@".\Examples.DomainEvents.xml", true);
21 | }
22 | );
23 | }
24 |
25 | public static IApplicationBuilder UseSwaggerExampleFeatures(this IApplicationBuilder app, string siteTitle, string version)
26 | {
27 | return app.UseSwagger()
28 | .UseSwaggerUI(s =>
29 | s.SwaggerEndpoint($"/swagger/{version}/swagger.json",
30 | $"{siteTitle} {version}"
31 | )
32 | );
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/Contracts/ILameRepository.cs:
--------------------------------------------------------------------------------
1 | using Examples.DomainModels;
2 |
3 | namespace Examples.Contracts
4 | {
5 | ///
6 | /// Interface ILameRepository
7 | ///
8 | public interface ILameRepository
9 | {
10 | ///
11 | /// Adds the domain object.
12 | ///
13 | /// The domain object.
14 | void AddDomainObject(DomainObject domainObject);
15 |
16 | ///
17 | /// Saves the changes.
18 | ///
19 | void SaveChanges();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/EventBits/RequestObjectCreatedEvent.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 |
3 | namespace Examples.EventBits
4 | {
5 | ///
6 | /// Class RequestObjectCreatedEvent.
7 | ///
8 | ///
9 | public class RequestObjectCreatedEvent : IDomainEvent
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The value that was created.
15 | ///
16 | /// Some other domain specific event value needed for consumption.
17 | ///
18 | public RequestObjectCreatedEvent(int theValueThatWasCreated, string someOtherDomainSpecificEventValueNeededForConsumption)
19 | {
20 | TheValueThatWasCreated = theValueThatWasCreated;
21 | SomeOtherDomainSpecificEventValueNeededForConsumption = someOtherDomainSpecificEventValueNeededForConsumption;
22 | }
23 |
24 | ///
25 | /// Gets the value that was created.
26 | ///
27 | /// The value that was created.
28 | public int TheValueThatWasCreated { get; }
29 |
30 | ///
31 | /// Gets some other domain specific event value needed for consumption.
32 | ///
33 | public string SomeOtherDomainSpecificEventValueNeededForConsumption { get; }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/EventBits/RequestObjectCreatedEventHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.NetCore.Attributes;
4 | using APIBlox.NetCore.Contracts;
5 | using Microsoft.Extensions.Logging;
6 |
7 | namespace Examples.EventBits
8 | {
9 | [InjectableService]
10 | internal class RequestObjectCreatedEventHandler : IDomainEventHandler
11 | {
12 | private readonly ILogger _log;
13 |
14 | public RequestObjectCreatedEventHandler(ILoggerFactory loggerFactory)
15 | {
16 | _log = loggerFactory.CreateLogger();
17 | }
18 |
19 | public Task HandleEventAsync(RequestObjectCreatedEvent domainEvent, CancellationToken cancellationToken = default)
20 | {
21 | _log.LogInformation(() =>
22 | "------------------\n\nHandling created event. Its special value " +
23 | $"is {domainEvent.SomeOtherDomainSpecificEventValueNeededForConsumption}, the " +
24 | $"value that was used during request was {domainEvent.TheValueThatWasCreated}\n\n-------------\n\n"
25 | );
26 |
27 | // Not actually doing anything outside of a log entry.
28 | // Just imagine I am part of a different aggregate root.
29 |
30 | return Task.CompletedTask;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/Examples.DomainEvents.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | Examples
6 | latest
7 |
8 | .\Examples.DomainEvents.xml
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/Examples.DomainEvents.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/InfrastructureAndDomainBits/DomainModels/DomainObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using APIBlox.NetCore.Contracts;
5 | using Examples.EventBits;
6 |
7 | namespace Examples.DomainModels
8 | {
9 | ///
10 | /// Class DomainObject.
11 | ///
12 | public class DomainObject
13 | {
14 | private readonly List _domainEvents = new();
15 |
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// Some value to save.
20 | public DomainObject(int someValueToSave)
21 | {
22 | SomeValueToSave = someValueToSave;
23 |
24 | _domainEvents.Add(new RequestObjectCreatedEvent(someValueToSave, DateTime.Now.ToLongTimeString()));
25 | }
26 |
27 | ///
28 | /// Gets some value to save.
29 | ///
30 | /// Some value to save.
31 | public int SomeValueToSave { get; }
32 |
33 | ///
34 | /// Gets or sets the identifier.
35 | ///
36 | /// The identifier.
37 | public int Id { get; set; }
38 |
39 | ///
40 | /// Gets the events.
41 | ///
42 | /// The events.
43 | public IEnumerable Events => _domainEvents.ToList();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/InfrastructureAndDomainBits/LameRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using APIBlox.NetCore.Attributes;
3 | using APIBlox.NetCore.Contracts;
4 | using Examples.Contracts;
5 | using Examples.DomainModels;
6 |
7 | namespace Examples
8 | {
9 | [InjectableService]
10 | internal class LameRepository : ILameRepository
11 | {
12 | private static readonly Dictionary Models = new();
13 | private readonly IDomainEventsDispatcher _dispatcher;
14 |
15 | public LameRepository(IDomainEventsDispatcher dispatcher)
16 | {
17 | _dispatcher = dispatcher;
18 | }
19 |
20 | public void AddDomainObject(DomainObject domainObject)
21 | {
22 | if (Models.ContainsKey(domainObject.Id))
23 | Models.Remove(domainObject.Id);
24 |
25 | Models.Add(domainObject.Id, domainObject);
26 | }
27 |
28 | public void SaveChanges()
29 | {
30 | var lst = new List();
31 |
32 | foreach (var obj in Models.Values)
33 | lst.AddRange(obj.Events);
34 |
35 | _dispatcher.PublishEventsAsync(lst.ToArray());
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace Examples
7 | {
8 | internal class Program
9 | {
10 |
11 | public static void Main(string[] args)
12 | {
13 | StartupLogger = LoggerFactory.Create(a => a.AddConsole());
14 |
15 | CreateHostBuilder(args).Build().Run();
16 | }
17 |
18 | public static ILoggerFactory StartupLogger { get; private set; }
19 |
20 | private static IHostBuilder CreateHostBuilder(string[] args) =>
21 | Host.CreateDefaultBuilder(args)
22 | .ConfigureWebHostDefaults(webBuilder =>
23 | {
24 | webBuilder.UseStartup();
25 | });
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:52705",
7 | "sslPort": 0
8 | }
9 | },
10 | "$schema": "http://json.schemastore.org/launchsettings.json",
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchUrl": "swagger",
15 | "environmentVariables": {
16 | "ASPNETCORE_ENVIRONMENT": "Development"
17 | }
18 | },
19 | "Examples.DomainEvents": {
20 | "commandName": "Project",
21 | "launchUrl": "swagger",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | },
25 | "applicationUrl": "http://localhost:5000"
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/Resources/ExampleRequestObject.cs:
--------------------------------------------------------------------------------
1 | namespace Examples.Resources
2 | {
3 | ///
4 | /// Class ExampleRequestObject.
5 | ///
6 | public class ExampleRequestObject
7 | {
8 | ///
9 | /// Gets or sets some value.
10 | ///
11 | /// Some value.
12 | public int SomeValue { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/Examples/Domain Events/Examples.DomainEvents/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/CmdQueryHandlers/ChildByIdRequestCommandHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.AspNetCore.Types;
4 | using APIBlox.NetCore.Attributes;
5 | using APIBlox.NetCore.Contracts;
6 | using Examples.Resources;
7 |
8 | namespace Examples.CmdQueryHandlers
9 | {
10 | [InjectableService]
11 | internal class ChildByIdRequestCommandHandler : ICommandHandler
12 | {
13 | public Task HandleAsync(ChildByIdRequest requestCommand, CancellationToken cancellationToken)
14 | {
15 | var ret = new HandlerResponse
16 | {
17 | Result = new ChildResponse {Age = 4}
18 | };
19 |
20 | return Task.FromResult(ret);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/CmdQueryHandlers/ChildByIdRequestHandlers.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections.ObjectModel;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using APIBlox.AspNetCore.Types;
6 | using APIBlox.NetCore.Attributes;
7 | using APIBlox.NetCore.Contracts;
8 | using Examples.Resources;
9 |
10 | namespace Examples.CmdQueryHandlers
11 | {
12 | [InjectableService]
13 | internal class ChildByIdRequestHandlers :
14 | IQueryHandler
15 | {
16 | public Task HandleAsync(ChildByIdRequest query, CancellationToken cancellationToken)
17 | {
18 | var ret = new HandlerResponse
19 | {
20 | Result = new List
21 | {
22 | new()
23 | {
24 | Age = 5,
25 | FirstName = "Sebastian",
26 | Id = 1,
27 | LastName = "Booth",
28 | Parents = new Collection
29 | {
30 | new()
31 | {
32 | Age = 29,
33 | LastName = "Booth",
34 | FirstName = "Britani"
35 | }
36 | }
37 | }
38 | }
39 | };
40 |
41 | //ret.CreateError().SetErrorToBadRequest("OMG!");
42 |
43 | return Task.FromResult(ret);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/CmdQueryHandlers/ChildPatchRequestCommandHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.AspNetCore.Types;
4 | using APIBlox.NetCore.Attributes;
5 | using APIBlox.NetCore.Contracts;
6 | using Examples.Resources;
7 |
8 | namespace Examples.CmdQueryHandlers
9 | {
10 | [InjectableService]
11 | internal class ChildPatchRequestCommandHandler : ICommandHandler
12 | {
13 | public Task HandleAsync(ChildPatchRequest requestCommand, CancellationToken cancellationToken)
14 | {
15 | var ret = new HandlerResponse();
16 |
17 | return Task.FromResult(ret);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/CmdQueryHandlers/ChildPostRequestCommandHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.AspNetCore.Types;
4 | using APIBlox.NetCore.Attributes;
5 | using APIBlox.NetCore.Contracts;
6 | using Examples.Resources;
7 |
8 | namespace Examples.CmdQueryHandlers
9 | {
10 | [InjectableService]
11 | internal class ChildPostRequestCommandHandler : ICommandHandler
12 | {
13 | public Task HandleAsync(ChildPostRequest requestCommand, CancellationToken cancellationToken)
14 | {
15 | var ret = new HandlerResponse();
16 |
17 | // if we don't return something the controller will complain. It will also complain if
18 | // it can not find a property that ends with "id", as it can't create a CreatedAtRoute.
19 |
20 | ret.Result = new {id = 1, Foo = "barrrr"};
21 |
22 | return Task.FromResult(ret);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/CmdQueryHandlers/ChildPutRequestCommandHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using APIBlox.AspNetCore.Types;
4 | using APIBlox.NetCore.Attributes;
5 | using APIBlox.NetCore.Contracts;
6 | using Examples.Resources;
7 |
8 | namespace Examples.CmdQueryHandlers
9 | {
10 | [InjectableService]
11 | internal class ChildPutRequestCommandHandler : ICommandHandler
12 | {
13 | public Task HandleAsync(ChildPutRequest requestCommand, CancellationToken cancellationToken)
14 | {
15 | var ret = new HandlerResponse();
16 |
17 | return Task.FromResult(ret);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/CmdQueryHandlers/ChildrenRequestQueryHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using APIBlox.AspNetCore.Types;
5 | using APIBlox.NetCore.Attributes;
6 | using APIBlox.NetCore.Contracts;
7 | using Examples.Resources;
8 |
9 | namespace Examples.CmdQueryHandlers
10 | {
11 | [InjectableService]
12 | internal class ChildrenRequestQueryHandler : IQueryHandler
13 | {
14 | public Task HandleAsync(ChildrenRequest query, CancellationToken cancellationToken)
15 | {
16 | var ret = new HandlerResponse ();
17 |
18 | // if we do not return something then the controller will get mad at us!
19 | var kids = new List();
20 |
21 | for (var i = 0; i < 10; i++)
22 | kids.Add(new ChildResponse { Age = i });
23 |
24 | ret.Result = kids;
25 |
26 | return Task.FromResult(ret);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Configuration/SwaggerConfig.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Extensions;
2 | //using MicroElements.Swashbuckle.FluentValidation;
3 | using Microsoft.AspNetCore.Builder;
4 | using Microsoft.OpenApi.Models;
5 |
6 | // ReSharper disable once CheckNamespace
7 | namespace Microsoft.Extensions.DependencyInjection
8 | {
9 | internal static class SwaggerConfig
10 | {
11 | public static IServiceCollection AddSwaggerExampleFeatures(this IServiceCollection services, string siteTitle, string version,
12 | string dynamicControllersXmlFile
13 | )
14 | {
15 | return services.AddSwaggerGen(c =>
16 | {
17 | c.SwaggerDoc(version,
18 | new OpenApiInfo
19 | {
20 | Title = siteTitle,
21 | Version = version
22 | }
23 | );
24 | c.IncludeXmlComments(@".\Examples.DynamicControllers.xml", true);
25 |
26 | if (!dynamicControllersXmlFile.IsEmptyNullOrWhiteSpace())
27 | c.IncludeXmlComments(dynamicControllersXmlFile, true);
28 |
29 | //c.AddFluentValidationRules();
30 | //c.SchemaFilter();
31 | //c.OperationFilter();
32 | }
33 | );
34 | }
35 |
36 | public static IApplicationBuilder UseSwaggerExampleFeatures(this IApplicationBuilder app, string siteTitle, string version)
37 | {
38 | return app.UseSwagger()
39 | .UseSwaggerUI(s =>
40 | s.SwaggerEndpoint($"/swagger/{version}/swagger.json",
41 | $"{siteTitle} {version}"
42 | )
43 | );
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Contracts/IChildRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Examples.Contracts
2 | {
3 | internal interface IChildRequest
4 | {
5 | bool LikesCandy { get; }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Contracts/IRandomNumberGeneratorService.cs:
--------------------------------------------------------------------------------
1 | namespace Examples.Contracts
2 | {
3 | ///
4 | /// Interface IRandomNumberGeneratorService
5 | ///
6 | public interface IRandomNumberGeneratorService
7 | {
8 | ///
9 | /// Generates the number.
10 | ///
11 | /// System.Int32.
12 | int GenerateNumber(int max);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Examples.DynamicControllers.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | Examples
6 | latest
7 |
8 | .\Examples.DynamicControllers.xml
9 |
10 |
11 |
12 | TRACE;UseAPIBlox
13 |
14 |
15 |
16 | TRACE;UseAPIBlox1
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace Examples
7 | {
8 | internal class Program
9 | {
10 | public static void Main(string[] args)
11 | {
12 | StartupLogger = LoggerFactory.Create(a => a.AddConsole());
13 |
14 | CreateHostBuilder(args).Build().Run();
15 | }
16 |
17 | public static ILoggerFactory StartupLogger { get; private set; }
18 |
19 | private static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:52094",
7 | "sslPort": 44365
8 | }
9 | },
10 | "$schema": "http://json.schemastore.org/launchsettings.json",
11 | "profiles": {
12 | "Examples.Features": {
13 | "commandName": "Project",
14 | "launchUrl": "swagger",
15 | "environmentVariables": {
16 | "ASPNETCORE_ENVIRONMENT": "Development"
17 | },
18 | "applicationUrl": "http://localhost:5000"
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/AllRequest.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace Examples.Resources
5 | {
6 | ///
7 | /// Class AllRequest.
8 | ///
9 | public class AllRequest
10 | {
11 | ///
12 | /// The required value, and it must be three characters. please check out http://www.kids.com for more info.
13 | ///
14 | /// The required value must be three characters.
15 | [FromQuery]
16 | [Required]
17 | [StringLength(3, MinimumLength = 3, ErrorMessage = "Value must be exactly 3 characters long.")]
18 | public string RequiredValueMustBeThreeCharacters { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ByIdRequest.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace Examples.Resources
4 | {
5 | ///
6 | ///
7 | /// ByIdRequest.
8 | ///
9 | public class ByIdRequest : AllRequest
10 | {
11 | ///
12 | /// Gets or sets some identifier.
13 | ///
14 | /// Some identifier.
15 | [FromRoute(Name = "someId")]
16 | public int Id { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ChildByIdRequest.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace Examples.Resources
4 | {
5 | ///
6 | /// This comment came from the first request object as part of the first
7 | /// action that was added to this controller. The request object is the type ChildByIdRequest.
8 | ///
9 | public class ChildByIdRequest
10 | {
11 | ///
12 | /// Sets the child id.
13 | ///
14 | [FromRoute(Name = "childId")]
15 | public int Id { get; set; }
16 |
17 | ///
18 | /// Gets or sets the parent identifier.
19 | ///
20 | /// The parent identifier.
21 | [FromRoute]
22 | public int ParentId { get; set; }
23 |
24 | ///
25 | /// Gets or sets a value indicating whether this is help.
26 | ///
27 | /// null if [help] contains no value, true if [help]; otherwise, false.
28 | [FromQuery]
29 | public bool? Help { get; set; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ChildPatchRequest.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 | using Microsoft.AspNetCore.JsonPatch;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Examples.Resources
6 | {
7 | ///
8 | /// Class ChildPutRequest.
9 | ///
10 | public class ChildPatchRequest : ChildByIdRequest
11 | {
12 | ///
13 | /// Gets or sets an query value we want.
14 | ///
15 | /// An query value we want.
16 | [FromQuery]
17 | [Required]
18 | public int AQueryValueWeWant { get; set; }
19 |
20 | ///
21 | /// Sets the body (patch document).
22 | ///
23 | /// The body.
24 | [FromBody]
25 | public JsonPatchDocument Body { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ChildPostRequest.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace Examples.Resources
4 | {
5 | ///
6 | /// Class ChildPostRequest.
7 | ///
8 | public class ChildPostRequest
9 | {
10 | ///
11 | /// Gets or sets the parent identifier.
12 | ///
13 | /// The parent identifier.
14 | [FromRoute(Name = "parentId")]
15 | public int ParentId { get; set; }
16 |
17 | ///
18 | /// Gets or sets the body.
19 | ///
20 | /// The body.
21 | [FromBody]
22 | public PersonModel Child { get; set; }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ChildPutRequest.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace Examples.Resources
4 | {
5 | ///
6 | /// Class ChildPutRequest.
7 | ///
8 | public class ChildPutRequest : ChildByIdRequest
9 | {
10 | ///
11 | /// Gets or sets an query value we want.
12 | ///
13 | /// An query value we want.
14 | [FromQuery]
15 | public int? AnQueryValueWeWant { get; set; }
16 |
17 | ///
18 | /// Gets or sets the body.
19 | ///
20 | /// The body.
21 | [FromBody]
22 | public PersonModel Body { get; set; }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ChildRequest.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Types;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace Examples.Resources
5 | {
6 | ///
7 | /// Class ChildRequest.
8 | ///
9 | ///
10 | ///
11 | public class ChildrenRequest : FilteredQuery
12 | {
13 | ///
14 | /// Gets or sets the parent identifier.
15 | ///
16 | /// The parent identifier.
17 | [FromRoute]
18 | public int ParentId { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ChildResponse.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using APIBlox.AspNetCore.Contracts;
3 |
4 | namespace Examples.Resources
5 | {
6 | ///
7 | /// Class ChildResponse.
8 | ///
9 | public class ChildResponse : IResource
10 | {
11 | ///
12 | /// Gets or sets the age.
13 | ///
14 | /// The age.
15 | public int Age { get; set; }
16 |
17 | ///
18 | /// Gets or sets the first name.
19 | ///
20 | /// The first name.
21 | public string FirstName { get; set; }
22 |
23 | ///
24 | /// Gets or sets the Id.
25 | ///
26 | /// The Id.
27 | public int Id { get; set; }
28 |
29 | ///
30 | /// Gets or sets the last name.
31 | ///
32 | /// The last name.
33 | public string LastName { get; set; }
34 |
35 | ///
36 | /// Gets or sets the parents.
37 | ///
38 | /// The parents.
39 | public Collection Parents { get; set; }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ParentPostRequest.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace Examples.Resources
4 | {
5 | ///
6 | /// Class ParentPostRequest.
7 | ///
8 | public class ParentPostRequest
9 | {
10 | ///
11 | /// Gets or sets the body.
12 | ///
13 | /// The body.
14 | [FromBody]
15 | public PersonModel Body { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ParentRequest.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.AspNetCore.Types;
2 |
3 | namespace Examples.Resources
4 | {
5 | ///
6 | /// This is the summary shown since it is the FIRST template generated.
7 | ///
8 | public class ParentRequest : FilteredPaginationQuery
9 | {
10 | /////
11 | ///// Gets or sets the identifier.
12 | /////
13 | ///// The identifier.
14 | //[FromRoute(Name = "parentId")]
15 | //public int Id { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/ParentResponse.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using APIBlox.AspNetCore.Contracts;
3 |
4 | namespace Examples.Resources
5 | {
6 | ///
7 | /// Class ParentResponse.
8 | ///
9 | ///
10 | public class ParentResponse : IResource
11 | {
12 | ///
13 | ///
14 | /// Gets or sets the Id.
15 | ///
16 | /// The Id.
17 | public int Id { get; set; }
18 |
19 | ///
20 | /// Gets or sets the age.
21 | ///
22 | /// The age.
23 | public int Age { get; set; }
24 |
25 | ///
26 | /// Gets or sets the first name.
27 | ///
28 | /// The first name.
29 | public string FirstName { get; set; }
30 |
31 | ///
32 | /// Gets or sets the last name.
33 | ///
34 | /// The last name.
35 | public string LastName { get; set; }
36 |
37 | ///
38 | /// Gets or sets the children.
39 | ///
40 | /// The children.
41 | public Collection Children { get; set; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Resources/PersonModel.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace Examples.Resources
4 | {
5 | ///
6 | /// Class PersonModel.
7 | ///
8 | public class PersonModel
9 | {
10 | ///
11 | /// Gets or sets the age.
12 | ///
13 | /// The age.
14 | [Required]
15 | public int Age { get; set; }
16 |
17 | ///
18 | /// Gets or sets the first name.
19 | ///
20 | /// The first name.
21 | [Required]
22 | public string FirstName { get; set; }
23 |
24 | ///
25 | /// Gets or sets the last name.
26 | ///
27 | /// The last name.
28 | [Required]
29 | public string LastName { get; set; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Services/RandomNumberGeneratorService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using APIBlox.NetCore.Attributes;
3 | using Examples.Contracts;
4 | using Microsoft.Extensions.DependencyInjection;
5 |
6 | namespace Examples.Services
7 | {
8 | ///
9 | ///
10 | /// Class RandomNumberGeneratorService.
11 | ///
12 | ///
13 | [InjectableService(ServiceLifetime = ServiceLifetime.Singleton)]
14 | public class RandomNumberGeneratorService : IRandomNumberGeneratorService
15 | {
16 | private static readonly Random Rnd = new((int) (DateTime.Now.Ticks % 100));
17 |
18 | ///
19 | ///
20 | /// Generates the number.
21 | ///
22 | /// System.Int32.
23 | public int GenerateNumber(int max)
24 | {
25 | return Rnd.Next(1, max);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/Startup.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using APIBlox.AspNetCore.Contracts;
3 | using Examples.Configuration;
4 | using Microsoft.AspNetCore.Hosting;
5 |
6 | namespace Examples
7 | {
8 | ///
9 | ///
10 | /// Class Startup.
11 | /// Implements the
12 | ///
13 | public class Startup : StartupBase
14 | {
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | /// The environment.
19 | public Startup(IWebHostEnvironment environment)
20 | : base(environment)
21 | {
22 | }
23 |
24 | ///
25 | /// Builds the templates.
26 | ///
27 | /// The templates.
28 | /// IEnumerable<IComposedTemplate>.
29 | protected override IEnumerable BuildTemplates(List templates)
30 | {
31 | templates
32 | .AddChildrenControllerTemplates()
33 | .AddParentsControllerTemplates()
34 | ;
35 |
36 | return templates;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
--------------------------------------------------------------------------------
/Examples/Dynamic Controllers/Examples.DynamicControllers/swaggerGen.dat:
--------------------------------------------------------------------------------
1 | -a c:\Source\Repos\Fks\api-blox\Examples\Dynamic Controllers\Examples.DynamicControllers\bin\debug\netcoreapp2.2\Examples.DynamicControllers.dll
2 | -ap c:\Source\Repos\Fks\api-blox\Examples\Dynamic Controllers\Examples.DynamicControllers\appsettings.json
3 | -t Startup
4 | -o c:\Source\Repos\Fks\api-blox\Examples\Dynamic Controllers\Examples.DynamicControllers\bin\debug\netcoreapp2.2\swagger.json
5 |
6 | -pretty
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/AggregateModels/CosmosAggregate.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 |
3 | namespace Examples.AggregateModels
4 | {
5 | ///
6 | ///
7 | /// Class CosmosAggregate.
8 | /// Implements the
9 | ///
10 | public class CosmosAggregate : Aggregate
11 | {
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | /// The event store service.
16 | /// The stream identifier.
17 | public CosmosAggregate(IEventStoreService eventStoreService, string streamId)
18 | : base(eventStoreService, streamId)
19 | {
20 | }
21 | }
22 |
23 | ///
24 | ///
25 | /// Class CosmosAggregate.
26 | /// Implements the
27 | ///
28 | public class CosmosAggregate2 : Aggregate
29 | {
30 | ///
31 | /// Initializes a new instance of the class.
32 | ///
33 | /// The event store service.
34 | /// The stream identifier.
35 | public CosmosAggregate2(IEventStoreService eventStoreService, string streamId)
36 | : base(eventStoreService, streamId)
37 | {
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/AggregateModels/EfCoreSqlAggregate.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 |
3 | namespace Examples.AggregateModels
4 | {
5 | ///
6 | ///
7 | /// Class EfCoreSqlAggregate.
8 | /// Implements the
9 | ///
10 | public class EfCoreSqlAggregate : Aggregate
11 | {
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | /// The event store service.
16 | /// The stream identifier.
17 | public EfCoreSqlAggregate(IEventStoreService eventStoreService, string streamId)
18 | : base(eventStoreService, streamId)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/AggregateModels/MongoAggregate.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 |
3 | namespace Examples.AggregateModels
4 | {
5 | ///
6 | ///
7 | /// Class MongoAggregate.
8 | /// Implements the
9 | ///
10 | public class MongoAggregate : Aggregate
11 | {
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | /// The event store service.
16 | /// The stream identifier.
17 | public MongoAggregate(IEventStoreService eventStoreService, string streamId)
18 | : base(eventStoreService, streamId)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/AggregateModels/RavenAggregate.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 |
3 | namespace Examples.AggregateModels
4 | {
5 | ///
6 | ///
7 | /// Class RavenAggregate.
8 | /// Implements the
9 | ///
10 | public class RavenAggregate : Aggregate
11 | {
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | /// The event store service.
16 | /// The stream identifier.
17 | public RavenAggregate(IEventStoreService eventStoreService, string streamId)
18 | : base(eventStoreService, streamId)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Configuration/SwaggerConfig.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using Microsoft.OpenApi.Models;
4 |
5 | namespace Examples.Configuration
6 | {
7 | internal static class SwaggerConfig
8 | {
9 | public static IServiceCollection AddSwaggerExampleFeatures(this IServiceCollection services, string siteTitle, string version)
10 | {
11 | return services.AddSwaggerGen(c =>
12 | {
13 | c.SwaggerDoc(version,
14 | new OpenApiInfo
15 | {
16 | Title = siteTitle,
17 | Version = version
18 | }
19 | );
20 | c.IncludeXmlComments(@".\Examples.EventSourcing.xml", true);
21 | }
22 | );
23 | }
24 |
25 | public static IApplicationBuilder UseSwaggerExampleFeatures(this IApplicationBuilder app, string siteTitle, string version)
26 | {
27 | return app.UseSwagger()
28 | .UseSwaggerUI(s =>
29 | s.SwaggerEndpoint($"/swagger/{version}/swagger.json",
30 | $"{siteTitle} {version}"
31 | )
32 | );
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Controllers/EventSourcingEfCoreController.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 | using Examples.AggregateModels;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Examples.Controllers
6 | {
7 | ///
8 | ///
9 | /// Class EventSourcingController.
10 | /// Implements the
11 | ///
12 | ///
13 | ///
14 | ///
15 | [Route("api/[controller]")]
16 | [ApiController]
17 | public class EventSourcingEfCoreController : EventSourcingController
18 | {
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | /// The SVC.
23 | public EventSourcingEfCoreController(IEventStoreService svc)
24 | : base(svc)
25 | {
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Controllers/EventSourcingMongoDbController.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 | using Examples.AggregateModels;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Examples.Controllers
6 | {
7 | ///
8 | ///
9 | /// Class EventSourcingController.
10 | /// Implements the
11 | ///
12 | ///
13 | ///
14 | ///
15 | [Route("api/[controller]")]
16 | [ApiController]
17 | public class EventSourcingMongoDbController : EventSourcingController
18 | {
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | /// The SVC.
23 | public EventSourcingMongoDbController(IEventStoreService svc)
24 | : base(svc)
25 | {
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Controllers/EventSourcingRavenDbController.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Contracts;
2 | using Examples.AggregateModels;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Examples.Controllers
6 | {
7 | ///
8 | ///
9 | /// Class EventSourcingController.
10 | /// Implements the
11 | ///
12 | ///
13 | ///
14 | ///
15 | [Route("api/[controller]")]
16 | [ApiController]
17 | public class EventSourcingRavenDbController : EventSourcingController
18 | {
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | /// The SVC.
23 | public EventSourcingRavenDbController(IEventStoreService svc)
24 | : base(svc)
25 | {
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Events/SomeValueAdded.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Examples.Events
4 | {
5 | internal class SomeValueAdded
6 | {
7 | public SomeValueAdded(Guid aggregateId, string someValue)
8 | {
9 | AggregateId = aggregateId;
10 | SomeValue = someValue;
11 | }
12 |
13 | public string SomeValue { get; }
14 |
15 | public Guid AggregateId { get; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Events/SomeValueChanged.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Examples.Events
4 | {
5 | internal class SomeValueChanged
6 | {
7 | public SomeValueChanged(Guid aggregateId, string someValue)
8 | {
9 | AggregateId = aggregateId;
10 | SomeValue = someValue;
11 | }
12 |
13 | public string SomeValue { get; }
14 |
15 | public Guid AggregateId { get; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Examples.EventSourcing.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | Examples
6 | latest
7 |
8 |
9 |
10 | .\Examples.EventSourcing.xml
11 | TRACE;UseAPIBlox
12 |
13 |
14 |
15 | TRACE;UseAPIBlox1
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Examples.EventSourcing.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | False
3 | False
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace Examples
7 | {
8 | internal class Program
9 | {
10 | public static void Main(string[] args)
11 | {
12 | StartupLogger = LoggerFactory.Create(a => a.AddConsole());
13 |
14 | CreateHostBuilder(args).Build().Run();
15 | }
16 |
17 | public static ILoggerFactory StartupLogger { get; private set; }
18 |
19 | private static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:52518",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "Examples.EventSourcing": {
19 | "commandName": "Project",
20 | "launchUrl": "http://localhost:5000/swagger",
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "http://localhost:5000"
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/Resources/AggregateResource.cs:
--------------------------------------------------------------------------------
1 | namespace Examples.Resources
2 | {
3 | ///
4 | /// Class AggregateResource.
5 | ///
6 | public class AggregateResource
7 | {
8 | ///
9 | /// Gets or sets the first name.
10 | ///
11 | /// The first name.
12 | public string FirstName { get; set; }
13 |
14 | ///
15 | /// Gets or sets some value.
16 | ///
17 | /// Some value.
18 | public string SomeValue { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Examples/Event Sourcing/Examples.EventSourcing/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*",
8 |
9 | "CosmosDbOptions": {
10 | "Endpoint": "https://localhost:8081",
11 | "Key": "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
12 | "DatabaseId": "APIBloxExamples",
13 |
14 | "CollectionProperties": {
15 | "DemoData": {
16 | "Models": [ "CosmosAggregate" ],
17 | "UniqueKeyPolicy": {
18 | "uniqueKeys": []
19 | },
20 | "OfferThroughput": -1
21 | },
22 | "DemoData2": {
23 | "Models": [ "CosmosAggregate2" ],
24 | "UniqueKeyPolicy": {
25 | "uniqueKeys": []
26 | },
27 | "OfferThroughput": -1
28 | }
29 | }
30 | },
31 |
32 | "MongoDbOptions": {
33 | "CnnString": "mongodb://localhost:27017",
34 | "DatabaseId": "APIBloxExamples",
35 |
36 | "CollectionProperties": {
37 | "MongoAggregate": {
38 | "Indexes": [ "{streamId:1}", "{documentType:1}" ]
39 | }
40 | }
41 | },
42 |
43 | "RavenDbOptions": {
44 | "Urls": [ "http://127.0.0.1:8080" ],
45 | "DatabaseId": "APIBloxExamples",
46 |
47 | "CollectionProperties": {
48 | "RavenAggregate": {
49 | }
50 | }
51 | },
52 |
53 | "EfCoreSqlOptions": {
54 | "CnnString": "Server=.;Database=UserSettingsDb;Trusted_Connection=True;",
55 | "EnableDetailedErrors": true,
56 | "EnableSensitiveDataLogging": true,
57 | "ConfigureWarnings": true
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Kill Assets.Json.cmd:
--------------------------------------------------------------------------------
1 | attrib -r *.assets.json /s
2 | del *.assets.json /s /q
--------------------------------------------------------------------------------
/Kill Bin and Obj.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | cls
3 | dir bin /s /AD /b > clean.tmp
4 | dir obj /s /AD /b >> clean.tmp
5 | for /F "tokens=*" %%A in (clean.tmp) do echo rmdir /S /Q "%%A"
6 | echo This command will remove ALL BIN and OBJ folders in this tree.
7 | rem echo To run the commands as listed ...
8 | rem pause
9 | for /F "tokens=*" %%A in (clean.tmp) do rmdir /S /Q "%%A"
10 | del clean.tmp
11 | rem pause
12 | timeout /t 5
--------------------------------------------------------------------------------
/SlnTests/APIBlox.AspNetCore.OpenApi/BuilderTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using Xunit;
3 |
4 | namespace SlnTests.APIBlox.AspNetCore.OpenApi
5 | {
6 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
7 | public class BuilderTests
8 | {
9 | [Fact]
10 | public void DocumentShouldNotBeEmpty()
11 | {
12 | var col = new ServiceCollection();
13 |
14 | //col.AddOpenApiBits();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SlnTests/APIBlox.NetCore/SimpleMapperTests.cs:
--------------------------------------------------------------------------------
1 | using APIBlox.NetCore.Types;
2 | using APIBlox.NetCore.Types.JsonBits;
3 | using Newtonsoft.Json;
4 | using Xunit;
5 |
6 | namespace SlnTests.APIBlox.NetCore
7 | {
8 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
9 |
10 | public class SimpleMapperTests
11 | {
12 | public class Foo
13 | {
14 | public string Name { get; set; }
15 | }
16 |
17 | public class Bar
18 | {
19 | public string Name { get; private set; }
20 | }
21 |
22 | [Fact]
23 | public void Success()
24 | {
25 | var foo = new Foo {Name = " "};
26 |
27 | var bar = foo.MapTo(settings: new JsonSerializerSettings
28 | {
29 | Converters = new JsonConverter[] {new EmptyStringToNullConverter()},
30 | ContractResolver = new PopulateNonPublicSettersContractResolver()
31 | }
32 | );
33 |
34 | Assert.Null(bar.Name);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/logo-blue-large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Slacquer/api-blox/0f27afa37480bf991ff9745dc9739bc9707660a6/logo-blue-large.png
--------------------------------------------------------------------------------
/logo-blue-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Slacquer/api-blox/0f27afa37480bf991ff9745dc9739bc9707660a6/logo-blue-small.png
--------------------------------------------------------------------------------