[英]How do you implement this generic class?
我有一個前端ASP.NET MVC網站,該網站與后端服務聯系。 前端和后端使用DTO進行通信。
public class MyDto
{
public string Name {get;set;}
}
我不想直接向我的網站用戶顯示此DTO,所以我制作了一個使用相同數據的ViewModel。
public class MyViewModel
{
public string Name {get;set;}
}
現在,對於所有這些視圖模型,update,post和其他方法都相同。 我決定不為每個視圖模型重新鍵入相同的控制器操作,而是決定創建一個包含所有這些方法的抽象控制器。 因此,我創建了一個接口,以便所有視圖模型都具有相同的行為:
public interface IViewModelControllerActions<T>
{
IUpdateData<T> UpdateData { get; } //IUpdateData defined somewhere else
IUploadData<T> UploadData { get; } // IUploadData defined somewhere else
// definitions for other actions
}
我添加到我的視圖模型:
public class MyViewModel : IViewModelControllerActions<MyDto>
{
public string Name {get;set;}
public IUpdateData<T> UpdateData { get { /* Do stuff to get UpdateData */ } }
public IUploadData <T> UploadData { get { /* Do stuff to get UploadData */ } }
}
並創建抽象控制器:
public abstract class ViewModelController<T>: Controller where T : IViewModelControllerActions<T>
{
[HttpPost]
public ActionResult Upload(T input)
{
// do stuff with T.UploadData to upload
}
[HttpPost]
public ActionResult Update(T input)
{
// do stuff with T.UpdateData to update
}
// other methods
}
這個想法是:引入新的dto和viewmodel時,我要做的就是在viewmodel上實現IViewModelControllerActions接口:
public class MyNewCoolerViewModel : IViewModelControllerActions<MyNewCoolerDto>
{
public string Name {get;set;}
public string AnotherNewName {get;set;}
public int ANumber {get;set;}
public IUpdateData<T> UpdateData { get { /* Do stuff to get UpdateData */ } }
public IUploadData <T> UploadData { get { /* Do stuff to get UploadData */ } }
}
並創建一個繼承自抽象控制器的新空控制器:
public class MyNewCoolerController : ViewModelController<MyNewCoolerViewModel> {}
這樣控制器內部的所有邏輯都將已經實現。 但是,我收到此錯誤消息:
MyNewCoolerViewModel類型不能用作泛型類型或方法ViewModelController <T>中的類型參數T。 從MyNewCoolerViewModel到IViewModelControllerActions <MyNewCoolerViewModel>沒有隱式引用轉換
我了解錯誤消息,但是,我不知道如何解決它。 如何使該設置起作用?
您是否看過/考慮過Automapper ?
我認為您過於復雜了-我意識到這不是您問題的直接答案,但DTO-> ViewModel的問題通常是使用某種映射器解決的。 您的項目中的這種方法有什么問題?
這聽起來像是一個難題,但是看了一會兒之后,主要的問題是控制器中的T是自引用的:
abstract class ViewModelController<T>: Controller where T : IViewModelControllerActions<T>
在這種情況下,這意味着T必須為IViewModelControllerActions<IViewModelControllerActions<T>>
。 控制器應為ViewModelController<T,U>:Controller where T:IViewModelController<U>
或ViewModelController<IViewModelControllerAction<T>>
具體取決於您打算如何使用它
但老實說,這(imo)與MVC架構不太吻合。 至於控制器和重用,我認為您可以跳過整個IViewModelControllerAction-interface並只重寫基類上的方法,如下所示:
public abstract class ViewModelController<T,U>:Controller{ public ActionResult Update(T item){...} public abstract void Save(U dto); }
根據您打算如何實現,U可能是可選的,但這只是一個開始。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.