.NET框架设计(高级框架架构模式)—钝化程序、逻辑冻结、冻结程序的延续、瞬间转移

简介:

阅读目录:

  • 1.开篇介绍

  • 2.程序书签(代码书签机制)

    • 2.1ProgramBookmark 实现(使用委托来锚点代码书签)

    • 2.2ProgramBookmarkManager书签管理器(对象化书签集合的处理,IEnumerable<T>书签管理)


  • 3.可恢复语句组件(将语句对象化)

    • 3.1可恢复语句组件管理器(将可恢复语句视为普通的对象成员,IEnumerable<T>可恢复语句组件)

    • 3.2可恢复语句组件运行时(Program CLR(简介))

    • 3.3可恢复语句逻辑配置(规则的配置(简介))

    • 3.4可恢复语句逻辑传输(将逻辑语句对象远程传输(简介))


  • 4.DomainModel规则引擎(规则持久化后管理配置(简介))

1】开篇介绍

这一篇文章我早准备写的,迟迟未写的原因是它过于抽象不太容易表达,也很难掌握;之前对它的理解还处于比较简单的功能性上,但是最近随着对领域驱动设计及架构的研究,设计思想有了一个提升对它的理解也有了一个更清晰的轮廓,所以才敢下手去写,这么好的一篇文章不能搞砸了;

“钝化语句” 简单描述:将基于栈的调用抽象成基于我们自己构建的虚拟运行时调用;

比如我们可以将普通的IF\ELSE调用进行对象化,然后就可以对他们进行面向对象的设计了;能做的事情就太多了,比如将所有的方法放入一个for循环语句组件当中去,它会自动的去循环执行,而不需要我们再去自己写for语句;然后在此基础上进行代码书签抽象对所有的代码片段进行类似逻辑锚点的设定;

更吓人的是可以瞬间将语句组件钝化,其实也就是瞬间冻结然后持久化,在遥远的地方再将它唤醒执行,很可能你的语句在你这台电脑上执行了一半由于你临时有事然后语句被钝化,在另外一台电脑上继续你的工作,是不是很方便;当然它的使用方式多种多样了;

我相信这篇文章绝对让你对 .NET框架设计 感兴趣,框架设计思想其实真的很美,让人陶醉;

2】程序书签(代码书签机制)

美好的一切都要有一个良性的开始,程序的钝化少不了对程序的逻辑保存的功能;有一个连续的调用穿过N个方法,方法一调用方法二,方法二调用方法三,这样的调用层次是根据业务的需求来定的,就好比一个复杂的业务逻辑这样的处理下去合情合理;

那么什么是代码书签呢?其实我们仔细分析一下我们日常所写的代码基本上都是由方法组合而成,不管是实例类还是静态类都是通过方法将彼此联系起来,所有的业务逻辑都是包装在方法的内部处理的,这里的代码书签就是方法的可持久化抽象;

试想一下,我们要想将程序的逻辑流程钝化肯定是少不了对逻辑调用的保存;原本的程序逻辑是线程本地的执行路径,属于.NETCLR直接管理的,依赖于栈的执行,所以我们无法干预其生命周期过程,那么我们只有将它们对象化后才能由我们自己操控;

图1:


上图的意思是说在一个流程的开始到结束基本上三个重要环节,Begin\Processs…\End过程,在每个过程中需要不同的处理逻辑,在图的偏上方,我们有三个ProcessName名称的小方块表示程序的调用顺序,ProcessName1调用ProcessName2调用ProcessName3;

在ProcessName2的上面我们加了一个Bookmark的标记,表示我们这里所说的代码书签,通过代码书签我们就可以记录下本次执行到哪里了,就好比我们在看书的时候都有一个买书时赠送的书签卡,我们看到哪里就把这个书签卡插在那里,当下次要看的时候直接找到这个书签卡继续看;

这里的代码书签跟这个是一样的道理,理论就是这些我们下面通过示例代码来亲身体验一下这种设计模式;

2.1】ProgramBookmark 实现(使用委托来锚定代码书签)

委托是天生的方法标签,通过委托我们完全可以将一个实例的方法直接锚定下来;

【有关对委托的高级应用不太清楚的可以参见本人的这两篇文章:

.NET框架设计(一:常被忽视的C#设计技巧).NET框架设计(二:常被忽视的框架设计技巧)

我们来构造代码书签对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*==============================================================================
  * Author:深度训练
  * Create time: 2013-08-10
  * Blog Address:http://www.cnblogs.com/wangiqngpei557/
  * Author Description:特定领域软件工程实践;
  *==============================================================================*/
namespace  ProgramComponent
{
     using  System;
     /// <summary>
     /// Program book mark.
     /// </summary>
     [Serializable]
     public  class  ProgramBookmark
     {
         /// <summary>
         /// Mark program book mark.
         /// </summary>
         /// <param name="name">Mark name.</param>
         /// <param name="continueAt">Program continue.</param>
         public  ProgramBookmark( string  name, ProgramBookmarkLocation continueAt)
         {
             this .markname = name;
             this .continueAt = continueAt;
         }
         private  string  markname;
         /// <summary>
         /// Book mark name.
         /// </summary>
         public  string  BookmarkName {  get  return  markname; } }
         private  ProgramBookmarkLocation continueAt;
         /// <summary>
         /// Continue location.
         /// </summary>
         public  ProgramBookmarkLocation ContinueAt {  get  return  continueAt; } }
         /// <summary>
         /// Program load data.
         /// </summary>
         public  object  Payload {  get set ; }
     }
     /// <summary>
     /// Program book mark location.
     /// </summary>
     /// <param name="resumed">Resumed bookmark.</param>
     public  delegate  void  ProgramBookmarkLocation(ProgramBookmark resumed);
}


这段代码是对代码书签的抽象,构造函数传入一个代码书签的名称、书签所表示的物理代码锚点,Payload是表示每次执行物理代码时的输入参数;

上面代码看似简单其实很不简单,它的背后隐藏着一个很大的设计思想:

将一块很大的逻辑代码拆成很多零碎的方法片段,很多人可能会觉得设计本身不就这样要求的嘛,那你可能真的没有深入理解代码碎片会后需要对所有的方法参数进行对象化,不管什么方法都会是同样的参数,只有这样才能让书签连续起作用;

下面我们来看一下代码书签有多巧妙,我们来构造一个简单的示例代码,当然你完全可以设计的很复杂很强大,这里毕竟是传递这种设计思想为主;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*==============================================================================
  * Author:深度训练
  * Create time: 2013-08-10
  * Blog Address:http://www.cnblogs.com/wangiqngpei557/
  * Author Description:特定领域软件工程实践;
  *==============================================================================*/
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Threading.Tasks;
namespace  ConsoleApplication1
{
     [Serializable]
     public  class  OrderCheckFlows
     {
         private  IList<ProgramComponent.ProgramBookmark> flowsManager =  new  List<ProgramComponent.ProgramBookmark>();
         public  OrderCheckFlows()
         {
             ProgramComponent.ProgramBookmark bookmarkCheckOrderPrices =
                 new  ProgramComponent.ProgramBookmark( "checkPrices" new  ProgramComponent.ProgramBookmarkLocation(CheckOrderPrices));
             flowsManager.Add(bookmarkCheckOrderPrices);
         }
         public  void  StartCheck()
         {
             do
             {
                 flowsManager[0].ContinueAt(flowsManager[0]);
             }
             while  (flowsManager.Count > 0);
         }
         #region business flows
         public  void  CheckOrderPrices(ProgramComponent.ProgramBookmark nextCheck)
         {
             Console.WriteLine( "checkPrices..." );
             ProgramComponent.ProgramBookmark bookmarkCheckOrderPrices =
                 new  ProgramComponent.ProgramBookmark( "checkPrices" new  ProgramComponent.ProgramBookmarkLocation(CheckOrderItems));
             bookmarkCheckOrderPrices.Payload =  true ; //method parameters.
             flowsManager.Add(bookmarkCheckOrderPrices);
             flowsManager.RemoveAt(0);
         }
         public  void  CheckOrderItems(ProgramComponent.ProgramBookmark nextCheck)
         {
             if  (( bool )nextCheck.Payload)
             {
                 Console.WriteLine( "checkItems..." );
             }
             else
             {
                 Console.WriteLine( "end check items." );
             }
             flowsManager.RemoveAt(0);
         }
         #endregion
     }
}


这个类是一个简单的模拟检查订单的一系列的业务流程;

图2:

上图能看见流程顺利执行完毕了,那么我们来解释一下重要的代码片段;

图3:

在第一个流程里面我们构造一个通往下一个流程的 ProgramComponent.ProgramBookmark 对象,如果这里出现关于流程无法继续下去的条件就可以不创建往下执行的代码书签;在第二流程里面我们获取第一个流程设置的参数,这里是一个Bool值,可以用来判断上一个执行是否成功等信息;

2.2】ProgramBookmarkManager书签管理器(书签集合的处理,IEnumerable<T>书签管理)

上一节我们完成了对代码书签的抽象实现,但是代码还有很多值得抽象设计的地方,上面的代码中最不太理解的地方就是对书签集合的操作上,很不OO;

那么这一节我们将把它改进,形成OO方式的调用,先看一下哪里不太理解;

图4:

第一个地方就是在声明ProgramCompoent.ProgramBookmark集合上,这样写问题太大了,无法进行扩展改进;然后就是在构造函数中,我们使用了很长一段代码来构造一个ProgramCompoent.ProgramBookmark对象,完全可以减少很多;还有就是在StartCheck方法的内部中进行循环调用书签的代码,也很有问题,完全可以封装在内部实现,外部直接一个CurrentProgram属性执行就行了;

那么对这些问题我们其实少一个ProgramCompoent.ProgramBookmark的管理器对象ProgramCompoent.ProgramBookmarkManager对象,它负责管理所有跟ProgramCompoent.ProgramBookmark对象相关的工作;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*==============================================================================
  * Author:深度训练
  * Create time: 2013-08-10
  * Blog Address:http://www.cnblogs.com/wangiqngpei557/
  * Author Description:特定领域软件工程实践;
  *==============================================================================*/
namespace  ProgramComponent
{
     using  System.Collections.Generic;
     /// <summary>
     /// Program book mark Manager.<see cref="System.Collections.Dictionary{BookmarkName,ProgramBookmark}"/>
     /// </summary>
     public  class  ProgramBookmarkManager : Dictionary< string , ProgramBookmark>
     {
         /// <summary>
         /// Add programbookmark and instant next programbookmark.
         /// </summary>
         /// <param name="bookmark"><see cref="ProgramComponent.ProgramBookmark"/></param>
         public  void  Add(ProgramBookmark bookmark)
         {
             base .Add(bookmark.BookmarkName, bookmark);
         }
         /// <summary>
         /// Remove programbookmark.
         /// </summary>
         /// <param name="bookmark"><see cref="ProgramComponent.ProgramBookmark"/></param>
         public  void  Remove(ProgramBookmark bookmark)
         {
             base .Remove(bookmark.BookmarkName);
         }
         /// <summary>
         /// Resume  bookmark by bookmarkname.
         /// </summary>
         /// <param name="bookmarkName">bookmark name.</param>
         /// <param name="payload">Continue load.</param>
         public  void  Resume( string  bookmarkName,  object  payload)
         {
             ProgramBookmark bookmark;
             this .TryGetValue(bookmarkName,  out  bookmark);
             if  (bookmark !=  null )
             {
                 bookmark.Payload = payload;
                 bookmark.ContinueAt(bookmark);
             }
         }
     }
}

书签管理器基本功能还算简单,主要的方法Resume是用来恢复指定的书签的;再来看一下订单检查流程调用;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*==============================================================================
  * Author:深度训练
  * Create time: 2013-08-10
  * Blog Address:http://www.cnblogs.com/wangiqngpei557/
  * Author Description:特定领域软件工程实践;
  *==============================================================================*/
namespace  ConsoleApplication1
{
     using  System;
     using  ProgramComponent;
     [Serializable]
     public  class  OrderCheckFlows
     {
         private  ProgramBookmarkManager BookmarkManager =  new  ProgramBookmarkManager();
         public  OrderCheckFlows()
         {
             BookmarkManager.Add( new  ProgramBookmark( "checkPrices" new  ProgramBookmarkLocation(CheckOrderPrices)));
         }
         public  void  StartCheck()
         {
             BookmarkManager.Resume( "checkPrices" null );
         }
         #region business flows
         public  void  CheckOrderPrices(ProgramComponent.ProgramBookmark nextCheck)
         {
             Console.WriteLine( "checkPrices..." );
             BookmarkManager.Remove(nextCheck);
             BookmarkManager.Add( new  ProgramBookmark( "checkItems" new  ProgramBookmarkLocation(CheckOrderItems)));
             BookmarkManager.Resume( "checkItems" true );
         }
         public  void  CheckOrderItems(ProgramComponent.ProgramBookmark nextCheck)
         {
             if  (( bool )nextCheck.Payload)
                 Console.WriteLine( "checkItems..." );
             else
                 Console.WriteLine( "end check items." );
             BookmarkManager.Remove(nextCheck);
         }
         #endregion
     }
}


是不是比之前的代码好多了,我感觉是好多了,当然还有很大的重构空间;

这里其实已经可以和链式编程的机制挂钩了,我们可以通过给书签管理器添加N个扩展方法来使书签管理器具有跟链式的调用;

3】可恢复语句组件(将可恢复语句对象化)

要想把所有的调用都拆开来使用松散的方式组合,通过使用书签机制基本上能将所有的方法进行松散组合;那么我们还需要将逻辑语法进行对象化才能做到无死角的松散;

什么叫语句组件,就是将一些原本无法独立的一些逻辑判断、循环之类的语句对象化,形成更具有对象的组件;

试想一下,如果我们将所有的这些逻辑语法对象化后我们的代码中还有精密耦合的代码吗?就算有也应该会很少,是不是很神奇;

其实对 企业应用架构 中的 规约模式 有所了解的人应该会比较熟悉这一节的内容,跟规约模式很像,但不是一个东西,侧重点不同;语句组件全面的概念是将所有的调用都对象化,包括一些输出、输入、网络调用等等,这样才是全部的语句组件定义,还记得我们上面的订单检查对象嘛,那个也是语句组件之一;

我们来构造可恢复语句组件对象;

ProgramComponent.LanguageComponent.LanguageComponent类代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*==============================================================================
  * Author:深度训练
  * Create time: 2013-08-10
  * Blog Address:http://www.cnblogs.com/wangiqngpei557/
  * Author Description:特定领域软件工程实践;
  *==============================================================================*/
namespace  ProgramComponent.LanguageComponent
{
     using  System;
     [Serializable]
     public  abstract  class  LanguageComponent
     {
         public  abstract  void  Run(ProgramBookmarkManager mgr);
     }
}

ProgramComponent.LanguageComponent.LanguageComponentBlock类代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*==============================================================================
  * Author:深度训练
  * Create time: 2013-08-10
  * Blog Address:http://www.cnblogs.com/wangiqngpei557/
  * Author Description:特定领域软件工程实践;
  *==============================================================================*/
namespace  ProgramComponent.LanguageComponent
{
     using  System.Collections.Generic;
     public  class  LanguageComponentBlock : LanguageComponent
     {
         List<LanguageComponent> statements =  new  List<LanguageComponent>();
         public  List<LanguageComponent> Statements
         {
             get  return  statements; }
         }
         public  void  AddLangugateComponent(LanguageComponent lc)
         {
             statements.Add(lc);
         }
         public  override  void  Run(ProgramBookmarkManager mgr)
         {
                                                                     
         }
     }
}

ProgramComponent.LanguageComponent.IfElseLanguageComponent类代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*==============================================================================
  * Author:深度训练
  * Create time: 2013-08-10
  * Blog Address:http://www.cnblogs.com/wangiqngpei557/
  * Author Description:特定领域软件工程实践;
  *==============================================================================*/
namespace  ProgramComponent.LanguageComponent
{
     using  System;
     using  System.Linq;
     using  System.Linq.Expressions;
     public  class  IfElseLanguageComponent : LanguageComponentBlock
     {
         public  Func< bool > Exp {  get set ; }
         public  override  void  Run(ProgramBookmarkManager mgr)
         {
             if  (Exp())
                 base .Statements[0].Run(mgr);
             else
                 base .Statements[1].Run(mgr);
         }
     }
}

检查流程代码,OrderCheckFlows\OrderSubmitFlows类代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*==============================================================================
  * Author:深度训练
  * Create time: 2013-08-10
  * Blog Address:http://www.cnblogs.com/wangiqngpei557/
  * Author Description:特定领域软件工程实践;
  *==============================================================================*/
namespace  ConsoleApplication1
{
     using  System;
     using  ProgramComponent;
     using  ProgramComponent.LanguageComponent;
     [Serializable]
     public  class  OrderCheckFlows : LanguageComponent
     {
         private  ProgramBookmarkManager BookmarkManager =  new  ProgramBookmarkManager();
         public  OrderCheckFlows(ProgramBookmarkManager bookmarkManager)
         {
             this .BookmarkManager = bookmarkManager;
             BookmarkManager.Add( new  ProgramBookmark( "checkPrices" new  ProgramBookmarkLocation(CheckOrderPrices)));
         }
         public  override  void  Run(ProgramBookmarkManager mgr)
         {
             this .BookmarkManager = mgr;
             StartCheck();
         }
         public  void  StartCheck()
         {
             BookmarkManager.Resume( "checkPrices" null );
         }
         #region business flows
         public  void  CheckOrderPrices(ProgramComponent.ProgramBookmark nextCheck)
         {
             Console.WriteLine( "checkPrices..." );
             BookmarkManager.Remove(nextCheck);
             BookmarkManager.Add( new  ProgramBookmark( "checkItems" new  ProgramBookmarkLocation(CheckOrderItems)));
             BookmarkManager.Resume( "checkItems" true );
         }
         public  void  CheckOrderItems(ProgramComponent.ProgramBookmark nextCheck)
         {
             if  (( bool )nextCheck.Payload)
                 Console.WriteLine( "checkItems..." );
             else
                 Console.WriteLine( "end check items." );
             BookmarkManager.Remove(nextCheck);
         }
         #endregion
     }
     [Serializable]
     public  class  OrderSubmitFlows : LanguageComponent
     {
         private  ProgramBookmarkManager BookmarkManager =  new  ProgramBookmarkManager();
         public  OrderSubmitFlows(ProgramBookmarkManager bookmarkManager)
         {
             this .BookmarkManager = bookmarkManager;
             BookmarkManager.Add( new  ProgramBookmark( "CheckSubmitPrices" new  ProgramBookmarkLocation(CheckSubmitPrices)));
         }
         public  override  void  Run(ProgramBookmarkManager mgr)
         {
             this .BookmarkManager = mgr;
             StartCheck();
         }
         public  void  StartCheck()
         {
             BookmarkManager.Resume( "CheckSubmitPrices" null );
         }
         #region business flows
         public  void  CheckSubmitPrices(ProgramComponent.ProgramBookmark nextCheck)
         {
             Console.WriteLine( "CheckSubmitPrices..." );
             BookmarkManager.Remove(nextCheck);
             BookmarkManager.Add( new  ProgramBookmark( "CheckSubmitItems" new  ProgramBookmarkLocation(CheckSubmitItems)));
             BookmarkManager.Resume( "CheckSubmitItems" true );
         }
         public  void  CheckSubmitItems(ProgramComponent.ProgramBookmark nextCheck)
         {
             if  (( bool )nextCheck.Payload)
                 Console.WriteLine( "CheckSubmitItems..." );
             else
                 Console.WriteLine( "end check CheckSubmitItems." );
             BookmarkManager.Remove(nextCheck);
         }
         #endregion
     }
}

调用代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Threading.Tasks;
namespace  ConsoleApplication1
{
     using  ProgramComponent;
     using  ProgramComponent.LanguageComponent;
     class  Program
     {
         static  void  Main( string [] args)
         {
             ProgramBookmarkManager bookmarkManager =  new  ProgramBookmarkManager();
             OrderCheckFlows orderCheckFlow =  new  OrderCheckFlows(bookmarkManager);
             OrderSubmitFlows submitCheckFlow =  new  OrderSubmitFlows(bookmarkManager);
             IfElseLanguageComponent languageComponent =  new  IfElseLanguageComponent();
             languageComponent.Exp = () => {  return  true ; };
             languageComponent.AddLangugateComponent(orderCheckFlow);
             languageComponent.AddLangugateComponent(submitCheckFlow);
             languageComponent.Run(bookmarkManager);
             Console.ReadLine();
         }
     }
}

一切都已经被对象化,我们来看一下逻辑;

图5:

这里的返回值决定了后面要执行的语句组件的路径,如果是true,则应该检查OrderCheckFlows流程;

图6:

如果是false,则应该检查OrderSubmitFlows流程;

图7:

可恢复语句对象模型基本构造完成,当然复杂的问题还需要仔细的去分析设计,这里只是一个简单的示例;

3.1】可恢复语句组件管理器(将可恢复语句视为普通的对象成员,IEnumerable<T>语句组件)

跟代码书签管理器一个道理,这里我们也可以实现一个LanguageComponentManager来对LanguageComponent管理,当然也要看需要不需要;可恢复语句管理器其实有很多文章可以做,因为它是所有语句组件的中心,这对于后面的持久化有很大的用处;

//由于内容比较多且相当抽象,下一篇文章介绍;

3.2】可恢复语句组件运行时(Program CLR)

所有的语句代码都已经被对象化,但是在运行时需要一个中心来管理这些被对象化的语句组件,因为我们要脱离对栈的依赖;一组语句组件是单个示例流程的一部分,但是我们可能会存在很多一起并行运行的流程,所以这是必须要提供的运行时;

//由于内容比较多且相当抽象,下一篇文章介绍;

3.3】可恢复语句逻辑配置(规则的配置)

领域驱动设计在使用规约模式的时候会存在动态配置的需求,可以参见这里的语句组件模型,让规约最大化的提供配置;

//由于内容比较多且相当抽象,下一篇文章介绍;

3.4】可恢复语句逻辑传输(将可恢复语句对象远程传输)

//由于内容比较多且相当抽象,下一篇文章介绍;

4】DomainModel规则引擎(规则持久化后管理配置)

//由于内容比较多且相当抽象,下一篇文章介绍;



示例Demo地址:http://files.cnblogs.com/wangiqngpei557/ConsoleApplication3.zip


 本文转自 王清培 51CTO博客,原文链接:http://blog.51cto.com/wangqingpei557/1270440,如需转载请自行联系原作者




相关文章
|
4月前
|
人工智能 API 数据库
Semantic Kernel .NET 架构学习指南
本指南系统解析微软Semantic Kernel .NET架构,涵盖核心组件、设计模式与源码结构,结合实战路径与调试技巧,助你从入门到贡献开源,掌握AI编排开发全栈技能。
456 2
|
开发框架 前端开发 .NET
一个适用于 .NET 的开源整洁架构项目模板
一个适用于 .NET 的开源整洁架构项目模板
286 26
|
C# Android开发 iOS开发
2025年全面的.NET跨平台应用框架推荐
2025年全面的.NET跨平台应用框架推荐
655 23
|
消息中间件 开发框架 监控
NET任务调度框架Hangfire使用指南
Hangfire 是一个用于 .NET 应用程序的开源任务调度框架,支持长时间运行任务、定时任务等。通过简单的安装配置,即可将任务从主线程分离,提升应用性能。支持多种数据库,提供丰富的任务类型如立即执行、延迟执行和周期性任务,并有可视化管理界面 Hangfire Dashboard。还支持安全性配置及扩展插件,如 Hangfire.HttpJob,适合各种复杂场景下的任务调度需求。
1429 1
NET任务调度框架Hangfire使用指南
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
521 5
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
860 13
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
189 4
|
敏捷开发 缓存 中间件
.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素
本文深入探讨了.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素,并通过企业级应用和Web应用开发的实践案例,展示了如何在实际项目中应用这些模式,旨在为开发者提供有益的参考和指导。
159 3
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
311 7