This is a standard Cqrs issue. Look up set based validation on Greg youngs site.
Also, why two IDs? It doesn't sound right.
--
Le doute n'est pas une condition agréable, mais la certitude est absurde.
You already have one
On Thu, Dec 1, 2011 at 4:49 AM, Henrik Olsson <u.henri...@live.se> wrote:
> How do I make the key of the aggregate natural with ncqrs?
--
namespace Test.Domain { #region Root and Entity Classes /// <summary> /// JsonObject is required to mitigate the self referencing loop error from Newtonsoft JSON serializer /// Since we are referencing an Entity /// </summary> [JsonObject(IsReference = true)] public class TestAr : AggregateRootMappedWithExpressions, ISnapshotable<TestAr>
{
[NonSerialized] private List<TestEntity> _entities = new List<TestEntity>();
[AggregateRootId]
public Guid TestArId { get; set; }
public string TestArData { get; set; }
public DateTime CreatedonUtc { get; set; }
public DateTime ModifiedOnUtc { get; set; }
//Entities
public List<TestEntity> TestEntities
{
get { return _entities; }
set { _entities = value; }
}
#region Constructors
public TestAr()
{
IsArCreated();
EventApplied += ArEventApplied;
}
public TestAr(Guid testarid, string testardata)
: this(testarid)
{
CreateTestAr(testarid, testardata);
}
private TestAr(Guid testarid)
: base(testarid)
{
TestArId = testarid;
EventApplied += ArEventApplied;
}
#endregion
#region Private Methods
/// <summary>
/// Fired after NCQRS events are applied
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Can be used to fire subsequent commands/events
/// Pumped from the <see cref="IEventHandler{TEvent}"/> event queue on the <see cref="IPublishedEvent{TEvent}"/> bus
/// </remarks>
private static void ArEventApplied(object sender, EventAppliedEventArgs e)
{
//Display the event
Console.WriteLine(e.Event);
}
/// <summary>
/// Validated that the business AR id exists for use
/// </summary>
private void IsArCreated()
{
if (EventSourceId.Equals(Guid.Empty))
{
throw new CoreException(
"The Test AR has not been created and no operations can be executed on it").
GetException<ApplicationException>();
}
}
#endregion
public override void InitializeEventHandlers()
{
Map<TestArCreated>().ToHandler(OnTestArCreated);
Map<TestArChanged>().ToHandler(OnTestArChanged);
Map<TestEntityCreated>().ToHandler(OnTestEntityCreated);
}
#region Snapshot
public TestAr CreateSnapshot()
{
return this;
}
public void RestoreFromSnapshot(TestAr snapshot)
{
TestArData = snapshot.TestArData;
CreatedonUtc = snapshot.CreatedonUtc;
ModifiedOnUtc = snapshot.ModifiedOnUtc;
foreach (var entity in snapshot.TestEntities)
entity.SetParent(this);
TestEntities = snapshot.TestEntities;
}
#endregion
#region CQRS Commands and Events
protected void CreateTestAr(Guid testarid, string testardata)
{
var clock = NcqrsEnvironment.Get<IClock>();
var e = new TestArCreated
{
TestArData = testardata,
CreatedonUtc = clock.UtcNow()
};
ApplyEvent(e);
}
protected void OnTestArCreated(TestArCreated e)
{
TestArData = e.TestArData;
CreatedonUtc = e.CreatedonUtc;
}
protected void ChangeTestAr(string testardata)
{
var clock = NcqrsEnvironment.Get<IClock>();
var e = new TestArChanged
{
TestArData = testardata,
ModifiedonUtc = clock.UtcNow()
};
ApplyEvent(e);
}
protected void OnTestArChanged(TestArChanged e)
{
TestArData = e.TestArData;
ModifiedOnUtc = e.ModifiedonUtc;
}
protected void CreateTestEntity(Guid testentityid, string entitydata)
{
var clock = NcqrsEnvironment.Get<IClock>();
var e = new TestEntityCreated
{
TestEntityId = testentityid,
EntityData = entitydata,
CreatedonUtc = clock.UtcNow()
};
ApplyEvent(e);
}
protected void OnTestEntityCreated(TestEntityCreated e)
{
var o = new TestEntity(this, e.TestEntityId);
TestEntities.Add(o);
}
protected void ChangeTestEntity(Guid testentityid, string entitydata)
{
var o = TestEntities.First(x => x.EntityId == testentityid);
o.ChangeTestEntity(entitydata);
}
#endregion
}
/// <summary>
/// Test Entity Class
/// </summary>
public class TestEntity : EntityMappedByConvention
{
public string EntityData { get; set; }
public DateTime CreatedOnUtc { get; set; }
public DateTime ModifiedOnUtc { get; set; }
public TestEntity(AggregateRoot parent, Guid entityId)
: base(parent, entityId)
{
}
/// <summary>
/// Used to establish the event handlers from the parent AR
/// when restored from a snapshot
/// </summary>
/// <param name="parent"></param>
public void SetParent(AggregateRoot parent)
{
ParentAggregateRoot = parent;
SetParentHandlers(parent);
}
public void ChangeTestEntity(string entitydata)
{
var clock = NcqrsEnvironment.Get<IClock>();
var e = new TestEntityChanged
{
EntityData = entitydata,
ModifiedOnUtc = clock.UtcNow()
};
ApplyEvent(e);
}
protected void OnTestEntityChanged(TestEntityChanged e)
{
EntityData = e.EntityData;
ModifiedOnUtc = e.ModifiedOnUtc;
}
}
#endregion
#region Command and Event Classes
[MapsToAggregateRootConstructor(typeof (TestAr))]
public class CreateTestAr : CommandBase
{
public Guid TestArId { get; set; }
public string TestArData { get; set; }
}
[Serializable]
public class TestArCreated
{
public string TestArData { get; set; }
public DateTime CreatedonUtc { get; set; }
}
[MapsToAggregateRootMethod(typeof (TestAr), "ChangeTestAr")]
public class ChangeTestAr : CommandBase
{
[AggregateRootId]
public Guid TestArId { get; set; }
public string TestArData { get; set; }
}
[Serializable]
public class TestArChanged
{
public string TestArData { get; set; }
public DateTime ModifiedonUtc { get; set; }
}
[MapsToAggregateRootMethod(typeof (TestAr), "CreateTestEntity")]
public class CreateTestEntity : CommandBase
{
[AggregateRootId]
public Guid TestArId { get; set; }
public Guid TestEntityId { get; set; }
public string EntityData { get; set; }
}
[Serializable]
public class TestEntityCreated
{
public Guid TestEntityId { get; set; }
public string EntityData { get; set; }
public DateTime CreatedonUtc { get; set; }
}
[MapsToAggregateRootMethod(typeof (TestAr), "ChangeTestEntity")]
public class ChangeTestEntity : CommandBase
{
[AggregateRootId]
public Guid TestArId { get; set; }
public Guid TestEntityId { get; set; }
public string EntityData { get; set; }
}
[Serializable]
public class TestEntityChanged : EntitySourcedEventBase
{
public string EntityData { get; set; }
public DateTime ModifiedOnUtc { get; set; }
}
#endregion
}