在设计我的新 MVC 4 应用程序时寻找一些指导。
我想s=2011
在应用程序的每个页面上都有一个 url 参数,让我知道我正在使用哪一年的数据。显然,用户将有办法根据需要更改该参数。
我将在每个控制器中都需要该参数,并想知道执行此操作的最佳方法。我正在考虑创建一个基本控制器来读取Request.QueryString
年份并将其放入公共财产中。但是,考虑到 MVC 中的所有可扩展性点,我想知道是否有更好的方法来做到这一点?
在设计我的新 MVC 4 应用程序时寻找一些指导。
我想s=2011
在应用程序的每个页面上都有一个 url 参数,让我知道我正在使用哪一年的数据。显然,用户将有办法根据需要更改该参数。
我将在每个控制器中都需要该参数,并想知道执行此操作的最佳方法。我正在考虑创建一个基本控制器来读取Request.QueryString
年份并将其放入公共财产中。但是,考虑到 MVC 中的所有可扩展性点,我想知道是否有更好的方法来做到这一点?
这在很大程度上取决于您的应用程序的设计,但只是给您两种选择
IActionFilter
如果您为每个请求执行数据上下文,则可以使用全局IActionFilter
挂钩全局执行操作前执行,并将查询过滤器应用于幕后的数据上下文。
这样做的主要缺点是,要测试控制器,您需要设置完整的 MVC 管道,以便正确应用 actionfilter。
依赖注入
您可以使用依赖注入,而不是使用子类化(如您所说的基本控制器)。让事情变得更松散将允许您从查询字符串、cookie、数据库中的用户设置或其他任何内容中提取过滤器 - 无需您的控制器知道它来自哪里。
这是一些伪代码,如果我使用实体框架或 Nhibernate 之类的东西,我会怎么做(我也肯定适用于其他技术)
public Car
{
public string Year { get; set; }
}
public class CarsDataContext : DbContext
{
private IQuerable<Cars> _cars = null;
private Func<Car, bool> _carsFilter = null;
public IQuerable<Car> Cars {
get {
if (_carsFitler != null)
return _cars.Where(_carsFitler);
return _cars;
}
set { _cars = value; }
}
public void ApplyCarsFilter(Func<Car, bool> predicate)
{
_carsFilter = predicate;
}
}
假设您已经有依赖注入设置(NInject 或任何其他框架),您可以配置如何初始化上下文
Bind<CarsDataContext>().ToMethod(() => {
string yearFilter = GetYearFilter(); // can be coming from anywhere
CarsDataContext dataContext = new CarsDataContext();
dataContext.Applyfilter(car => car.Year == yearFilter);
return dataContext;
}).InRequestScope();
然后我的控制器对数据过滤一无所知,我可以轻松地对其进行测试:
class MyController : Controller
{
public MyController(CarsDataContext dataContext)
{
}
...
}
但是,我只会过滤跨许多控制器和我软件的重要部分的数据集。否则就是纯粹的过度设计。