.NET中多个步骤业务方案的后备方法

发布于 2025-02-01 03:20:52 字数 2087 浏览 2 评论 0原文

我有一个相当简单的应用程序,其中我需要一些简化的传奇模式版本。 这是一种应用程序类型的应用程序,我需要在其中抓住一堆注射的服务,然后对这些服务进行一些操作。 为了简单起见,让我们称这些服务为“步骤”,因此非常类似于一个多步骤的方案,其中每个步骤操作实际上是某些注射服务的方法。 当然很容易。但是我想知道使用后备方法处理一些巧妙的错误处理。 假设我有三种服务和三种方法可以呼吁它们。如果第一个失败,我需要在上面解雇后备方法。如果第二个失败,我需要从第二个拨回后备,然后拨打第一个。如果第三个失败,我需要从第三步中呼叫回退,然后是第二步,最后是第一步。 因此,与微服务世界的传奇模式相似,刚刚在非分布的应用程序中完成。

如下所示,易于使用简单的尝试/捕获块代码。我只是在寻找更聪明的方法来做这件事。关于如何将该代码重构为更易于管理的东西有什么提示?它看起来非常糟糕,尤其是如果它成长为十个步骤的情况。

我玩了WorkFlow-core软件包( https://github.com/danielgergerlag/workflow-core-workflow-core/workflow-core < /a>)以及ELSA工作流( https://elsa-workflows.github.github。 io/elsa-core/),但它们似乎是个过度杀伤。我不想在我的应用程序中进入完全消息或事件驱动的模型。我只需要他们允许您做的那种不错的后备机制即可。

https://dotnetfiddle.net/wrlry1

public class Program
{
    public static void Main()
    {
        var step1 = new Step1();
        var step2 = new Step2();
        var step3 = new Step3();
        
        try
        {
            step1.DoSomethingInStep1();
        }
        catch
        {
            step1.FallbackFromStep1();
        }
        
        try
        {
            step2.DoSomethingInStep2();
        }
        catch
        {
            step2.FallbackFromStep2();
            step1.FallbackFromStep1();
        }
        
        try
        {
            step3.DoSomethingInStep3();
        }
        catch
        {
            step3.FallbackFromStep3();
            step2.FallbackFromStep2();
            step1.FallbackFromStep1();
        }
    }
}

public class Step1
{
    public void DoSomethingInStep1() {} 
    public void FallbackFromStep1() {}
}

public class Step2
{
    public void DoSomethingInStep2() {} 
    public void FallbackFromStep2() {}
}

public class Step3
{
    public void DoSomethingInStep3() {} 
    public void FallbackFromStep3() {}
}

I have a fairly simple app in which I need some simplified version of a saga pattern.
It's a monolith type of app where I need to just grab a bunch of injected services and perform some actions of those services one by one.
For simplicity, let's call those services "steps" so it's pretty much like a multi step scenario where each step action is actually a method on some injected service.
That's easy of course. But I'm wondering about some clever error handling with fallback methods.
So let's say I have three services and three method to call on them. If first one fails, I need to fire a fallback method on it. If the second one fails, I need to call a fallback from the second and then the first one. If the third one fail, I need to call fallback from third step, then second and lastly from the first one.
So something similar to saga pattern of the microservices world, just done in a non-distributed app.

Easy to code with simple try/catch blocks as in example below. I'm just looking for more clever way to do that thing. Any tips about how this piece of code could be refactored into something more manageable? It looks very crappy especially if it grows into something like ten steps scenario.

I played around with the workflow-core package (https://github.com/danielgerlag/workflow-core) as well as the Elsa workflows (https://elsa-workflows.github.io/elsa-core/) but they just seem like an overkill for that. I don't want to go into fully message or event driven model in my app. I just need that nice fallback mechanism that they allow you to do.

https://dotnetfiddle.net/WRLRy1

public class Program
{
    public static void Main()
    {
        var step1 = new Step1();
        var step2 = new Step2();
        var step3 = new Step3();
        
        try
        {
            step1.DoSomethingInStep1();
        }
        catch
        {
            step1.FallbackFromStep1();
        }
        
        try
        {
            step2.DoSomethingInStep2();
        }
        catch
        {
            step2.FallbackFromStep2();
            step1.FallbackFromStep1();
        }
        
        try
        {
            step3.DoSomethingInStep3();
        }
        catch
        {
            step3.FallbackFromStep3();
            step2.FallbackFromStep2();
            step1.FallbackFromStep1();
        }
    }
}

public class Step1
{
    public void DoSomethingInStep1() {} 
    public void FallbackFromStep1() {}
}

public class Step2
{
    public void DoSomethingInStep2() {} 
    public void FallbackFromStep2() {}
}

public class Step3
{
    public void DoSomethingInStep3() {} 
    public void FallbackFromStep3() {}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

呆头 2025-02-08 03:20:52

您可以使用堆栈来节省工作进度所需的所有回滚步骤。出错时,只需在堆栈中运行所有回滚步骤即可。

这是代码 -

    public interface IStep
    {
        public void Do();
        public void Rollback();
    }

    public static class StepHelper
    {
        public static void RunSteps(List<IStep> steps)
        {
            var rollback = new Stack<Action>();

            try
            {
                foreach (var step in steps)
                {
                    rollback.Push(step.Rollback);
                    step.Do();
                }
            }
            catch (Exception ex)
            {
                //handle exception...

                //roll back all changes
                while (rollback.Count > 0)
                {
                    rollback.Pop()();
                }
            }
        }
    }

    public class Step1 : IStep
    {
        public void Do()
        {
            Console.WriteLine("Do step1 ...");
        }

        public void Rollback()
        {
            Console.WriteLine("Roll back step1 ...");
        }

    }
    public class Step2 : IStep
    {
        public void Do()
        {
            Console.WriteLine("Do step2 ...");
        }

        public void Rollback()
        {
            Console.WriteLine("Roll back step2 ...");
        }

    }
    public class Step3 : IStep
    {
        public void Do()
        {
            Console.WriteLine("Do step3 ...");
            throw new Exception("test exception...");
        }

        public void Rollback()
        {
            Console.WriteLine("Roll back step3 ...");
        }

    }

测试运行 -

    StepHelper.RunSteps(new List<IStep>()
    {
        new Step1(),
        new Step2(),
        new Step3()
    });    

You can use a stack to save all the rollback steps needed along the work progress. When it goes wrong, simply run all the rollback steps in the stack.

Here is the code -

    public interface IStep
    {
        public void Do();
        public void Rollback();
    }

    public static class StepHelper
    {
        public static void RunSteps(List<IStep> steps)
        {
            var rollback = new Stack<Action>();

            try
            {
                foreach (var step in steps)
                {
                    rollback.Push(step.Rollback);
                    step.Do();
                }
            }
            catch (Exception ex)
            {
                //handle exception...

                //roll back all changes
                while (rollback.Count > 0)
                {
                    rollback.Pop()();
                }
            }
        }
    }

    public class Step1 : IStep
    {
        public void Do()
        {
            Console.WriteLine("Do step1 ...");
        }

        public void Rollback()
        {
            Console.WriteLine("Roll back step1 ...");
        }

    }
    public class Step2 : IStep
    {
        public void Do()
        {
            Console.WriteLine("Do step2 ...");
        }

        public void Rollback()
        {
            Console.WriteLine("Roll back step2 ...");
        }

    }
    public class Step3 : IStep
    {
        public void Do()
        {
            Console.WriteLine("Do step3 ...");
            throw new Exception("test exception...");
        }

        public void Rollback()
        {
            Console.WriteLine("Roll back step3 ...");
        }

    }

Test run -

    StepHelper.RunSteps(new List<IStep>()
    {
        new Step1(),
        new Step2(),
        new Step3()
    });    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文