-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor entity instance and categories service
- Loading branch information
Showing
34 changed files
with
1,702 additions
and
1,765 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
CloudFabric.EAV.Domain/Events/Instance/Entity/EntityInstanceMachineNameUpdated.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using CloudFabric.EAV.Domain.Models; | ||
using CloudFabric.EventSourcing.EventStore; | ||
|
||
namespace CloudFabric.EAV.Domain.Events.Instance.Entity; | ||
|
||
public record EntityInstanceMachineNameUpdated : Event | ||
{ | ||
// ReSharper disable once UnusedMember.Global | ||
// This constructor is required for Event Store to properly deserialize from json | ||
public EntityInstanceMachineNameUpdated() | ||
{ | ||
} | ||
|
||
public EntityInstanceMachineNameUpdated(Guid id, Guid entityConfigurationId, string newMachineName) | ||
{ | ||
EntityConfigurationId = entityConfigurationId; | ||
AggregateId = id; | ||
NewMachineName = newMachineName; | ||
} | ||
|
||
public Guid EntityConfigurationId { get; set; } | ||
|
||
public string NewMachineName { get; set; } | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
namespace CloudFabric.EAV.Domain.Models; | ||
|
||
public class CategoryPath | ||
public record CategoryPath | ||
{ | ||
public Guid TreeId { get; set; } | ||
public string Path { get; set; } | ||
public string? Path { get; set; } | ||
public Guid? ParentId { get; set; } | ||
public string ParentMachineName { get; set; } | ||
public string? ParentMachineName { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,185 @@ | ||
using System.Collections.ObjectModel; | ||
|
||
using CloudFabric.EAV.Domain.Events.Instance.Attribute; | ||
using CloudFabric.EAV.Domain.Events.Instance.Entity; | ||
using CloudFabric.EventSourcing.Domain; | ||
using CloudFabric.EventSourcing.EventStore; | ||
|
||
namespace CloudFabric.EAV.Domain.Models; | ||
|
||
public class EntityInstance : EntityInstanceBase | ||
public class EntityInstance : AggregateBase | ||
{ | ||
/// <summary> | ||
/// For multi-tenant applications this can be used to separate records between tenants. | ||
/// </summary> | ||
public Guid? TenantId { get; protected set; } | ||
|
||
/// <summary> | ||
/// Unique human-readable identifier. Can be used in urls to help with SEO. | ||
/// </summary> | ||
public string? MachineName { get; protected set; } | ||
|
||
public override string PartitionKey => EntityConfigurationId.ToString(); | ||
|
||
/// <summary> | ||
/// An entity instance can belong to many hierarchy trees, this list will contain a record for each hierarchy tree | ||
/// and a place (path) in it. | ||
/// </summary> | ||
public IReadOnlyCollection<CategoryPath> CategoryPaths { get; protected set; } = | ||
new ReadOnlyCollection<CategoryPath>(new List<CategoryPath>()); | ||
|
||
/// <summary> | ||
/// All attributes for this EntityInstance are validated against EntityConfiguration's attributes. | ||
/// </summary> | ||
public Guid EntityConfigurationId { get; protected set; } | ||
|
||
public IReadOnlyCollection<AttributeInstance> Attributes { get; protected set; } = | ||
new ReadOnlyCollection<AttributeInstance>(new List<AttributeInstance>()); | ||
|
||
protected EntityInstance() | ||
{ | ||
} | ||
|
||
public EntityInstance(IEnumerable<IEvent> events) : base(events) | ||
{ | ||
} | ||
|
||
public EntityInstance(Guid id, Guid entityConfigurationId, List<AttributeInstance> attributes, Guid? tenantId) | ||
: base(id, entityConfigurationId, attributes, tenantId) | ||
public EntityInstance( | ||
Guid id, | ||
Guid entityConfigurationId, | ||
List<AttributeInstance> attributes, | ||
string? machineName, | ||
Guid? tenantId, | ||
List<CategoryPath>? categoryPaths | ||
) { | ||
Apply(new EntityInstanceCreated( | ||
id, | ||
entityConfigurationId, | ||
attributes, | ||
machineName, | ||
tenantId, | ||
categoryPaths | ||
)); | ||
} | ||
|
||
public void AddAttributeInstance(AttributeInstance attribute) | ||
{ | ||
Apply(new AttributeInstanceAdded(Id, attribute)); | ||
} | ||
|
||
public void UpdateAttributeInstance(AttributeInstance attribute) | ||
{ | ||
Apply(new AttributeInstanceUpdated(Id, EntityConfigurationId, attribute)); | ||
} | ||
|
||
public void RemoveAttributeInstance(string attributeMachineName) | ||
{ | ||
Apply(new AttributeInstanceRemoved(Id, EntityConfigurationId, attributeMachineName)); | ||
} | ||
|
||
public void UpdateMachineName(string newMachineName) | ||
{ | ||
Apply(new EntityInstanceMachineNameUpdated(Id, EntityConfigurationId, newMachineName)); | ||
} | ||
|
||
/// <summary> | ||
/// Updates the path of this entity inside one of hierarchy trees is belongs to. | ||
/// </summary> | ||
/// <param name="treeId">Id of existing category tree.</param> | ||
/// <param name="categoryPath">Slash-separated path constructed from `machineName`s of parent EntityInstances. | ||
/// Empty for root node. Example: Electronics/Laptops </param> | ||
/// <param name="parentId"></param> | ||
public void UpdateCategoryPath(Guid treeId, string categoryPath, Guid parentId) | ||
{ | ||
Apply(new EntityInstanceCategoryPathUpdated(Id, EntityConfigurationId, treeId, categoryPath, parentId)); | ||
} | ||
|
||
#region Event Handlers | ||
|
||
public void On(EntityInstanceCreated @event) | ||
{ | ||
Id = @event.AggregateId; | ||
EntityConfigurationId = @event.EntityConfigurationId; | ||
Attributes = new List<AttributeInstance>(@event.Attributes).AsReadOnly(); | ||
MachineName = @event.MachineName; | ||
TenantId = @event.TenantId; | ||
CategoryPaths = @event.CategoryPaths ?? new List<CategoryPath>().AsReadOnly(); | ||
} | ||
|
||
public void On(AttributeInstanceAdded @event) | ||
{ | ||
List<AttributeInstance> newCollection = new List<AttributeInstance>(Attributes) { @event.AttributeInstance }; | ||
Attributes = newCollection.AsReadOnly(); | ||
} | ||
|
||
public void On(AttributeInstanceUpdated @event) | ||
{ | ||
AttributeInstance? attribute = Attributes.FirstOrDefault(x => | ||
x.ConfigurationAttributeMachineName == @event.AttributeInstance.ConfigurationAttributeMachineName | ||
); | ||
|
||
if (attribute != null) | ||
{ | ||
var newCollection = new List<AttributeInstance>(Attributes); | ||
|
||
newCollection.Remove(attribute); | ||
newCollection.Add(@event.AttributeInstance); | ||
|
||
Attributes = newCollection.AsReadOnly(); | ||
} | ||
} | ||
|
||
public void On(AttributeInstanceRemoved @event) | ||
{ | ||
AttributeInstance? attribute = Attributes.FirstOrDefault(x => | ||
x.ConfigurationAttributeMachineName == @event.AttributeMachineName | ||
); | ||
|
||
if (attribute != null) | ||
{ | ||
var newCollection = new List<AttributeInstance>(Attributes); | ||
|
||
newCollection.Remove(attribute); | ||
|
||
Attributes = newCollection.AsReadOnly(); | ||
} | ||
} | ||
|
||
public void On(EntityInstanceCategoryPathUpdated @event) | ||
{ | ||
CategoryPath? categoryPath = CategoryPaths.FirstOrDefault(x => x.TreeId == @event.CategoryTreeId); | ||
|
||
var newCollection = new List<CategoryPath>(CategoryPaths); | ||
|
||
if (categoryPath != null) | ||
{ | ||
newCollection.Remove(categoryPath); | ||
} | ||
|
||
var newCategoryPath = categoryPath != null | ||
? categoryPath with | ||
{ | ||
Path = @event.CategoryPath, | ||
ParentMachineName = @event.ParentMachineName, | ||
ParentId = @event.ParentId | ||
} | ||
: new CategoryPath | ||
{ | ||
TreeId = @event.CategoryTreeId, | ||
Path = @event.CategoryPath, | ||
ParentId = @event.ParentId, | ||
ParentMachineName = @event.ParentMachineName | ||
}; | ||
|
||
newCollection.Add(newCategoryPath); | ||
|
||
CategoryPaths = newCollection.AsReadOnly(); | ||
} | ||
|
||
public void On(EntityInstanceMachineNameUpdated @event) | ||
{ | ||
MachineName = @event.NewMachineName; | ||
} | ||
|
||
#endregion | ||
} |
Oops, something went wrong.