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. 42
      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());
} }
} }
} }

42
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();
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. containerBuilder.RegisterType<AutofacDomainObjectFactory>()
.As<IDomainObjectFactory>()
.SingleInstance();
containerBuilder.RegisterType<InMemoryCommandBus>()
.As<ICommandBus>()
.SingleInstance();
container = containerBuilder.Build();
return new AutofacServiceProvider(container);
}
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