首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在应用层抽象DTF框架?

如何在应用层抽象DTF框架?
EN

Stack Overflow用户
提问于 2021-11-24 15:10:13
回答 5查看 274关注 0票数 1

我有一个关于清洁架构和持久任务框架的问题。但首先,让我举个例子向你们展示我们可以用DTF做些什么。DTF使我们能够在后台运行单个任务的工作流/编排。下面是一个示例:

代码语言:javascript
复制
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将各个任务连接到一个工作流中。下面是如何定义任务:

代码语言:javascript
复制
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中创建一个工作人员并注册所有任务和编排:

代码语言:javascript
复制
TaskHubWorker hubWorker = new TaskHubWorker("myvideohub", "connectionDetails")
    .AddTaskOrchestrations(typeof (EncodeVideoOrchestration))
    .AddTaskActivities(typeof (EncodeActivity), typeof (EmailActivity))
    .Start();

使用DTF客户端,您实际上可以触发一个业务流程:

代码语言:javascript
复制
TaskHubClient client = new TaskHubClient("myvideohub", "connectionDetails");
client.CreateOrchestrationInstance(typeof (EncodeVideoOrchestration), "http://<azurebloblocation>/MyVideo.mpg");

DTF处理背景中的所有魔术,可以使用不同的存储解决方案,例如服务总线,甚至mssql。

假设我们的应用程序被组织成这样的文件夹:

  • 域名
  • 应用程序
  • 基础设施
  • 用户界面

在任务中,我们运行应用程序逻辑/用例。但DTF框架本身就是基础设施,对吗?如果是这样,那么DTF框架的抽象在应用层中会是什么样的呢?是否有可能使应用层不知道DTF?

EN

回答 5

Stack Overflow用户

发布于 2021-11-29 20:36:00

关于清洁架构方法,如果您想摆脱Application层中的DTF,可以执行以下操作(原始回购使用MediatR,所以我也这么做了)

  • TaskActivity实现为query/command,并将其放入Application
代码语言:javascript
复制
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;
    }
}
  • 实现实际的DTF类(我发现它们支持异步)并将它们放入"UI“层。这里没有UI,但从技术上讲,它是一个控制台应用程序。
代码语言:javascript
复制
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));
    }
}
票数 1
EN

Stack Overflow用户

发布于 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/api/system.configuration.configuration?view=dotnet-plat-ext-6.0

接下来,您需要动态加载程序集,您可以在这里了解如何动态加载程序集( 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?

是的,就像任何能够支持插件/扩展/代理的语言一样

票数 1
EN

Stack Overflow用户

发布于 2021-12-04 12:01:50

您必须将您的实现与无处不在的语言相匹配。在具体的例子中:编码是谁和何时发生的?无论哪个实体或服务(客户机)执行编码,只需调用一个IEncode.encode接口,该接口将处理调用DTF所涉及的“细节”。

是的,DTF的定义在基础设施中,它应该像在基础结构中的其他所有东西一样处理,比如日志记录或通知。也就是说:功能应该放在可以注入域并由其域客户端使用的接口后面。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70098490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档