2

在设计我的新 MVC 4 应用程序时寻找一些指导。

我想s=2011在应用程序的每个页面上都有一个 url 参数,让我知道我正在使用哪一年的数据。显然,用户将有办法根据需要更改该参数。

我将在每个控制器中都需要该参数,并想知道执行此操作的最佳方法。我正在考虑创建一个基本控制器来读取Request.QueryString年份并将其放入公共财产中。但是,考虑到 MVC 中的所有可扩展性点,我想知道是否有更好的方法来做到这一点?

4

1 回答 1

1

这在很大程度上取决于您的应用程序的设计,但只是给您两种选择

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)
    {
    }
    ...
}

但是,我只会过滤跨许多控制器和我软件的重要部分的数据集。否则就是纯粹的过度设计。

于 2012-08-24T23:27:49.353 回答