2013-11-15 22 views
6

我問一個關於ASP.NET MVC的通用控制器和this answer問題表示控制器是這樣的:如何使用ASP.NET MVC的通用控制器來填充正確的模式

public abstract class GenericController<T> 
    where T : class 
{ 
    public virtual ActionResult Details(int id) 
    { 
     var model = _repository.Set<T>().Find(id); 
     return View(model); 
    } 
} 

這可以這樣實現的。

public class FooController : GenericController<Foo> 
{ 

} 

現在,當有人請求/美孚/詳細信息/ 42,entitiy從_repository的Set<Foo>()拉,而無需編寫的,在任何FooController

他解釋說,是好的,但覺得我要開發的產品和客戶的通用控制器,在那裏我不會用EF加載產品&客戶模式,而使用MS數據訪問應用程序塊的方式。

public abstract class GenericController<T> 
     where T : class 
    { 
     public virtual ActionResult Details(int id) 
     { 
      //var model = _repository.Set<T>().Find(id); 
      var model =customer.load(id); 
      or 
      var model =product.load(id); 
      return View(model); 
     } 
    } 

所以,當收到請求時喜歡/Customer/Details/42 or /product/Details/11那麼通用控制器的詳細方法將調用,但我們如何能夠檢測請求來自哪個控制器和相應的實例正確的類加載正確的模式。

如果客戶有要求,那麼我需要從詳細的操作方法中加載客戶詳細信息,或者如果請求來自產品,那麼我需要從通用控制器的詳細操作方法加載產品詳細信息。

如何使用泛型來獲取帶有實體框架數據塊的T類型的數據集?

+0

通用控制器的目標是什麼? –

+0

您需要在當前工作的控制器中顯示初始化數據塊的代碼。泛型的東西是,你不能按照它的類型訪問模型;你讓你的倉庫返回它。這就是你可以使用實體框架的'DbContext.Set ()'方法,所以你的通用控制器_不會在編譯時知道它將返回哪個具體模型。我們可以給出一個數據塊的例子,但是如果你顯示你當前的代碼,這樣做是最簡單的。 – CodeCaster

回答

12

您可以與您的實體的工作,像CustomerRepositoryProductRepository從基本接口像

public interface IBaseRepository 
{ 
    T Get<T>(int id); 
    void Save<T>(T entity); 
} 

創建一組資料庫,然後用任何DI框架的擴展與資源庫類型的控制器基類和它的實例

public abstract class GenericController<T, TRepo> 
     where T : class 
     where TRepo : IBaseRepository, new() 
    { 
     private IBaseRepository repository; 

     public GenericController() 
     { 
      repository = new TRepo(); 
     } 

     public virtual ActionResult Details(int id) 
     { 
      var model =repository.Get<T>(id); 
      return View(model); 
     } 
    } 

示例CustomerController

public class CustomerController : GenericController<Customer, CustomerRepository> 
{ 

} 

其中CustomerRepository:

public class CustomerRepository : IBaseRepository 
{ 
    public T Get <T>(int id) 
    { 
    // load data from DB 
    return new Customer(); 
    } 
} 
+0

感謝您的答案,但你可以給我完整的產品和客戶smaple代碼....但我想提一提,我不會使用EF,而是我會使用ado.net進行數據庫交互。謝謝 – Mou

+0

如何實現IBaseRepository的實現並不重要。重點是產品和客戶控制器,用具體的實體類型和存儲庫類型來定義。例如,如果您的Customer實體具有CustomerRepository:IBaseRepository,那麼您應該只有控制器類的公共類CustomerContoller:GenericController {}定義。 –

+0

通用控制器的主要目標是什麼.......我們通過這個得到了什麼好處......請儘可能地解釋它。 –

7

當您的應用程序的大小和複雜性超過某個特定點時,我不認爲在控制器中放置像這樣的數據訪問和業務邏輯是明智的。您應該創建處理數據訪問的存儲庫,並將該技術(EF,純ADO.NET等)從消費者處抽象出來。您可以在控制器中使用這些存儲庫,但這意味着您的控制器仍包含您不想要的業務邏輯。控制器應該很薄。

我所做的是在我的存儲庫和控制器之間創建一個服務層,它包含業務邏輯並委託數據訪問存儲庫。我在我的控制器中使用這些服務來獲取我的域模型,並將其映射到查看模型。你會想要一個Inversion of Control容器來將這些圖層「粘合」在一起,並在它們之間提供鬆散的耦合。

搜索'c#mvc存儲​​庫和服務模式'將導致大量示例。我發現this post是一個很好的例子,除了他從服務而不是領域模型返回視圖模型。

這僅僅是我的2美分,請記住,以上所有僅適用於您有'中檔'應用程序而不是典型的教程/試用網站。

+0

給你聽,嗯! –

+0

這是個好主意,但是我的知識對於存儲庫設計模式並不好,但是想知道如何在人們請求此URL/Customer/Details/42時通知我的存儲庫加載客戶數據?或在/ product/Details/11時加載產品數據。你能指導我嗎?你可以給我任何我的場景的文章。謝謝 – Mou

+0

@Mou在我的回答中查看我提到的URL,它給出了一個詳細的例子。 –

3

鑑於我在其他問題拒絕和我的意見在這裏解釋爲什麼這不是一個最終的解決方案,我會盡量給出更具體的實現:

public abstract class GenericController<T> : Controller 
    where T : class 
{ 
    protected YourEFContext _dataSource; 

    public GenericController() 
    { 
     _dataSource = new YourEFContext(); 
    } 

    public virtual ActionResult Details(int id) 
    { 
     var model = _dataSource.Set<T>().Find(id); 
     return View(model); 
    } 
} 

public class CustomerController : GenericController<Customer> 
{ 

} 

這是使/Customers/Details/42加載客戶所需的代碼,ID爲42需要從實體框架上下文中加載。 「通用」部分通過實體框架的DbContext.Set<T>()方法來解決,該方法返回DbSet<TEntity>爲合適的實體,在這種情況下,您可以查詢DbSet<Customer>

話雖這麼說,也有很多問題,實際使用此代碼:

  • 你不想讓你的控制器知道你的數據訪問。如您所見,在控制器中使用了YourEFContext屬性,並將其與Entity Framework緊密結合。您需要以存儲庫模式將其抽象化。
  • 你不想讓你的控制器實例化其數據訪問,這應該被注入。
  • 你不想讓你的控制器返回返回數據庫實體。您正在尋找ViewModels和Mapper。
  • 您不希望您的控制器以做數據訪問。將數據訪問移動到同樣包含業務邏輯的服務層中,並通過存儲庫模式將其重新抽象出來。

現在問題其實是「做企業庫數據塊有一個像GetDataSet<T>的方法」,所以你不必指customerproduct在通用控制器,但不幸的是,我可以沒有發現,因爲我幾年沒有使用過EntLib。如果您顯示您當前用於訪問數據庫的代碼,這將有所幫助。

你正在尋找的終極目標是:只有

[  MVC    ] <=> [   Service   ] <=> [ Repository ] 
View ViewModel Controller  BusinessModel BusinessLogic  DataModel Database 

你的控制器會談,爲您服務,創建/讀取/更新/刪除BusinessModels,並執行的ViewModels和BusinessModels(在<=>)之間的映射。該服務包含業務邏輯和業務模型(使用WCF時的DataContacts),並依次映射(<=>)到DataModel和從DataModels映射到您的存儲庫以保存模型。

我明白這可能需要一點時間才能掌握,這也許就是爲什麼大多數ASP.NET MVC教程都從一個應用程序中的所有三層開始。看看ProDinner更合適的方法。

+0

通用控制器的主要目標是什麼.......我們得到了什麼好處....請儘可能地解釋它。 –

相關問題