当职责链遇到DI

Posted axzxs2001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当职责链遇到DI相关的知识,希望对你有一定的参考价值。

在GitHub上有个项目,本来是作为自己研究学习.net core的Demo,没想到很多同学在看,还给了很多星,所以觉得应该升成3.0,整理一下,写成博分享给学习.net core的同学们。

项目名称:Asp.NetCoreExperiment

项目地址:https://github.com/axzxs2001/Asp.NetCoreExperiment

 

本案例Github代码库

https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/Common/DIChainOfResponsibility

当设计模式中的职责链模式,遇到asp.net core的依赖注入该怎么做呢?

职责链模式是一环套一环,从FirstTask→SecondTask→ThirdTask→EndTask,代码如下

ParentTask是一个父抽象类

 

FirstTask代码

 1    /// <summary>
 2     /// 第一个任务
 3     /// </summary>
 4     public class FirstTask : ITask
 5     {
 6         ITask _task;
 7         readonly ILogger<FirstTask> _logger;
 8         public FirstTask(ILogger<FirstTask> logger, SecondTask secondTask)
 9         {
10             _logger = logger;
11             this.Next(secondTask);
12         }
13         //错误姿势
14         //public FirstTask(ILogger<FirstTask> logger, IEnumerable<ITask> tasks)
15         //{
16         //    _logger = logger;
17         //    foreach (var task in tasks)
18         //    {
19         //        if (task is SecondTask)
20         //        {
21         //            this.Next(task);
22         //        }
23         //    }
24         //}
25 
26         /// <summary>
27         /// 传送下一个方法
28         /// </summary>
29         /// <param name="parentTask"></param>
30         public void Next(ITask task)
31         {
32             Console.WriteLine($"-------------{task.GetType().Name}.Next()");
33             _task = task;
34         }
35         /// <summary>
36         /// 职责链任务方法
37         /// </summary>
38         /// <param name="taskParmeter">任务内容</param>
39         /// <returns></returns>
40         public bool ExecuteTask(TaskParmeter taskParmeter)
41         {
42             var result = SelfTask(taskParmeter);
43             return _task.ExecuteTask(taskParmeter) && result;
44         }
45         bool SelfTask(TaskParmeter taskParmeter)
46         {
47             _logger.LogInformation("-------------------------------------------FirstTask");
48             return true;
49         }
50 }

FirstTask中是链接到SecondTask,同理SecondTask链接到ThirdTask,ThirdTask链接到EndTask,EndTask是个终于,不需要链接到其他任务了

 1     /// <summary>
 2     /// 最后的任务
 3     /// </summary>
 4     public class EndTask : ITask
 5     {       
 6         readonly ILogger<EndTask> _logger;
 7         public EndTask(ILogger<EndTask> logger)
 8         {
 9             _logger = logger;
10         }
11   
12         /// <summary>
13         /// 职责链任务方法
14         /// </summary>
15         /// <param name="taskParmeter">任务内容</param>
16         /// <returns></returns>
17         public bool ExecuteTask(TaskParmeter taskParmeter)
18         {
19             _logger.LogInformation("-------------------------------------------EndTask");
20             return true;
21         }
22 }

依赖注入发生在每个任务的构造函数中的Task,EndTask是结束任务,所以不需要往下传递链任务

在StartUp中,注入必需是实体类,负责在每个任务的构造函数中找不到下一个准确的任务类型,其实可以使用代码中注释为错误姿势的代码试一下。

 1         public void ConfigureServices(IServiceCollection services)
 2         {
 3             //职责链依赖注入
 4             services.AddScoped<EndTask>();
 5             services.AddScoped<ThirdTask>();
 6             services.AddScoped<SecondTask>();
 7             services.AddScoped<FirstTask>();
 8 
 9             //错误姿势
10             //services.AddScoped<ITask,EndTask>();
11             //services.AddScoped<ITask, ThirdTask>();
12             //services.AddScoped<ITask, SecondTask>();
13             //services.AddScoped<ITask, FirstTask>(); 
14        }

在ValuesController中调起第一个任务

 1   public class ValuesController : ControllerBase
 2     {
 3         /// <summary>
 4         /// 第一个任务
 5         /// </summary>
 6         readonly ITask _task;
 7 
 8         public ValuesController(FirstTask firstTask)
 9         {
10             _task = firstTask;
11         }
12         //错误姿势
13         //public ValuesController(IEnumerable<ITask> tasks)
14         //{
15         //    foreach (var task in tasks)
16         //    {
17         //        if (task is EndTask)
18         //        {
19         //            _task = task;
20         //        }
21         //    }
22         //}
23 
24         [HttpGet]
25         public ActionResult<IEnumerable<string>> Get()
26         {
27             //调用第一个任务
28             _task.ExecuteTask(new TaskParmeter() { TaskID = 1 });
29      
30             return new string[] { "value1", "value2" };
31         }
32 }

 

以上是关于当职责链遇到DI的主要内容,如果未能解决你的问题,请参考以下文章

javascript设计模式——职责链模式

用于数据加载的 Android 活动/片段职责

(十五)职责链模式-代码实现

设计模式 之 职责链模式

设计模式——职责链模式

设计模式——职责链模式