首页 技术 正文
技术 2022年11月18日
0 收藏 990 点赞 2,302 浏览 6363 个字

要求:修改good表,添加 organization

基础定义

用于引发和调度事件的延迟方法 AddDomainEvent

Domain\SeedWork\Entity.cs

public abstract class Entity<T>
{
int? _requestedHashCode;
T _Id;
public virtual T Id
{
get
{
return _Id;
}
protected set
{
_Id = value;
}
} private List<INotification> _domainEvents;
public IReadOnlyCollection<INotification> DomainEvents => _domainEvents?.AsReadOnly(); public void AddDomainEvent(INotification eventItem)
{
_domainEvents = _domainEvents ?? new List<INotification>();
_domainEvents.Add(eventItem);
} public void RemoveDomainEvent(INotification eventItem)
{
_domainEvents?.Remove(eventItem);
} public void ClearDomainEvents()
{
_domainEvents?.Clear();
} public bool IsTransient()
{
return Id.ToString() == default(T).ToString();
} public override bool Equals(object obj)
{
if (obj == null || !(obj is Entity<T>))
return false; if (Object.ReferenceEquals(this, obj))
return true; if (this.GetType() != obj.GetType())
return false; Entity<T> item = (Entity<T>)obj; if (item.IsTransient() || this.IsTransient())
return false;
else
return item.Id.ToString() == this.Id.ToString();
} public override int GetHashCode()
{
if (!IsTransient())
{
if (!_requestedHashCode.HasValue)
_requestedHashCode = this.Id.GetHashCode() ^ 31; // XOR for random distribution (http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) return _requestedHashCode.Value;
}
else
return base.GetHashCode(); }
public static bool operator ==(Entity<T> left, Entity<T> right)
{
if (Object.Equals(left, null))
return (Object.Equals(right, null)) ? true : false;
else
return left.Equals(right);
} public static bool operator !=(Entity<T> left, Entity<T> right)
{
return !(left == right);
}
}

聚合根

Goods.cs

  public class Goods: Entity<Guid>, IAggregateRoot
{ public string CreatedBy { get; private set; }
public DateTime? CreatedTime { get; private set; } public string ModifiedBy { get; private set; } public DateTime? ModifiedTime { get; private set; } public string GoodsName { get; private set; }
public int? GoodsNum { get; private set; } public Goods(string createdBy, DateTime? createdTime, string modifiedBy, DateTime? modifiedTime, string goodsName, int? goodsNum)
{
CreatedBy = createdBy;
CreatedTime = createdTime;
ModifiedBy = modifiedBy;
ModifiedTime = modifiedTime;
GoodsName = goodsName;
GoodsNum = goodsNum;
} public void StockAddedToGoods()
{
AddDomainEvent(new StockAddedToGoodsDomainEvent()); //加入事件列表
} public void SetModified()
{
ModifiedBy = "aaaaa";
ModifiedTime = DateTime.Now;
}
}

请注意 AddDomainEvent 方法的唯一功能是将事件添加到列表。 尚未调度任何事件,尚未调用任何事件处理程序。

你需要在稍后将事务提交到数据库时调度事件。 如果使用 Entity Framework Core,意味着在 EF DbContext 的 SaveChanges 方法中,如以下示例所示:

// EF Core DbContext
public class SampleContext : DbContext, IUnitOfWork
{
// ...
public async Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
// Dispatch Domain Events collection.
// Choices:
// A) Right BEFORE committing data (EF SaveChanges) into the DB. This makes
// a single transaction including side effects from the domain event
// handlers that are using the same DbContext with Scope lifetime
// B) Right AFTER committing data (EF SaveChanges) into the DB. This makes
// multiple transactions. You will need to handle eventual consistency and
// compensatory actions in case of failures.
await _mediator.DispatchDomainEventsAsync(this); // After this line runs, all the changes (from the Command Handler and Domain
// event handlers) performed through the DbContext will be committed
var result = await base.SaveChangesAsync();
}

}

Organization.cs

    public class Organization:
Entity<Guid>, IAggregateRoot
{
public string CreatedBy { get; set; }
public DateTime CreatedTime { get; set; }
public string ModifiedBy { get; set; }
public DateTime ModifiedTime { get; set; } public string Name { get; set; } private Organization() { } public Organization(Guid id, string name, string createdBy, DateTime createdTime, string modifiedBy,DateTime modifiedTime)
{
Id = id;
Name = name;
CreatedBy = createdBy;
ModifiedBy = modifiedBy;
ModifiedTime = modifiedTime; AddDomainEvent(new OrganizationCreatedDomainEvent(name, id));
} }

CQRS

1.创建命令

    [DataContract]
public class UpdateGoodsAndAddStockCommand : IRequest<bool>
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public string CreatedBy { get; private set; } [DataMember]
public string GoodsName { get; private set; }
[DataMember]
public int GoodsNum { get; private set; }
}

2.创建处理

    public class UpdateGoodsAndAddStockCommandHandler: IRequestHandler<UpdateGoodsAndAddStockCommand, bool>
{
private readonly IGoodsRepository _goodsRepository;
private readonly IMediator _mediator; public UpdateGoodsAndAddStockCommandHandler(IGoodsRepository goodsRepository, IMediator mediator)
{
_goodsRepository = goodsRepository;
_mediator = mediator;
} public async Task<bool> Handle(UpdateGoodsAndAddStockCommand request, CancellationToken cancellationToken)
{
var good = await _goodsRepository.GetAsync(request.Id); good.SetModified(); //赋值修改人和修改时间,
good.StockAddedToGoods(); //添加 Stock 事件
return await _goodsRepository.UnitOfWork.SaveEntitiesAsync();
}
}

3.使用 IoC 的域事件调度程序

public class MediatorModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly)
.AsImplementedInterfaces(); // Register all the Command classes (they implement IRequestHandler) in assembly holding the Commands
builder.RegisterAssemblyTypes(typeof(CreateOrderCommand).GetTypeInfo().Assembly)
.AsClosedTypesOf(typeof(IRequestHandler<,>)); //这里
builder.RegisterAssemblyTypes(typeof(UpdateGoodsAndAddStockCommand).GetTypeInfo().Assembly)
.AsClosedTypesOf(typeof(IRequestHandler<,>)) // Other registrations ...
}
}

事件列表

Sample.Domain\Event\StockAddedToGoodsDomainEvent.cs

   public class StockAddedToGoodsDomainEvent: INotification
{
public Organization Organization { get; } public StockAddedToGoodsDomainEvent()
{
Organization = new Organization(Guid.NewGuid(), "tss","tss", DateTime.Now,null,DateTime.Now);
}
}

事件处理:StockAddedToGoodsDomainEventHandler

    public class StockAddedToGoodsDomainEventHandler : INotificationHandler<StockAddedToGoodsDomainEvent>
{
private readonly IOrganizationRepository _iorganizationRepository;
private readonly ILoggerFactory _logger;
private readonly ISampleIntegrationEventService _sampleIntegrationEventService; public StockAddedToGoodsDomainEventHandler(IOrganizationRepository iorganizationRepository, ILoggerFactory logger)
{
_iorganizationRepository = iorganizationRepository;
_logger = logger;
} public async Task Handle(Domain.Events.StockAddedToGoodsDomainEvent notification, CancellationToken cancellationToken)
{
_iorganizationRepository.Add(notification.Organization); var organization = await _iorganizationRepository.GetAsync(notification.Organization.Id);
await _iorganizationRepository.UnitOfWork.SaveEntitiesAsync();
_logger.CreateLogger(nameof(StockAddedToGoodsDomainEventHandler))
.LogTrace($"Stock with Id: {organization.Id} has been successfully Created");
}
}

资料:

microsoft.doc 域事件:设计和实现

微软的官方.NET CORE微服务示例eShopOnContainers

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,027
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,518
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,365
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,146
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,780
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,857