65.9K
CodeProject 正在变化。 阅读更多。
Home

[TinyERP:企业应用的单页应用程序]跨模块/域通信

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2018年11月27日

Apache

3分钟阅读

viewsIcon

7084

[TinyERP:企业应用的单页应用程序]跨模块/域通信

概述

请确保您已阅读概述(配置和运行hello示例),检索员工列表(第一部分 & 第二部分)和创建新员工

如前文所述,整个项目将被拆分成多个较小的模块/域。这带来了一个新问题:“这些模块/域如何相互通信”,因为一些业务流程跨越多个模块。让我们更详细地研究一下如何解决这个问题。

注意:在本系列文章中,模块和域可以互换使用,但一个模块可以包含多个作为单体应用程序运行的域。因此,您可以以类似的方式同时应用模块和域的规则。

让我们来看一下这个场景:有了新的需求,我们希望我们的员工登录系统,这意味着系统应该在“创建新员工”的过程中创建一个新的登录帐户。

并且此登录功能将来可以重复用于其他方面,例如客户……

更新“添加新员工”功能

让我们在“添加新员工”屏幕中添加两个字段:电子邮件和密码。

我们还需要更新StaffHandler,更改CreateStaffRequest如下:

public class CreateStaffRequest : IBaseCommand
{
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public string Email { get; set; }
	public string Password { get; set; }
	public CreateStaffRequest(string firstName, string lastName, string email, string password)
	{
		this.FirstName = firstName;
		this.LastName = lastName;
		this.Email = email;
		this.Password = password;
	}
}

让我们更新StaffCommandHandler类中的Handle(CreateStaffRequest request)

public CreateStaffResponse Handle(CreateStaffRequest command)
{
	this.Validate(command);
	IAccountFacade accountFacade = IoC.Container.Resolve<IAccountFacade>();
	using (IUnitOfWork uow = this.CreateUnitOfWork<TinyERP.HRM.Aggregate.Staff>()) {
		CreateAccountRequest createAccountRequest = new CreateAccountRequest
        (command.FirstName, command.LastName, command.Email, command.Password, command.Password);
		createAccountRequest.Roles.Add(new Role(SecurityRoleType.Administrator, 
        SecurityRoleType.Administrator, SecurityRoleType.Administrator, Modules.All, 
        TinyERP.Common.ItemStatus.Active));
		CreateAccountResponse createAccountResponse = 
                         accountFacade.CreateAccount(createAccountRequest);
		TinyERP.HRM.Aggregate.Staff staff = new Aggregate.Staff();
		staff.UpdateBasicInfo(command);
		staff.UpdateAccount(createAccountResponse.AccountId);
		IStaffRepository repository = IoC.Container.Resolve<IStaffRepository>(uow);
		repository.Add(staff);
		uow.Commit();
		staff.PublishEvents();
		return ObjectHelper.Cast<CreateStaffResponse>(staff);
	}
}

在第4、6、7、8行进行少量更改。我们调用安全模块,使用来自“CreateStaffRequest”的信息创建一个新的登录帐户。

然后,此帐户的引用将作为员工聚合的部分信息进行更新。参见第11行。

我们可以看到,“创建新帐户”和“创建新员工”不在同一个事务中。我们将在“Saga模式”中再次讨论这个问题。

对于TinyERP.Security包,请从nuget包管理器安装它。有关更多信息,请参见TinyERP.Security (https://nuget.net.cn/packages/TinyERP.Security/)。

检查TinyERP.HRM项目的引用部分。我们还可以看到添加了许多子项目。

安全模块作为微服务实现,并使用CQRS模式来构建高性能系统。

系统可能会抛出一些异常,现在先忽略它们。我们将在将来修复它们。我们现在需要做的是提供TinyERP.Security的连接字符串,如上所述。这是使用CQRS实现的,因此我们需要配置读写数据库(MSSQL和MongoDB),将以下配置添加到“configuration.debug.config\aggregates”部分。

<add name="TinyERP.Security.Share.Context.ISecurityQueryDbContext" 
repoType="MongoDb" connectionStringName="DefaultMongoDb"></add>
<add name="TinyERP.Security.Share.Context.ISecurityDbContext" 
repoType="MSSQL" connectionStringName="DefaultMSSQL"></add>

此配置文件的结果类似于:

<aggregates>
	<add name="TinyERP.HRM.Context.IHRMQueryContext" repoType="MongoDb" 
connectionStringName="DefaultMongoDb"></add>
	<add name="TinyERP.HRM.Context.IHRMContext" repoType="MSSQL" 
connectionStringName="DefaultMSSQL"></add>

	<add name="TinyERP.Security.Share.Context.ISecurityQueryDbContext" 
repoType="MongoDb" connectionStringName="DefaultMongoDb"></add>
	<add name="TinyERP.Security.Share.Context.ISecurityDbContext" 
repoType="MSSQL" connectionStringName="DefaultMSSQL"></add>
</aggregates>

请注意并输入repoType的正确值,目前,值可以是“MSSQL”或“MongoDb”中的1。我们以后可以支持更多存储库,例如:RavenDb、ElasticSearch、Json文件、Azure Blob……

ISecurityQueryDbContextISecurityDbContext分别用作读写上下文到相应的数据库。

我们还将TinyERP.Security包安装到TinyERP.Api中。

让我们再次编译并运行应用程序。UI看起来像这样:

请不要担心缺少“确认密码”字段。目前这并不重要。

点击保存并返回“员工”页面。

这与前一部分相同。让我们检查MSSQL数据库,有两个名为App_Security_User_RolesApp_Security_Users的新表。

这些是由TinyERP.Security自动生成的,打开这些表,我们有:

有两个用户:

  • contact@tranthanhtu.vn是由系统创建的,此用户附加了许多角色。查看所有userId为“ECB06DF4-CC65-4134-9E44-EC1AFC9EF3EF”的角色。
  • tu.tran@email.com:这是刚刚创建的新登录帐户。

在mongodb中,打开AccountSummary,我们有:

我们可以看到,mongodb(读取端)中的AccountSummary记录包含与帐户相关的所有必要信息。因此,将来我们不需要连接表来获取此信息,这也提高了系统的性能。

企业应用程序开发有一些注意事项:

  • 应用程序应划分为较小的模块/域。
  • 每个模块/域应具有单一用途。
  • 每个模块/域将管理其行为/数据,并且应与其他模块/域隔离。
  • 每个模块/域应通过单个公共接口访问其他模块/域中的数据。

有关此部分源代码的更多信息,请查看https://github.com/tranthanhtu0vn/TinyERP(在feature/module_communication分支)。

感谢阅读!

© . All rights reserved.