2009-05-28 64 views
1

我需要幫助使這種方法通用。重複約10次以獲取不同網頁列表控件的列表(用「MyType」替換特定控件中使用的類型)。DRY這種方法

private static IList<MyType> GetList(RequestForm form) 
    { 
     // get base list 
     IMyTypeRepository myTypeRepository = new MyTypeRepository(new HybridSessionBuilder()); 
     IList<MyType> myTypes = myTypeRepository.GetAll(); 

     // create results list 
     IList<MyType> result = new List<MyType>(); 

     // iterate for active + used list items 
     foreach (MyType myType in myTypes) 
     { 
      if (myType.Active || form.SolutionType.Contains(myType.Value)) 
      { 
       result.Add(myType); 
      } 
     } 

     // return sorted results 
     result.OrderBy(o => o.DisplayOrder); 
     return result; 
    } 

讓我知道,如果這是不夠的信息。我認爲這需要我剛剛熟悉的更高級的語言功能。也許我應該讓他們都使用相同的存儲庫?

感謝您的幫助。編輯: 感謝您的幫助。我沒有任何同行的支持,所以這個主板太棒了,我從你們每個人那裏學到了一些東西。我希望我能接受所有的答案。

回答

6

你可以先使你的功能多一點簡潔這樣的:

private static IList<MyType> GetList(RequestForm form) 
{ 
    // get base list 
    IMyTypeRepository myTypeRepository = 
     new MyTypeRepository(new HybridSessionBuilder()); 

    IList<MyType> myTypes = myTypeRepository.GetAll(); 

    return myTypes.Where(x => x.Active || form.SolutionType.Contains(x.Value)) 
        .OrderBy(x => x.DisplayOrder).ToList(); 
} 

在這一點上,大多數功能的內容,直接關係到MyType,所以怎麼可以進一步提高它在很大程度上取決於關於如何涉及其他類型的MyType。例如,這裏是如果你的其他類型遵循了合理的前瞻性(對我)的合同,你可以寫一個假想的版本:

private static IList<T> GetList(RequestForm form) where T : OrderedValueContainer 
{ 
    // we'll want to somehow genericize the idea of a TypeRepository that can 
    // produce these types; if that can't be done, we're probably better off 
    // passing a repository into this function rather than creating it here 

    var repository = new TypeRepository<T>(new HybridSessionBuilder()); 
    IList<T> myTypes = repository.GetAll(); 

    // the hypothetical OrderedValueContainer class/interface 
    // contains definitions for Active, Value, and DisplayOrder 

    return myTypes.Where(x => x.Active || form.SolutionType.Contains(x.Value)) 
        .OrderBy(x => x.DisplayOrder).ToList(); 
} 
+0

首先感謝讓方法更簡潔;我真的很喜歡那樣。所有類型都繼承IWebControl接口。我想我可以讓他們都使用同一個存儲庫。 – Leslie 2009-05-28 13:29:21

4

如果所有類型都實現相同的接口(如果他們不這樣做,並確保將所有屬性添加到該方法所需的接口中),那麼你可以這樣做:

private static IList<T> GetList(RequestForm form) 
     where T: IMyInterface 
    { 
     // get base list 
     IMyTypeRepository myTypeRepository = new MyTypeRepository(new HybridSessionBuilder()); 
     IList<T> myTypes = myTypeRepository.GetAll(); 

     // create results list 
     IList<T> result = new List<T>(); 

     // iterate for active + used list items 
     foreach (T myType in myTypes) 
     { 
      if (myType.Active || form.SolutionType.Contains(myType.Value)) 
      { 
       result.Add(myType); 
      } 
     } 

     // return sorted results 

     return result.OrderBy(o => o.DisplayOrder).ToList(); 
    } 

我做的一個其他改變是最後一行,你在單獨的行上有orderby,並且從未實際捕獲Ordered列表。

編輯:爲了解決這個庫的問題,你可以有各種各樣的倉庫工廠,基於T類型返回正確的存儲庫:

public static IMyTypeRepository GetRepository(Type t) 
{ 
    if(t == typeof(Type1)) 
    { 
     return Type1Repository(); 
    } 

    if(t == typeof(Type2)) 
    { 
     return Type2Repository(); 
    } 
    ....... 
} 

假設,當然,所有的倉庫實現IMyRepository接口。

+0

感謝您接受訂單;在測試中還沒有那麼遠。 所有類型都實現相同的接口,但使用它們自己的存儲庫。我必須讓他們都使用相同的存儲庫,是的? – Leslie 2009-05-28 13:21:15

+0

嗯,不一定。您可以擁有某種基於T類型創建存儲庫的Factory。請參閱我的編輯。 – BFree 2009-05-28 13:44:36

1

假設庫共享一個通用的接口,與資源庫中的問題,應該是很容易解決:添加靜態函數如


public static IRepository RepositoryForType(Type t) 
{ 
    if(t == typeof(SomeClass)) 
     return new SomeClassRepository(new HybridSession()); 
    else if ... 
    else throw new InvalidOperationException("No repository for type " + t.Name); 
} 

這應該要求你改變最少的現有代碼,但是請注意,將來您必須在您的項目中添加新的存儲庫時,才能在此函數中添加對新存儲庫的類支持(如果您正在使用單元測試,則無論如何您都會很輕易地發現是否忘記了此幫助程序)。

+0

感謝您的這個想法。我認爲在這個例子中可能會更好,讓所有的Web控件都使用同一個存儲庫,尤其是因爲它們都來自同一個數據庫表。 – Leslie 2009-05-28 13:26:18

2

首先,所有的類型必須實現一個共同的interface是這樣定義的屬性Active,Value ...

此外,我可以告訴,必須有一個獨立於MyType所有存儲庫的存儲庫接口,以便您可以使用這樣的通用方法。應在0​​中定義GetAll()方法。

public interface IRepository<T> where T : IMyType 
{ 
    IList<T> GetAll(); 
} 

public class RepositoryFactory 
{ 
    public static IRepository<T> createRepository<T>(ISessionBuilder sb) where T : IMyType 
    { 
     // create repository 
    } 
} 

public interface IMyType 
{ 
    bool Active { get; } 
    string Value { get; } 
} 

private static IList<T> GetList(RequestForm form) where T : IMyType 
{ 
    // get base list 
    IRepository<T> repository = RepositoryFactory.createRepository<T>(new HybridSessionBuilder()); 
    IList<T> myTypes = repository.GetAll(); 

    // create results list 
    IList<T> result = new List<T>(); 

    // iterate for active + used list items 
    foreach (T myType in myTypes) 
    { 
     if (myType.Active || form.SolutionType.Contains(myType.Value)) 
     { 
      result.Add(myType); 
     } 
    } 

    // return sorted results 
    return result.OrderBy(o => o.DisplayOrder).ToList(); 
}