gpt4 book ai didi

c# - 架构问题 : use of dependency injection resulting in rubbish API

转载 作者:太空狗 更新时间:2023-10-29 23:18:25 24 4
gpt4 key购买 nike

我正在尝试创建一个类,它执行各种与数据库相关的低级操作,但为 UI 层提供一个非常简单的界面。

此类表示特定聚合根中的一堆数据,由单个 ID int 检索。

构造函数有四个参数:

public AssetRegister(int caseNumber, ILawbaseAssetRepository lawbaseAssetRepository, IAssetChecklistKctcPartRepository assetChecklistKctcPartRepository, User user)
{
_caseNumber = caseNumber;
_lawbaseAssetRepository = lawbaseAssetRepository;
_assetChecklistKctcPartRepository = assetChecklistKctcPartRepository;
_user = user;
LoadChecklists();
}

UI层通过接口(interface)IAssetRegister访问这个类。 CaSTLe Windsor 可以自己提供 ILawbaseAssetRepository 和 IAssetChecklistKctcPartRepository 参数,但 UI 代码需要使用匿名类型提供其他两个参数,如下所示:

int caseNumber = 1000;
User user = GetUserFromPage();
IAssetRegister assetRegister = Moose.Application.WindsorContainer.Resolve<IAssetRegister>(new { caseNumber, user});

从API设计的角度来看,这是垃圾。 UI 层开发人员无法知道 IAssetRegister 需要一个整数和一个用户。他们需要了解类的实现才能使用它。

我知道我这里一定有某种设计问题。谁能给我一些指示?

最佳答案

尝试将消息与行为分开。创建一个类来保存操作的数据,并创建一个不同的类来包含该操作的业务逻辑。例如,创建这个命令:

public class RegisterAssetCommand
{
[Required]
public int CaseNumber { get; set; }

[Required]
public User Operator { get; set; }
}

现在定义一个接口(interface)来处理业务命令:

public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}

您的演示代码现在将如下所示:

var command = new RegisterAssetCommand
{
CaseNumber = 1000,
Operator = GetUserFromPage(),
};

var commandHandler = WindsorContainer
.Resolve<ICommandHandler<RegisterAssetCommand>);

commandHandler.Handle(command);

注意: 如果可能,转移获得 commandHandler 的责任从表示类中取出并将其注入(inject)该类的构造函数(再次构造函数注入(inject))。

不,您可以创建 ICommandHandler<RegisterAssetCommand> 的实现像这样:

public class RegisterAssetCommandHandler
: ICommandHandler<RegisterAssetCommand>
{
private ILawbaseAssetRepository lawbaseAssetRepository;
private IAssetChecklistKctcPartRepository assetRepository;

public RegisterAssetCommandHandler(
ILawbaseAssetRepository lawbaseAssetRepository,
IAssetChecklistKctcPartRepository assetRepository)
{
this.lawbaseAssetRepository = lawbaseAssetRepository;
this.assetRepository = assetRepository;
}

public void Handle(RegisterAssetCommand command)
{
// Optionally validate the command

// Execute the command
}
}

您甚至可以选择保留 User来自 RegisterAssetCommand通过注入(inject) IUserProviderRegisterAssetCommandHandler . IUserProvider接口(interface)可以有一个 GetUserForCurrentContext处理程序可以调用。

我希望这是有道理的。

关于c# - 架构问题 : use of dependency injection resulting in rubbish API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5272094/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com