Browse Source

Some progress

pull/1/head
Sebastian Stehle 9 years ago
parent
commit
8405695374
  1. 9
      PinkParrot.sln
  2. 74
      src/PinkParrot/Modules/Api/Schemas/SchemaFieldsController.cs
  3. 37
      src/PinkParrot/Modules/Api/Schemas/SchemasController.cs
  4. 40
      src/PinkParrot/Startup.cs
  5. 8
      src/PinkParrot/project.json
  6. 5
      src/PinkParrot/web.config
  7. 8
      src/pinkparrot_core/PinkParrot.Core/Schema/ModelField.cs
  8. 12
      src/pinkparrot_core/PinkParrot.Core/Schema/ModelSchema.cs
  9. 2
      src/pinkparrot_core/PinkParrot.Core/Schema/ModelSchemaMetadata.cs
  10. 4
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldAdded.cs
  11. 4
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldDeleted.cs
  12. 4
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldDisabled.cs
  13. 4
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldEnabled.cs
  14. 4
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldHidden.cs
  15. 4
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldShown.cs
  16. 3
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldUpdated.cs
  17. 4
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelSchemaCreated.cs
  18. 4
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelSchemaDeleted.cs
  19. 3
      src/pinkparrot_events/PinkParrot.Events/Schema/ModelSchemaUpdated.cs
  20. 18
      src/pinkparrot_events/PinkParrot.Events/TenantEvent.cs
  21. 3
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure.Tests/DispatchingTests.cs
  22. 8
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure.Tests/PropertiesBagTests.cs
  23. 33
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/Autofac/AutofacDomainObjectFactory.cs
  24. 16
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/DomainObject.cs
  25. 20
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/EnvelopeExtensions.cs
  26. 11
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/GetEventStore/GetEventStoreDomainObjectRepository.cs
  27. 2
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/IAggregate.cs
  28. 1
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/Dispatching/ActionContextDispatcherFactory.cs
  29. 1
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/Dispatching/ActionDispatcherFactory.cs
  30. 1
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/Dispatching/FuncContextDispatcherFactory.cs
  31. 1
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/Dispatching/FuncDispatcherFactory.cs
  32. 15
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/ICommandContext.cs
  33. 12
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/ValidationException.cs
  34. 7
      src/pinkparrot_infrastructure/PinkParrot.Infrastructure/project.json
  35. 16
      src/pinkparrot_read/PinkParrot.Read/Models/ModelSchemaRM.cs
  36. 19
      src/pinkparrot_read/PinkParrot.Read/PinkParrot.Read.xproj
  37. 19
      src/pinkparrot_read/PinkParrot.Read/Repositories/IModelSchemaRepository.cs
  38. 42
      src/pinkparrot_read/PinkParrot.Read/Repositories/MongoDb/MongoDbModelSchemaRepository.cs
  39. 33
      src/pinkparrot_read/PinkParrot.Read/Repositories/MongoDb/Utils/BaseRepository.cs
  40. 27
      src/pinkparrot_read/PinkParrot.Read/project.json
  41. 18
      src/pinkparrot_write/PinkParrot.Write/Schema/ISchemaIdProvider.cs
  42. 4
      src/pinkparrot_write/PinkParrot.Write/Schema/ModelSchemaDomainObject.cs
  43. 70
      src/pinkparrot_write/PinkParrot.Write/Schema/ModelSchemaNameMap.cs

9
PinkParrot.sln

@ -32,6 +32,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pinkparrot_write", "pinkpar
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "PinkParrot.Write", "src\pinkparrot_write\PinkParrot.Write\PinkParrot.Write.xproj", "{A85201C6-6AF8-4B63-8365-08F741050438}" Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "PinkParrot.Write", "src\pinkparrot_write\PinkParrot.Write\PinkParrot.Write.xproj", "{A85201C6-6AF8-4B63-8365-08F741050438}"
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "PinkParrot.Read", "src\pinkparrot_read\PinkParrot.Read\PinkParrot.Read.xproj", "{A92B4734-2587-4F6F-97A3-741BE48709A5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pinkparrot_read", "pinkparrot_read", "{2CDAF493-B88E-48BD-9634-B5128C106199}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -66,6 +70,10 @@ Global
{A85201C6-6AF8-4B63-8365-08F741050438}.Debug|Any CPU.Build.0 = Debug|Any CPU {A85201C6-6AF8-4B63-8365-08F741050438}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A85201C6-6AF8-4B63-8365-08F741050438}.Release|Any CPU.ActiveCfg = Release|Any CPU {A85201C6-6AF8-4B63-8365-08F741050438}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A85201C6-6AF8-4B63-8365-08F741050438}.Release|Any CPU.Build.0 = Release|Any CPU {A85201C6-6AF8-4B63-8365-08F741050438}.Release|Any CPU.Build.0 = Release|Any CPU
{A92B4734-2587-4F6F-97A3-741BE48709A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A92B4734-2587-4F6F-97A3-741BE48709A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A92B4734-2587-4F6F-97A3-741BE48709A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A92B4734-2587-4F6F-97A3-741BE48709A5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -78,5 +86,6 @@ Global
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF} {BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{25F66C64-058A-4D44-BC0C-F12A054F9A91} = {6AE39761-FD74-45CD-99CF-73D3D2E5D064} {25F66C64-058A-4D44-BC0C-F12A054F9A91} = {6AE39761-FD74-45CD-99CF-73D3D2E5D064}
{A85201C6-6AF8-4B63-8365-08F741050438} = {4AED438F-684F-4FAE-B016-21CF2EAEA79F} {A85201C6-6AF8-4B63-8365-08F741050438} = {4AED438F-684F-4FAE-B016-21CF2EAEA79F}
{A92B4734-2587-4F6F-97A3-741BE48709A5} = {2CDAF493-B88E-48BD-9634-B5128C106199}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

74
src/PinkParrot/Modules/Api/Schemas/SchemaFieldsController.cs

@ -0,0 +1,74 @@
// ==========================================================================
// SchemaFieldsController.cs
// PinkParrot Headless CMS
// ==========================================================================
// Copyright (c) PinkParrot Group
// All rights reserved.
// ==========================================================================
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using PinkParrot.Infrastructure.CQRS.Commands;
using PinkParrot.Write.Schema.Commands;
namespace PinkParrot.Modules.Api.Schemas
{
public class SchemasFieldsController : Controller
{
private readonly ICommandBus commandBus;
public SchemasFieldsController(ICommandBus commandBus)
{
this.commandBus = commandBus;
}
[HttpPost]
[Route("schemas/{name}/fields/")]
public Task Add(AddModelField command)
{
return commandBus.PublishAsync(command);
}
[HttpPut]
[Route("schemas/{name}/fields/{fieldId:long}/")]
public Task Update(UpdateModelField command)
{
return commandBus.PublishAsync(command);
}
[HttpPut]
[Route("schemas/{name}/fields/{fieldId:long}/hide/")]
public Task Hide(HideModelField command)
{
return commandBus.PublishAsync(command);
}
[HttpPut]
[Route("schemas/{name}/fields/{fieldId:long}/show/")]
public Task Show(ShowModelField command)
{
return commandBus.PublishAsync(command);
}
[HttpPut]
[Route("schemas/{name}/fields/{fieldId:long}/enable/")]
public Task Enable(EnableModelField command)
{
return commandBus.PublishAsync(command);
}
[HttpPut]
[Route("schemas/{name}/fields/{fieldId:long}/disable/")]
public Task Enable(DisableModelField command)
{
return commandBus.PublishAsync(command);
}
[HttpDelete]
[Route("schemas/{name}/fields/{fieldId:long}/")]
public Task Delete(DeleteModelField command)
{
return commandBus.PublishAsync(command);
}
}
}

37
src/PinkParrot/Modules/Api/Schemas/SchemasController.cs

@ -1,26 +1,55 @@
using System.Threading.Tasks; // ==========================================================================
// SchemasController.cs
// PinkParrot Headless CMS
// ==========================================================================
// Copyright (c) PinkParrot Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using PinkParrot.Infrastructure.CQRS.Commands;
using PinkParrot.Read.Models;
using PinkParrot.Write.Schema.Commands;
namespace PinkParrot.Modules.Api.Schemas namespace PinkParrot.Modules.Api.Schemas
{ {
public class SchemasController : Controller public class SchemasController : Controller
{ {
private readonly ICommandBus commandBus;
public SchemasController(ICommandBus commandBus)
{
this.commandBus = commandBus;
}
[HttpGet]
[Route("schemas/")]
public Task<List<ModelSchemaRM>> Query()
{
return null;
}
[HttpPost] [HttpPost]
[Route("schemas/")] [Route("schemas/")]
public async Task Create() public Task Create(CreateModelSchema command)
{ {
return commandBus.PublishAsync(command);
} }
[HttpPut] [HttpPut]
[Route("schemas/{name}/")] [Route("schemas/{name}/")]
public async Task Update() public Task Update(UpdateModelSchema command)
{ {
return commandBus.PublishAsync(command);
} }
[HttpDelete] [HttpDelete]
[Route("schemas/{name}/")] [Route("schemas/{name}/")]
public async Task Delete() public Task Delete()
{ {
return commandBus.PublishAsync(new DeleteModelSchema());
} }
} }
} }

40
src/PinkParrot/Startup.cs

@ -6,27 +6,59 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using System;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using PinkParrot.Infrastructure.CQRS.Autofac;
using PinkParrot.Infrastructure.CQRS.Commands;
// ReSharper disable AccessToModifiedClosure
namespace PinkParrot namespace PinkParrot
{ {
public class Startup public class Startup
{ {
// This method gets called by the runtime. Use this method to add services to the container. public IServiceProvider ConfigureServices(IServiceCollection services)
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc();
services.AddRouting();
services.AddSwaggerGen();
IContainer container = null;
var containerBuilder = new ContainerBuilder();
containerBuilder.Populate(services);
containerBuilder.Register(c => container)
.As<IContainer>()
.SingleInstance();
containerBuilder.RegisterType<AutofacDomainObjectFactory>()
.As<IDomainObjectFactory>()
.SingleInstance();
containerBuilder.RegisterType<InMemoryCommandBus>()
.As<ICommandBus>()
.SingleInstance();
container = containerBuilder.Build();
return new AutofacServiceProvider(container);
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{ {
loggerFactory.AddConsole(); loggerFactory.AddConsole();
app.UseMvc();
app.UseStaticFiles();
app.UseSwagger();
app.UseSwaggerUi();
if (env.IsDevelopment()) if (env.IsDevelopment())
{ {
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();

8
src/PinkParrot/project.json

@ -1,5 +1,7 @@
{ {
"dependencies": { "dependencies": {
"Autofac": "4.1.0",
"Autofac.Extensions.DependencyInjection": "4.0.0",
"Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Razor.Tools": { "Microsoft.AspNetCore.Razor.Tools": {
@ -19,10 +21,14 @@
"version": "1.0.0", "version": "1.0.0",
"type": "platform" "type": "platform"
}, },
"MongoDB.Driver": "2.3.0-rc1",
"PinkParrot.Core": "1.0.0-*", "PinkParrot.Core": "1.0.0-*",
"PinkParrot.Events": "1.0.0-*", "PinkParrot.Events": "1.0.0-*",
"PinkParrot.Infrastructure": "1.0.0-*", "PinkParrot.Infrastructure": "1.0.0-*",
"PinkParrot.Write": "1.0.0-*" "PinkParrot.Read": "1.0.0-*",
"PinkParrot.Write": "1.0.0-*",
"Swashbuckle.SwaggerGen": "6.0.0-beta901",
"Swashbuckle.SwaggerUi": "6.0.0-beta901"
}, },
"tools": { "tools": {

5
src/PinkParrot/web.config

@ -1,10 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer> <system.webServer>
<handlers> <handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>

8
src/pinkparrot_core/PinkParrot.Core/Schema/ModelField.cs

@ -134,7 +134,7 @@ namespace PinkParrot.Core.Schema
{ {
if (isHidden) if (isHidden)
{ {
throw new DomainValidationException($"The field '{name} is already hidden."); throw new ValidationException($"The field '{name} is already hidden.");
} }
var clone = Clone(); var clone = Clone();
@ -148,7 +148,7 @@ namespace PinkParrot.Core.Schema
{ {
if (!isHidden) if (!isHidden)
{ {
throw new DomainValidationException($"The field '{name} is already visible."); throw new ValidationException($"The field '{name} is already visible.");
} }
var clone = Clone(); var clone = Clone();
@ -162,7 +162,7 @@ namespace PinkParrot.Core.Schema
{ {
if (isDisabled) if (isDisabled)
{ {
throw new DomainValidationException($"The field '{name} is already disabled."); throw new ValidationException($"The field '{name} is already disabled.");
} }
var clone = Clone(); var clone = Clone();
@ -176,7 +176,7 @@ namespace PinkParrot.Core.Schema
{ {
if (!isDisabled) if (!isDisabled)
{ {
throw new DomainValidationException($"The field '{name} is already enabled."); throw new ValidationException($"The field '{name} is already enabled.");
} }
var clone = Clone(); var clone = Clone();

12
src/pinkparrot_core/PinkParrot.Core/Schema/ModelSchema.cs

@ -37,7 +37,7 @@ namespace PinkParrot.Core.Schema
{ {
if (!name.IsSlug()) if (!name.IsSlug())
{ {
throw new DomainValidationException("Cannot create the schema.", $"'{name}' is not a valid slug."); throw new ValidationException("Cannot create the schema.", $"'{name}' is not a valid slug.");
} }
return new ModelSchema(new ModelSchemaMetadata(name), ImmutableDictionary<long, ModelField>.Empty); return new ModelSchema(new ModelSchemaMetadata(name), ImmutableDictionary<long, ModelField>.Empty);
@ -79,7 +79,7 @@ namespace PinkParrot.Core.Schema
if (errors.Any()) if (errors.Any())
{ {
throw new DomainValidationException($"Cannot update field with id '{fieldId}', becase the settings are invalid.", errors); throw new ValidationException($"Cannot update field with id '{fieldId}', becase the settings are invalid.", errors);
} }
return newField; return newField;
@ -112,7 +112,7 @@ namespace PinkParrot.Core.Schema
if (fields.Values.Any(f => f.Name == field.Name && f.Id != field.Id)) if (fields.Values.Any(f => f.Name == field.Name && f.Id != field.Id))
{ {
throw new DomainValidationException($"A field with name '{field.Name}' already exists."); throw new ValidationException($"A field with name '{field.Name}' already exists.");
} }
return new ModelSchema(metadata, fields.SetItem(field.Id, field)); return new ModelSchema(metadata, fields.SetItem(field.Id, field));
@ -122,7 +122,7 @@ namespace PinkParrot.Core.Schema
{ {
if (!fields.ContainsKey(fieldId)) if (!fields.ContainsKey(fieldId))
{ {
throw new DomainValidationException($"A field with id {fieldId} does not exist."); throw new ValidationException($"A field with id {fieldId} does not exist.");
} }
return new ModelSchema(metadata, fields.Remove(fieldId)); return new ModelSchema(metadata, fields.Remove(fieldId));
@ -134,7 +134,7 @@ namespace PinkParrot.Core.Schema
if (!fields.TryGetValue(fieldId, out field)) if (!fields.TryGetValue(fieldId, out field))
{ {
throw new DomainValidationException($"Cannot update field with id '{fieldId}'.", "Field does not exist."); throw new ValidationException($"Cannot update field with id '{fieldId}'.", "Field does not exist.");
} }
var newField = updater(field); var newField = updater(field);
@ -168,7 +168,7 @@ namespace PinkParrot.Core.Schema
if (errors.Any()) if (errors.Any())
{ {
throw new DomainValidationException("The data is not valid.", errors); throw new ValidationException("The data is not valid.", errors);
} }
} }
} }

2
src/pinkparrot_core/PinkParrot.Core/Schema/ModelSchemaMetadata.cs

@ -54,7 +54,7 @@ namespace PinkParrot.Core.Schema
{ {
if (!newName.IsSlug()) if (!newName.IsSlug())
{ {
throw new DomainValidationException("Cannot update the schema.", $"'{newName}' is not a valid slug."); throw new ValidationException("Cannot update the schema.", $"'{newName}' is not a valid slug.");
} }
clone.name = newName; clone.name = newName;

4
src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldAdded.cs

@ -6,11 +6,9 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelFieldAdded : IEvent public class ModelFieldAdded : TenantEvent
{ {
public long FieldId; public long FieldId;

4
src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldDeleted.cs

@ -6,11 +6,9 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelFieldDeleted : IEvent public class ModelFieldDeleted : TenantEvent
{ {
public long FieldId; public long FieldId;
} }

4
src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldDisabled.cs

@ -6,11 +6,9 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelFieldDisabled : IEvent public class ModelFieldDisabled : TenantEvent
{ {
public long FieldId; public long FieldId;
} }

4
src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldEnabled.cs

@ -6,11 +6,9 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelFieldEnabled : IEvent public class ModelFieldEnabled : TenantEvent
{ {
public long FieldId; public long FieldId;
} }

4
src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldHidden.cs

@ -6,11 +6,9 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelFieldHidden : IEvent public class ModelFieldHidden : TenantEvent
{ {
public long FieldId; public long FieldId;
} }

4
src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldShown.cs

@ -6,11 +6,9 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelFieldShown : IEvent public class ModelFieldShown : TenantEvent
{ {
public long FieldId; public long FieldId;
} }

3
src/pinkparrot_events/PinkParrot.Events/Schema/ModelFieldUpdated.cs

@ -7,11 +7,10 @@
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure; using PinkParrot.Infrastructure;
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelFieldUpdated : IEvent public class ModelFieldUpdated : TenantEvent
{ {
public long FieldId; public long FieldId;

4
src/pinkparrot_events/PinkParrot.Events/Schema/ModelSchemaCreated.cs

@ -6,11 +6,9 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelSchemaCreated : IEvent public class ModelSchemaCreated : TenantEvent
{ {
public string Name; public string Name;
} }

4
src/pinkparrot_events/PinkParrot.Events/Schema/ModelSchemaDeleted.cs

@ -6,11 +6,9 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelSchemaDeleted : IEvent public class ModelSchemaDeleted : TenantEvent
{ {
} }
} }

3
src/pinkparrot_events/PinkParrot.Events/Schema/ModelSchemaUpdated.cs

@ -7,11 +7,10 @@
// ========================================================================== // ==========================================================================
using PinkParrot.Infrastructure; using PinkParrot.Infrastructure;
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events.Schema namespace PinkParrot.Events.Schema
{ {
public class ModelSchemaUpdated : IEvent public class ModelSchemaUpdated : TenantEvent
{ {
public string NewName; public string NewName;

18
src/pinkparrot_events/PinkParrot.Events/TenantEvent.cs

@ -0,0 +1,18 @@
// ==========================================================================
// TenantEvent.cs
// PinkParrot Headless CMS
// ==========================================================================
// Copyright (c) PinkParrot Group
// All rights reserved.
// ==========================================================================
using System;
using PinkParrot.Infrastructure.CQRS.Events;
namespace PinkParrot.Events
{
public class TenantEvent : IEvent
{
public Guid TenantId;
}
}

3
src/pinkparrot_infrastructure/PinkParrot.Infrastructure.Tests/DispatchingTests.cs

@ -10,6 +10,9 @@ using System.Threading.Tasks;
using PinkParrot.Infrastructure.Dispatching; using PinkParrot.Infrastructure.Dispatching;
using PinkParrot.Infrastructure.Tasks; using PinkParrot.Infrastructure.Tasks;
using Xunit; using Xunit;
// ReSharper disable UnusedMethodReturnValue.Local
// ReSharper disable UnusedParameter.Local
// ReSharper disable UnusedMember.Local
namespace PinkParrot.Infrastructure namespace PinkParrot.Infrastructure
{ {

8
src/pinkparrot_infrastructure/PinkParrot.Infrastructure.Tests/PropertiesBagTests.cs

@ -295,6 +295,14 @@ namespace PinkParrot.Infrastructure
AssertBoolean(false); AssertBoolean(false);
} }
[Fact]
public void Should_provide_value_as_string()
{
bag.Set("Key", "Foo");
AssertString("Foo");
}
[Fact] [Fact]
public void Should_throw_when_converting_instant_to_number() public void Should_throw_when_converting_instant_to_number()
{ {

33
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/Autofac/AutofacDomainObjectFactory.cs

@ -0,0 +1,33 @@
// ==========================================================================
// AutofacDomainObjectFactory.cs
// PinkParrot Headless CMS
// ==========================================================================
// Copyright (c) PinkParrot Group
// All rights reserved.
// ==========================================================================
using System;
using Autofac;
using PinkParrot.Infrastructure.CQRS.Commands;
namespace PinkParrot.Infrastructure.CQRS.Autofac
{
public sealed class AutofacDomainObjectFactory : IDomainObjectFactory
{
private readonly IContainer container;
public AutofacDomainObjectFactory(IContainer container)
{
Guard.NotNull(container, nameof(container));
this.container = container;
}
public IAggregate CreateNew(Type type, Guid id)
{
return (IAggregate)container.Resolve(type,
new NamedParameter("id", id),
new NamedParameter("version", 0));
}
}
}

16
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/DomainObject.cs

@ -38,17 +38,19 @@ namespace PinkParrot.Infrastructure.CQRS
this.version = version; this.version = version;
} }
protected abstract void ApplyEvent(IEvent @event); protected abstract void ApplyEvent(Envelope<IEvent> @event);
protected void RaiseEvent<TEvent>(Envelope<TEvent> envelope, bool disableApply = false) where TEvent : class, IEvent protected void RaiseEvent<TEvent>(Envelope<TEvent> envelope, bool disableApply = false) where TEvent : class, IEvent
{ {
Guard.NotNull(envelope, nameof(envelope)); Guard.NotNull(envelope, nameof(envelope));
uncomittedEvents.Add(envelope.To<IEvent>()); var envelopeToAdd = envelope.To<IEvent>();
uncomittedEvents.Add(envelopeToAdd);
if (!disableApply) if (!disableApply)
{ {
ApplyEvent(envelope.Payload); ApplyEvent(envelopeToAdd);
} }
} }
@ -56,15 +58,17 @@ namespace PinkParrot.Infrastructure.CQRS
{ {
Guard.NotNull(@event, nameof(@event)); Guard.NotNull(@event, nameof(@event));
uncomittedEvents.Add(EnvelopeFactory.ForEvent(@event, id)); var envelopeToAdd = EnvelopeFactory.ForEvent(@event, id);
uncomittedEvents.Add(envelopeToAdd);
if (!disableApply) if (!disableApply)
{ {
ApplyEvent(@event); ApplyEvent(envelopeToAdd);
} }
} }
void IAggregate.ApplyEvent(IEvent @event) void IAggregate.ApplyEvent(Envelope<IEvent> @event)
{ {
ApplyEvent(@event); version++; ApplyEvent(@event); version++;
} }

20
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/EnvelopeExtensions.cs

@ -14,9 +14,9 @@ namespace PinkParrot.Infrastructure.CQRS
{ {
public static class EnvelopeExtensions public static class EnvelopeExtensions
{ {
public static int EventNumber<T>(this Envelope<T> envelope) where T : class public static int EventNumber(this EnvelopeHeaders headers)
{ {
return envelope.Headers[CommonHeaders.EventNumber].ToInt32(CultureInfo.InvariantCulture); return headers[CommonHeaders.EventNumber].ToInt32(CultureInfo.InvariantCulture);
} }
public static Envelope<T> SetEventNumber<T>(this Envelope<T> envelope, int value) where T : class public static Envelope<T> SetEventNumber<T>(this Envelope<T> envelope, int value) where T : class
@ -26,9 +26,9 @@ namespace PinkParrot.Infrastructure.CQRS
return envelope; return envelope;
} }
public static Guid CommitId<T>(this Envelope<T> envelope) where T : class public static Guid CommitId(this EnvelopeHeaders headers)
{ {
return envelope.Headers[CommonHeaders.CommitId].ToGuid(CultureInfo.InvariantCulture); return headers[CommonHeaders.CommitId].ToGuid(CultureInfo.InvariantCulture);
} }
public static Envelope<T> SetCommitId<T>(this Envelope<T> envelope, Guid value) where T : class public static Envelope<T> SetCommitId<T>(this Envelope<T> envelope, Guid value) where T : class
@ -38,9 +38,9 @@ namespace PinkParrot.Infrastructure.CQRS
return envelope; return envelope;
} }
public static Guid AggregateId<T>(this Envelope<T> envelope) where T : class public static Guid AggregateId(this EnvelopeHeaders headers)
{ {
return envelope.Headers[CommonHeaders.AggregateId].ToGuid(CultureInfo.InvariantCulture); return headers[CommonHeaders.AggregateId].ToGuid(CultureInfo.InvariantCulture);
} }
public static Envelope<T> SetAggregateId<T>(this Envelope<T> envelope, Guid value) where T : class public static Envelope<T> SetAggregateId<T>(this Envelope<T> envelope, Guid value) where T : class
@ -50,9 +50,9 @@ namespace PinkParrot.Infrastructure.CQRS
return envelope; return envelope;
} }
public static Guid EventId<T>(this Envelope<T> envelope) where T : class public static Guid EventId(this EnvelopeHeaders headers)
{ {
return envelope.Headers[CommonHeaders.EventId].ToGuid(CultureInfo.InvariantCulture); return headers[CommonHeaders.EventId].ToGuid(CultureInfo.InvariantCulture);
} }
public static Envelope<T> SetEventId<T>(this Envelope<T> envelope, Guid value) where T : class public static Envelope<T> SetEventId<T>(this Envelope<T> envelope, Guid value) where T : class
@ -62,9 +62,9 @@ namespace PinkParrot.Infrastructure.CQRS
return envelope; return envelope;
} }
public static Instant Timestamp<T>(this Envelope<T> envelope) where T : class public static Instant Timestamp(this EnvelopeHeaders headers)
{ {
return envelope.Headers[CommonHeaders.Timestamp].ToInstant(CultureInfo.InvariantCulture); return headers[CommonHeaders.Timestamp].ToInstant(CultureInfo.InvariantCulture);
} }
public static Envelope<T> SetTimestamp<T>(this Envelope<T> envelope, Instant value) where T : class public static Envelope<T> SetTimestamp<T>(this Envelope<T> envelope, Instant value) where T : class

11
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/GetEventStore/GetEventStoreDomainObjectRepository.cs

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace PinkParrot.Infrastructure.CQRS.GetEventStore
{
public class GetEventStoreDomainObjectRepository
{
}
}

2
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/CQRS/IAggregate.cs

@ -18,7 +18,7 @@ namespace PinkParrot.Infrastructure.CQRS
int Version { get; } int Version { get; }
void ApplyEvent(IEvent @event); void ApplyEvent(Envelope<IEvent> @event);
void ClearUncommittedEvents(); void ClearUncommittedEvents();

1
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/Dispatching/ActionContextDispatcherFactory.cs

@ -27,6 +27,7 @@ namespace PinkParrot.Infrastructure.Dispatching
return new Tuple<Type, Action<TTarget, object, TContext>>(inputType, (Action<TTarget, object, TContext>)handler); return new Tuple<Type, Action<TTarget, object, TContext>>(inputType, (Action<TTarget, object, TContext>)handler);
} }
// ReSharper disable once UnusedMember.Local
private static Action<TTarget, object, TContext> Factory<TTarget, TIn, TContext>(MethodInfo methodInfo) private static Action<TTarget, object, TContext> Factory<TTarget, TIn, TContext>(MethodInfo methodInfo)
{ {
var type = typeof(Action<TTarget, TIn, TContext>); var type = typeof(Action<TTarget, TIn, TContext>);

1
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/Dispatching/ActionDispatcherFactory.cs

@ -27,6 +27,7 @@ namespace PinkParrot.Infrastructure.Dispatching
return new Tuple<Type, Action<T, object>>(inputType, (Action<T, object>)handler); return new Tuple<Type, Action<T, object>>(inputType, (Action<T, object>)handler);
} }
// ReSharper disable once UnusedMember.Local
private static Action<TTarget, object> Factory<TTarget, TIn>(MethodInfo methodInfo) private static Action<TTarget, object> Factory<TTarget, TIn>(MethodInfo methodInfo)
{ {
var type = typeof(Action<TTarget, TIn>); var type = typeof(Action<TTarget, TIn>);

1
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/Dispatching/FuncContextDispatcherFactory.cs

@ -27,6 +27,7 @@ namespace PinkParrot.Infrastructure.Dispatching
return new Tuple<Type, Func<TTarget, object, TContext, TOut>>(inputType, (Func<TTarget, object, TContext, TOut>)handler); return new Tuple<Type, Func<TTarget, object, TContext, TOut>>(inputType, (Func<TTarget, object, TContext, TOut>)handler);
} }
// ReSharper disable once UnusedMember.Local
private static Func<TTarget, object, TContext, TOut> Factory<TTarget, TIn, TContext, TOut>(MethodInfo methodInfo) private static Func<TTarget, object, TContext, TOut> Factory<TTarget, TIn, TContext, TOut>(MethodInfo methodInfo)
{ {
var type = typeof(Func<TTarget, TIn, TContext, TOut>); var type = typeof(Func<TTarget, TIn, TContext, TOut>);

1
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/Dispatching/FuncDispatcherFactory.cs

@ -27,6 +27,7 @@ namespace PinkParrot.Infrastructure.Dispatching
return new Tuple<Type, Func<TTarget, object, TReturn>>(inputType, (Func<TTarget, object, TReturn>)handler); return new Tuple<Type, Func<TTarget, object, TReturn>>(inputType, (Func<TTarget, object, TReturn>)handler);
} }
// ReSharper disable once UnusedMember.Local
private static Func<TTarget, object, TReturn> Factory<TTarget, TIn, TReturn>(MethodInfo methodInfo) private static Func<TTarget, object, TReturn> Factory<TTarget, TIn, TReturn>(MethodInfo methodInfo)
{ {
var type = typeof(Func<TTarget, TIn, TReturn>); var type = typeof(Func<TTarget, TIn, TReturn>);

15
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/ICommandContext.cs

@ -1,15 +0,0 @@
using System;
namespace PinkParrot.Infrastructure.CQRS.Commands
{
public interface ICommandContext
{
ICommand Command { get; }
Exception Exception { get; }
IDomainObjectFactory Factory { get; }
bool IsFailed { get; }
bool IsHandled { get; }
bool IsSucceeded { get; }
IDomainObjectRepository Repository { get; }
}
}

12
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/DomainValidationException.cs → src/pinkparrot_infrastructure/PinkParrot.Infrastructure/ValidationException.cs

@ -1,5 +1,5 @@
// ========================================================================== // ==========================================================================
// DomainValidationException.cs // ValidationException.cs
// PinkParrot Headless CMS // PinkParrot Headless CMS
// ========================================================================== // ==========================================================================
// Copyright (c) PinkParrot Group // Copyright (c) PinkParrot Group
@ -12,7 +12,7 @@ using System.Linq;
namespace PinkParrot.Infrastructure namespace PinkParrot.Infrastructure
{ {
public class DomainValidationException : Exception public class ValidationException : Exception
{ {
private readonly IReadOnlyList<string> errors; private readonly IReadOnlyList<string> errors;
@ -21,25 +21,25 @@ namespace PinkParrot.Infrastructure
get { return errors; } get { return errors; }
} }
public DomainValidationException(string message, params string[] errors) public ValidationException(string message, params string[] errors)
: base(message) : base(message)
{ {
this.errors = errors != null ? errors.ToList() : new List<string>(); this.errors = errors != null ? errors.ToList() : new List<string>();
} }
public DomainValidationException(string message, IReadOnlyList<string> errors) public ValidationException(string message, IReadOnlyList<string> errors)
: base(message) : base(message)
{ {
this.errors = errors ?? new List<string>(); this.errors = errors ?? new List<string>();
} }
public DomainValidationException(string message, Exception inner, params string[] errors) public ValidationException(string message, Exception inner, params string[] errors)
: base(message, inner) : base(message, inner)
{ {
this.errors = errors != null ? errors.ToList() : new List<string>(); this.errors = errors != null ? errors.ToList() : new List<string>();
} }
public DomainValidationException(string message, Exception inner, IReadOnlyList<string> errors) public ValidationException(string message, Exception inner, IReadOnlyList<string> errors)
: base(message, inner) : base(message, inner)
{ {
this.errors = errors ?? new List<string>(); this.errors = errors ?? new List<string>();

7
src/pinkparrot_infrastructure/PinkParrot.Infrastructure/project.json

@ -1,11 +1,12 @@
{ {
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"NodaTime": "2.0.0-alpha20160729", "Autofac": "4.1.0",
"NETStandard.Library": "1.6.0", "NETStandard.Library": "1.6.0",
"System.Reflection.TypeExtensions": "4.1.0", "Newtonsoft.Json": "9.0.1",
"NodaTime": "2.0.0-alpha20160729",
"System.Linq": "4.1.0", "System.Linq": "4.1.0",
"Newtonsoft.Json": "9.0.1" "System.Reflection.TypeExtensions": "4.1.0"
}, },
"frameworks": { "frameworks": {
"netcoreapp1.0": { "netcoreapp1.0": {

16
src/pinkparrot_read/PinkParrot.Read/Models/ModelSchemaRM.cs

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace PinkParrot.Read.Models
{
public sealed class ModelSchemaRM
{
public string Id { get; set; }
public string Name { get; set; }
public Guid SchemaId { get; set; }
}
}

19
src/pinkparrot_read/PinkParrot.Read/PinkParrot.Read.xproj

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>a92b4734-2587-4f6f-97a3-741be48709a5</ProjectGuid>
<RootNamespace>PinkParrot.Read</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

19
src/pinkparrot_read/PinkParrot.Read/Repositories/IModelSchemaRepository.cs

@ -0,0 +1,19 @@
// ==========================================================================
// IModelSchemaRepository.cs
// PinkParrot Headless CMS
// ==========================================================================
// Copyright (c) PinkParrot Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
using System.Threading.Tasks;
using PinkParrot.Read.Models;
namespace PinkParrot.Read.Repositories
{
public interface IModelSchemaRepository
{
Task<List<ModelSchemaRM>> QueryAllAsync();
}
}

42
src/pinkparrot_read/PinkParrot.Read/Repositories/MongoDb/MongoDbModelSchemaRepository.cs

@ -0,0 +1,42 @@
// ==========================================================================
// MongoDbModelSchemaRepository.cs
// PinkParrot Headless CMS
// ==========================================================================
// Copyright (c) PinkParrot Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using PinkParrot.Read.Models;
using PinkParrot.Read.Repositories.MongoDb.Utils;
namespace PinkParrot.Read.Repositories.MongoDb
{
public sealed class MongoDbModelSchemaRepository : BaseRepository<ModelSchemaRM>, IModelSchemaRepository
{
public MongoDbModelSchemaRepository(IMongoDatabase database)
: base(database, "ModelSchemas")
{
CreateIndicesAsync().Wait();
}
private async Task CreateIndicesAsync()
{
await Collection.Indexes.CreateOneAsync(IndexKeys.Ascending(x => x.SchemaId));
}
public IQueryable<ModelSchemaRM> QuerySchemas()
{
return Collection.AsQueryable();
}
public Task<List<ModelSchemaRM>> QueryAllAsync()
{
return Collection.Find(s => true).ToListAsync();
}
}
}

33
src/pinkparrot_read/PinkParrot.Read/Repositories/MongoDb/Utils/BaseRepository.cs

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MongoDB.Driver;
using PinkParrot.Infrastructure;
namespace PinkParrot.Read.Repositories.MongoDb.Utils
{
public abstract class BaseRepository<T>
{
private readonly IMongoCollection<T> collection;
private readonly IndexKeysDefinitionBuilder<T> indexKeys = new IndexKeysDefinitionBuilder<T>();
protected IMongoCollection<T> Collection
{
get { return collection; }
}
protected IndexKeysDefinitionBuilder<T> IndexKeys
{
get { return indexKeys; }
}
protected BaseRepository(IMongoDatabase database, string collectioName)
{
Guard.NotNull(database, nameof(database));
Guard.NotNullOrEmpty(collectioName, nameof(collectioName));
collection = database.GetCollection<T>(collectioName);
}
}
}

27
src/pinkparrot_read/PinkParrot.Read/project.json

@ -0,0 +1,27 @@
{
"version": "1.0.0-*",
"dependencies": {
"MongoDB.Driver": "2.3.0-rc1",
"NETStandard.Library": "1.6.0",
"NodaTime": "2.0.0-alpha20160729",
"PinkParrot.Core": "1.0.0-*",
"PinkParrot.Events": "1.0.0-*",
"PinkParrot.Infrastructure": "1.0.0-*"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
},
"tooling": {
"defaultNamespace": "PinkParrot.Read"
}
}

18
src/pinkparrot_write/PinkParrot.Write/Schema/ISchemaIdProvider.cs

@ -0,0 +1,18 @@
// ==========================================================================
// ISchemaIdProvider.cs
// PinkParrot Headless CMS
// ==========================================================================
// Copyright (c) PinkParrot Group
// All rights reserved.
// ==========================================================================
using System;
using System.Threading.Tasks;
namespace PinkParrot.Write.Schema
{
public interface ISchemaIdProvider
{
Task<Guid> FindSchemaId(string name);
}
}

4
src/pinkparrot_write/PinkParrot.Write/Schema/ModelSchemaDomainObject.cs

@ -199,9 +199,9 @@ namespace PinkParrot.Write.Schema
} }
} }
protected override void ApplyEvent(IEvent @event) protected override void ApplyEvent(Envelope<IEvent> @event)
{ {
this.DispatchAction(@event); this.DispatchAction(@event.Payload);
} }
} }
} }

70
src/pinkparrot_write/PinkParrot.Write/Schema/ModelSchemaNameMap.cs

@ -0,0 +1,70 @@
// ==========================================================================
// ModelSchemaNameMap.cs
// PinkParrot Headless CMS
// ==========================================================================
// Copyright (c) PinkParrot Group
// All rights reserved.
// ==========================================================================
using System;
using System.Collections.Generic;
using PinkParrot.Events.Schema;
using PinkParrot.Infrastructure.CQRS;
using PinkParrot.Infrastructure.CQRS.Events;
using PinkParrot.Infrastructure.Dispatching;
// ReSharper disable InvertIf
namespace PinkParrot.Write.Schema
{
public class ModelSchemaNameMap : DomainObject
{
private readonly Dictionary<string, Guid> schemaIdsByName = new Dictionary<string, Guid>();
private readonly Dictionary<Guid, string> schemaNamesByIds = new Dictionary<Guid, string>();
public ModelSchemaNameMap(Guid id, int version)
: base(id, version)
{
}
protected void On(ModelSchemaDeleted @event, EnvelopeHeaders headers)
{
var aggregateId = headers.AggregateId();
string oldName;
if (schemaNamesByIds.TryGetValue(aggregateId, out oldName))
{
schemaIdsByName.Remove(oldName);
schemaNamesByIds.Remove(aggregateId);
}
}
protected void On(ModelSchemaUpdated @event, EnvelopeHeaders headers)
{
var aggregateId = headers.AggregateId();
string oldName;
if (schemaNamesByIds.TryGetValue(aggregateId, out oldName))
{
schemaIdsByName.Remove(oldName);
schemaIdsByName[@event.NewName] = aggregateId;
}
}
protected void On(ModelSchemaCreated @event, EnvelopeHeaders headers)
{
schemaIdsByName[@event.Name] = headers.AggregateId();
}
public void Apply(Envelope<IEvent> @event)
{
ApplyEvent(@event);
}
protected override void ApplyEvent(Envelope<IEvent> @event)
{
this.DispatchAction(@event.Payload, @event.Headers);
}
}
}
Loading…
Cancel
Save