我无法想到处理以下情况的“最佳”方式 - 基本上,我有一堆存储对象从基类型继承并希望能够从存储中检索一个,找到它的子类型(也许通过“if(x是y)”)然后相应地采取行动 - 一些使用共享实现,另一些使用专用逻辑和视图。
我猜[剥离]这看起来有点像:
/vehicle/details/1234
- Views
- Vehicle
- Details.aspx
abstract class Vehicle{
public int ID{ get; }
}
class Motorbike : Vehicle{
//whatever
}
class Car : Vehicle{
public int NoOfDoors{ get; }
}
class VehicleController : Controller{
VehicleRepository _vehicleRepository; //injected, etc
public ActionResult Details(int id){
var vehicle = _vehicleRepository.Get(id);
//we can now figure out what subtype the vehicle is
//and can respond accordingly
}
}
现在,如果我们不担心未来的扩展和维护以及所有这些,我们可以沿着黑暗的道路走下去并实施类似下面的东西 - 这将起到很好的作用,但毫无疑问会成为绝对的梦魇。
- Views
- Vehicle
- Details.aspx
- CarDetails.aspx
public ActionResult Details(int id){
var vehicle = _vehicleRepository.Get(id);
return (vehicle is Car) ? DetailsView((Car)vehicle) : DetailsView(vehicle);
}
private ActionResult DetailsView(Car car){
var crashTestResults = GetCrashTestResults(car);
var carData = new CarDetailsViewData(car, crashTestResults);
return View("CarDetails", carData);
}
private ActionResult DetailsView(Vehicle vehicle){
var vehicleData = new VehicleDetailsViewData(car, crashTestResults);
return View("Details", vehicleData);
}
另一种机制是在视图层使用子文件夹 - 这将保持代码合理清洁,但不适用于我的情况,因为我也想要一个自定义操作方法......
- Views
- Vehicle
- Car
- Details.aspx
- Motorbike
- Details.aspx
public ActionResult Details(int id){
var vehicle = _vehicleRepository.Get(id);
return View(vehicle.GetType().Name + "\Details", vehicle);
}
理想情况下,解决方案将是一个基本控制器和专用控制器,并在需要时覆盖 - 但由于我们必须先从存储中拉出对象才能确定理想的控制器,否则我无法弄清楚如何使其工作。 ..
我目前的想法通常落在第一个障碍,让“VehicleController”对这些子类型覆盖的内容了解得太多,所以任何想法都会受到赞赏。
干杯。
答案 0 :(得分:0)
我可以看到两种解决方案,具体取决于哪种解决方案可以减少重复:
1)让Vehicle包含抽象方法GetViewName
和GetViewData
,它允许您拥有多个视图,但您的控制器不需要了解它们。
2)让Vehicle包含一个抽象的GetViewData
方法,该方法返回一个包含该类的所有ViewData的对象。然后ViewData将实现接口,您的单个视图可以基于if (ViewData is IHasCrashTestData)
或类似的东西来调整HTML部分。
在大多数情况下,我建议选项1更具可扩展性。
答案 1 :(得分:0)
我可能错了,但它真的让我觉得你只是想问一下如何渲染适合给定子类型的视图(例如摩托车或船或其他)。
除了不同的视图内容之外,控制器逻辑看起来并不像每种车型都需要不同。您是否真的试图根据车辆类型更改程序流程,还是控制器主要是关于处理CRUD操作?
假设您只是尝试更改渲染视图,那么请查看MVC 2的DisplayFor和EditorFor功能。这应该允许你传递模型类型,然后渲染一个合适的视图(iirc,没有玩过多)。
如果这不是你想要的方式,或者如果你不想使用MVC 2,因为它只是RC,而不是RTM,那么你的下一个最好的选择是覆盖ViewEngine(可能是你的当前子类)一)改变查看视图的逻辑,以涵盖上面基于文件夹的场景或你想要应用的任何方案。
答案 2 :(得分:-1)
为什么要为所有类型的车辆创建新的控制器。在数据库中,N-M关联将是简单而灵活的。
VehicleTypes
->Id
->Name
VehicleTypeVariables
->Id
->Name
Vehicles
->Id
->VehicleTypeId
VehicleVariables
->Id
->VehicleId
->VehicleTypeVariableId
->Value