我有一个关于清洁架构和持久任务框架的问题。但首先,让我举个例子向你们展示我们可以用DTF做些什么。DTF使我们能够在后台运行单个任务的工作流/编排。下面是一个示例:
public class EncodeVideoOrchestration : TaskOrchestration<string, string>
{
public override async Task<string> RunTask(OrchestrationContext context, string input)
{
string encodedUrl = await context.ScheduleTask<string>(typeof (EncodeActivity), input);
await context.ScheduleTask<object>(typeof (EmailActivity), input);
return encodedUrl;
}
}TaskOrchestration将各个任务连接到一个工作流中。下面是如何定义任务:
public class EncodeActivity : TaskActivity<string, string>
{
protected override string Execute(TaskContext context, string input)
{
Console.WriteLine("Encoding video " + input);
// TODO : actually encode the video to a destination
return "http://<azurebloblocation>/encoded_video.avi";
}
}
public class EmailActivity : TaskActivity<string, object>
{
protected override object Execute(TaskContext context, string input)
{
// TODO : actually send email to user
return null;
}
}挺直的,对吧?然后在Program.cs中创建一个工作人员并注册所有任务和编排:
TaskHubWorker hubWorker = new TaskHubWorker("myvideohub", "connectionDetails")
.AddTaskOrchestrations(typeof (EncodeVideoOrchestration))
.AddTaskActivities(typeof (EncodeActivity), typeof (EmailActivity))
.Start();使用DTF客户端,您实际上可以触发一个业务流程:
TaskHubClient client = new TaskHubClient("myvideohub", "connectionDetails");
client.CreateOrchestrationInstance(typeof (EncodeVideoOrchestration), "http://<azurebloblocation>/MyVideo.mpg");DTF处理背景中的所有魔术,可以使用不同的存储解决方案,例如服务总线,甚至mssql。
假设我们的应用程序被组织成这样的文件夹:
在任务中,我们运行应用程序逻辑/用例。但DTF框架本身就是基础设施,对吗?如果是这样,那么DTF框架的抽象在应用层中会是什么样的呢?是否有可能使应用层不知道DTF?
发布于 2021-11-29 20:36:00
关于清洁架构方法,如果您想摆脱Application层中的DTF,可以执行以下操作(原始回购使用MediatR,所以我也这么做了)
TaskActivity实现为query/command,并将其放入Application层using MediatR;
public class EncodeVideoQuery : IRequest<string>
{
// TODO: ctor
public string Url { get; set; }
}
public class EncodeHandler : IRequestHandler<EncodeVideoQuery, string>
{
public async Task<string> Handle(EncodeVideoQuery input, CancellationToken cancel)
{
Console.WriteLine("Encoding video " + input);
// TODO : actually encode the video to a destination
return "http://<azurebloblocation>/encoded_video.avi";
}
}
public class EmailCommand
{
public string UserEmail { get; set; }
}
public class EmailCommandHandler : IRequestHandler<EmailCommand>
{
public async Task<Unit> Handle(EmailCommand input, CancellationToken cancel)
{
// TODO : actually send email to user
return Unit.Value;
}
}using MediatR;
public class EncodeActivity : TaskActivity<string, string>
{
private readonly ISender mediator;
public EncodeActivity(ISender mediator)
{
this.mediator = mediator;
}
protected override Task<string> ExecuteAsync(TaskContext context, string input)
{
// Perhaps no ability to pass a CancellationToken
return mediator.Send(new EncodeVideoQuery(input));
}
}发布于 2021-12-04 00:58:48
我认为您的问题不仅仅是关于代码的一个问题,而是对如何使主程序“不知道”您将要使用的特定DTF库的整个概念的要求。
好吧,它涉及到您需要使用的几个功能领域来完成这一任务。我添加了一个图表,说明架构应该如何实现您的要求,但是我并没有关注语法,因为问题是关于体系结构的,而不是我所理解的代码本身,所以把它当作一个伪代码--它只是为了传递这个概念。
关键思想是,您必须读取希望从配置文件(如app.config)加载的DLL的路径或名称,但要做到这一点,您需要了解如何在配置文件中创建自定义配置元素。您可以在链接中看到这些内容:
https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/
接下来,您需要动态加载程序集,您可以在这里了解如何动态加载程序集( https://learn.microsoft.com/en-us/dotnet/framework/app-domains/how-to-load-assemblies-into-an-application-domain )。
传递之后,请记住,您正在加载的DLL仍然是您需要实现的东西,它需要知道您希望引用的特定DTF库,但是它也实现了应用程序中众所周知的接口。
因此,基本上,您将有一个接口来描述您的程序从DTF库(任何DTF库)中需要的抽象,以及您将在运行时加载的代理DLL,它将充当描述该抽象的接口与特定DTF库的实际实现之间的中介。
所以,根据你的问题:
在应用层中,DTF框架的抽象会是什么样的呢?
看看我提供的图表。
是否有可能使应用层不知道DTF?
是的,就像任何能够支持插件/扩展/代理的语言一样

发布于 2021-12-04 12:01:50
您必须将您的实现与无处不在的语言相匹配。在具体的例子中:编码是谁和何时发生的?无论哪个实体或服务(客户机)执行编码,只需调用一个IEncode.encode接口,该接口将处理调用DTF所涉及的“细节”。
是的,DTF的定义在基础设施中,它应该像在基础结构中的其他所有东西一样处理,比如日志记录或通知。也就是说:功能应该放在可以注入域并由其域客户端使用的接口后面。
https://stackoverflow.com/questions/70098490
复制相似问题