Reputation: 1616
I've implemented domain dispatching using a similar pattern here by overriding the SaveChanges
method on my DbContext
. I have entities with domain events that inherit a base abstract class that contains a list of domain events. I now want to enforce that the abstract class to have an Id property of a generic type.
Below is the base entity class before and after:
//BEFORE
public abstract class BaseEntity
{
public List<BaseDomainEvent> Events = new List<BaseDomainEvent>();
}
//AFTER
public abstract class BaseEntity<TId>
{
public virtual TId Id { get; protected set; }
public List<BaseDomainEvent> Events = new List<BaseDomainEvent>();
protected BaseEntity(TId id)
{
Id = id;
}
// EF requires an empty constructor
protected BaseEntity()
{
}
}
On my DbContext.SaveChanges()
I'm having a problem finding entities that have events now that I've changed the BaseEntity
class. Below you will find the code before and after.
//BEFORE
public override int SaveChanges()
{
int result = base.SaveChanges();
// dispatch events only if save was successful
var entitiesWithEvents = ChangeTracker.Entries<BaseEntity>()
.Select(e => e.Entity)
.Where(e => e.Events.Any())
.ToArray();
foreach (var entity in entitiesWithEvents)
{
var events = entity.Events.ToArray();
entity.Events.Clear();
foreach (var domainEvent in events)
{
_dispatcher.Dispatch(domainEvent);
}
}
return result;
}
//AFTER
public override int SaveChanges()
{
int result = base.SaveChanges();
// dispatch events only if save was successful
var entitiesWithEvents = ChangeTracker.Entries<BaseEntity<object>>()
.Select(e => e.Entity)
.Where(e => e.Events.Any())
.ToArray();
foreach (var entity in entitiesWithEvents)
{
var events = entity.Events.ToArray();
entity.Events.Clear();
foreach (var domainEvent in events)
{
_dispatcher.Dispatch(domainEvent);
}
}
return result;
}
I can change ChangeTracker.Entries<BaseEntity<object>>()
to ChangeTracker.Entries<BaseEntity<int>>()
and it works for all entities with the Id of int but not for the ones that may contain a Guid or String as the Id type.
Any help would be appreciated!
Upvotes: 1
Views: 1556
Reputation: 118947
One solution is to keep the original class and inherit from that:
public abstract class BaseEntity
{
public List<BaseDomainEvent> Events = new List<BaseDomainEvent>();
}
public abstract class BaseEntity<TId> : BaseEntity
{
public virtual TId Id { get; protected set; }
protected BaseEntity(TId id)
{
Id = id;
}
// EF requires an empty constructor
protected BaseEntity()
{
}
}
Now you don't need to change the SaveChanges
method.
Upvotes: 2