2013-08-02 50 views
0

我正在研究使用責任鏈處理請求的應用程序。我知道如何建立連鎖店,但如果你看看下面的例子,我將不得不打電話link1.Process(request);來啓動連鎖過程。我想弄明白的是,有沒有一種方法可以像集合一樣對待它,只需調用鏈中的第一個鏈接,無論這可能是什麼?原因是,我知道基本元素是什麼(最終的默認對象),但其他程序員可以將對象添加到鏈中,並可能將它們置於鏈條永遠不會到達的位置。責任鏈動態鏈

public class MergedFieldProcessor 
{ 

    public MergedFieldProcessor() 
    { 
     //Define CoR here 

     FieldProcessor link1 = new FieldProcessor(); 
     FieldProcessor link2 = new FieldProcessor(); 
     FieldProcessor link3 = new FieldProcessor(); 

     link1.SetNextProcessor(link2); 
     link2.SetNextProcessor(link3); 

    } 



} 

public abstract class FieldProcessor 
{ 
    private FieldProcessor NextProcessor { get; set; } 

    public FieldProcessor() 
    { 
     this.NextProcessor = new SprocObject(); 
    } 

    public void SetNext (FieldProcessor successor) 
    { 
     this.NextProcessor = successor; 
    } 

    //determines if this link in the change is responsible for the request 
    public abstract Boolean WillProcess(MergedFieldProcessorRequest request); 

    //performs the processing required for the tag 
    public abstract void ProcessField(MergedFieldProcessorRequest request); 


    //chain method that passes the request 
    public void ProcessRequest(MergedFieldProcessorRequest request) 
    { 
     if (!this.WillProcess(request)) 
      this.NextProcessor.ProcessRequest(request); 
     else 
      this.ProcessField(request); 
    } 


} 

public class MergedFieldProcessorRequest 
{ 
    public MergedField Field { get; set; } 

    public Dictionary<string, string> SearchParams { get; set; } 
} 

可達鏈接的例子:

FieldProcessor link1 = new FieldProcessor(); 
     FieldProcessor link2 = new FieldProcessor(); 
     FieldProcessor link3 = new FieldProcessor(); 
     FieldProcessor link4 = new FieldProcessor(); 

     link4.SetNext(link1); 
     link1.SetNext(link2); 
     link2.SetNext(link3); 

,如果他們沒有修改,其中過程initated說link4.Process(request)代碼,然後LINK4絕不會是鏈的一部分。

簡而言之,是否有可能動態構建鏈,這樣如果有人將對象添加到集合中,它會自動添加到鏈中?

+1

你對這個問題想得太多了。如果你的消費者遺漏了一個鏈接,這很可能是故意的。如果他們不這樣做,那是他們的錯。這與強制編譯器確保while循環被關閉相似,只是因爲可以使用while循環來進行無限循環。 –

+0

所有這些看起來像你沒有使用C#和.Net提供的任何好的功能。這背後的真正要求是什麼?我相信有很多更好的方法來實現你所需要的,比如MEF。 –

回答

0

這是我想出的解決方案。只是每個處理器添加到一個集合,然後遍歷該集合構建鏈,加工鏈,只需撥打this.Links[0].Process(request);

#region Build Chain Collection; 
     this.Links = new List<FieldProcessor>() 
     { 
      new StudentEnrollmentDetailsProcessor(), 
      new SprocObject() 
     }; 
     #endregion; 

     #region Build Chain Dynamically 
     for (int i = 0; i < this.Links.Count(); i++) 
     { 
      if (i < this.Links.Count()) 
      { 
       this.Links[i].SetNext(this.Links[i + 1]); 
      } 
     } 
     #endregion; 
1

您是否想讓用戶有能力構建連鎖店......無法構建連鎖店?
兩個用戶都負責鏈接對象,或者拋出鏈接併爲FieldProcessor s提供任何集合(然後調用它們以便在集合中)。

如果鏈接很重要,最好的做法是在處理之前對鏈接進行鏈式驗證並且無法訪問鏈接。

0

你可以使用反射,有點遞歸

public class MergedFieldProcessor 
{ 
    private FieldProcessor first; 

    private FieldProcessor CreateLink(IEnumerator<Type> processors) 
    { 
     if(processors.MoveNext()) 
     { 
      FieldProcessor link = (FieldProcessor)Activator.CreateInstance(processors.Current); 
      link.NextProcessor = CreateLink(processors); 
      return link; 
     } 
     return null; 
    } 

    public MergedFieldProcessor() 
    { 
     var processType = typeof(FieldProcessor); 
     var allProcess = processType.Assembly.GetTypes() 
      .Where(t => t != processType && processType.IsAssignableFrom(t)); 
     first = CreateLink(allProcess.GetEnumerator()); 
    } 

    public void Handle(MergedFieldProcessorRequest request) 
    { 
     first.ProcessRequest(request); 
    } 
} 

這將確保所有可能的鏈接被創建和鏈接在一起,但有一個警告:最後一個鏈接將有一個null後繼者,並且通常它必須是一個更靠近鏈(將處理任何請求)。