Mar*_*nox 5 asp.net-mvc global-variables
我正在开发一个MVC应用程序来服务多个域 - 每个域都是一个大公司的分支.
一LocalBranch类存储详细信息,如电话,地址,电子邮件,位置坐标等.
我想为每个http请求创建一个这个类的单个实例,并让它在整个应用程序中可用 - 从控制器,视图,一些帮助程序类和其他代码.
有推荐的方法吗?
现在我将它作为a上的属性BaseController并用于ViewBag将其传递给视图.但如果可能的话,我希望它强烈输入视图.
我不想把它放在一个应用程序变量中,因为我们需要为不同的域提供不同的值.
如果可能的话,我宁愿避免使用会话变量,因为我们可能会在未来扩展到使用多个服务器,而且我听说这对会话不起作用.
如果您认为有更清晰的方式来表达我所追求的内容,请随时更新标签/标题.谢谢.
在每个请求的Web应用程序中维护状态的最佳方法是使用HttpContext类.
您需要将状态(LocalBranch)存储为一个Item在HttpContext:
HttpContext.Current.Items.Add("LocalBranch", GetLocalBranch());
Run Code Online (Sandbox Code Playgroud)
您可以在整个应用程序中获取所有项目,如下所示:
LocalBranch branch = HttpContext.Current.Items["LocalBranch"] as LocalBranch;
Run Code Online (Sandbox Code Playgroud)
该Items物业只是一个关键价值Dictionary.值是一个对象.您必须检查空值,这与Session您知道的对象非常相似.
主要区别在于范围.这HttpContext是一个点网络对象,具有http请求的生命周期.
现在使用HttpContext,我向你展示的方式是最简单的方法.
您可以前进两步并使用名为Unity的框架,并为您的对象添加生命周期.
Unity做得更多,终身管理只是一个宝石.
您可以创建自定义HttpContext生命周期,以便为每个请求生成对象.
像这样的东西.
他们所需要做的就是:
1.注册具有HttpContext生命周期的LocalBranch类.
2.添加一个静态Current属性,该属性将使用Unity容器并解析正确的实例LocalBranch.
3.使用这样的东西:LocalBranch.Current
顺便说一句,您可以使用Unity dependency injection将对象注入控制器和其他模块.这是一个更好的做法,然后只使用静态Current属性.
你在这里有两个问题.第一个是"如何根据HttpRequest创建此类的单个实例?" 第二个是"我如何将其用于强类型视图?"
@ amir-popovich几乎已经回答了第一个使用依赖注入的问题.但是,FWIW我可能会使用Ninject而不是Unity(只是偏好,真的),我可能会以不同的方式实现它.我不会使用HttpContext,只是构建一个服务(使用Ninject的OnePerHttpRequest模块进行实例化,将域作为参数传递以获取正确的值).
然后,为了将这些LocalBranch值添加到强类型视图模型,您可以先创建一个包含此类型的基本视图模型:
public class BaseViewModel
{
public LocalBranch Branch {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
然后,使所有当前视图模型继承此基本类型
public MyViewModel : BaseViewModel
{
public string SomeValue {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的控制器中,很容易从您从第一步创建的服务中添加这些值
public ActionResult SomeAction()
{
var vm = new MyViewModel();
vm.Branch = LocalBranchService.GetLocalBranchValues(); //Local Branch Service has been injected with Ninject
//do other stuff
return View(vm);
}
Run Code Online (Sandbox Code Playgroud)
但是,将其添加到每个控制器操作变得非常繁琐,因此您可以创建一个结果过滤器来为您添加它:
public class LocalBranchResultFilter : FilterAttribute, IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
//This method gets invoked before the ActionResult is executed.
filterContext.Controller.ViewData.Model.Branch = LocalBranchService.GetLocalBranchValues(); //Local Branch Service has been injected with Ninject
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用过滤器装饰Controller和/或Actions(如果需要,您甚至可以在全局过滤器中设置它).