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





5.00/5 (1投票)
[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……
ISecurityQueryDbContext
和ISecurityDbContext
分别用作读写上下文到相应的数据库。
我们还将TinyERP.Security
包安装到TinyERP.Api
中。
让我们再次编译并运行应用程序。UI看起来像这样:
请不要担心缺少“确认密码”字段。目前这并不重要。
点击保存并返回“员工”页面。
这与前一部分相同。让我们检查MSSQL数据库,有两个名为App_Security_User_Roles
和App_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分支)。
感谢阅读!