0

假设我正在开发一个将由多个部门使用的帮助台应用程序。应用程序中的每个 URL 都将包含一个表示特定部门的键。密钥始终是系统中每个操作的第一个参数。例如

http://helpdesk/HR/Members
http://helpdesk/HR/Members/PeterParker
http://helpdesk/HR/Categories
http://helpdesk/Finance/Members
http://helpdesk/Finance/Members/BruceWayne
http://helpdesk/Finance/Categories

问题是,在每个请求的每个操作中,我都必须采用此参数,然后根据该密钥从存储库中检索 Helpdesk Department 模型。从该模型中,我可以检索成员、类别等的列表,这对于每个帮助台部门都是不同的。这显然违反了 DRY。

我的问题是,我如何创建一个基本控制器,它为我执行此操作,以便 URL 中指定的特定帮助台部门可用于所有派生控制器,并且我可以专注于操作?

4

3 回答 3

2

我的一个项目中有一个类似的场景,我倾向于使用 ModelBinder 而不是使用单独的继承层次结构。您可以创建一个 ModelBinder 属性来从 RouteData 中获取实体/实体:

public class HelpdeskDepartmentBinder : CustomModelBinderAttribute, IModelBinder {

    public override IModelBinder GetBinder() {
        return this;
    }

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) {
        //... extract appropriate value from RouteData and fetch corresponding entity from database. 
    }
}

...然后您可以使用它使 HelpdeskDepartment 可用于您的所有操作:

public class MyController : Controller {
    public ActionResult Index([HelpdeskDepartmentBinder] HelpdeskDepartment department) {
        return View();
    }
}
于 2008-09-17T13:29:51.453 回答
0

免责声明:我目前正在运行 MVC Preview 5,所以其中一些可能是新的。

最佳实践方法:只需实现一个静态实用程序类,该类提供一个执行模型查找的方法,将动作中的 RouteData 作为参数。然后,从需要模型的所有操作中调用此方法。

笨拙的方式,仅当每个控制器中的每个操作都需要模型时,并且您真的不希望在您的操作中调用额外的方法:在您的控制器实现基类中,覆盖 ExecuteCore(),使用 RouteData 填充模型,然后调用 base.ExecuteCore()。

于 2008-09-16T00:53:00.940 回答
0

您可以通过普通的 C# 继承创建一个基本控制器类:

public abstract class BaseController : Controller 
{
}

public class DerivedController : BaseController 
{
}

您只能将此基类用于需要部门的控制器。您不必执行任何特殊操作来实例化派生控制器。

从技术上讲,这很好用。然而,从设计的角度来看,存在一些风险。如您所说,如果您的所有控制器都需要一个部门,那很好。如果只有其中一些需要一个部门,那可能还是可以的。但是,如果某些控制器需要一个部门,而其他控制器需要一些其他继承行为,并且两个子集相交,那么您可能会发现自己陷入了多重继承问题。这表明继承不是解决您陈述的问题的最佳设计。

于 2008-09-16T13:42:45.427 回答