我正在使用ravendb
作为存储后端。由于它使用unit of work
模式,我需要打开会话,执行操作,保存结果和关闭会话。我想保持我的代码干净,不要在每个操作中明确地调用会话打开和关闭,因此我将此代码放到OnActionExecuting
和OnActionExecuted
方法中,如下所示:
#region RavenDB's specifics
public IDocumentSession DocumentSession { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.IsChildAction)
{
return;
}
this.DocumentSession = Storage.Instance.OpenSession();
base.OnActionExecuting(filterContext);
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.IsChildAction)
{
return;
}
if (this.DocumentSession != null && filterContext.Exception == null)
{
this.DocumentSession.SaveChanges();
}
this.DocumentSession.Dispose();
base.OnActionExecuted(filterContext);
}
#endregion
但是某些操作需要连接到ravendb
而不是。{所以我决定创建自定义属性和标记方法需要使用它打开DocumentSession。这是一个例子:
//
// GET: /Create
[DataAccess]
public ActionResult Create()
{
return View();
}
我卡住了。我的计划是在OnActionExecuted
方法中检索操作属性,如果存在[DataAccess]
,请打开DocumentSession
。
在OnActionExecuted
我可以通过filterContext.ActionDescriptor.ActionName
语句检索操作名称(方法名称)。但是我如何使用反射检索给定类的方法属性?
我发现它可能是Attribute.GetCustomAttributes
调用,但最接近我 - 我需要拥有该方法的MemberInfo
对象。但是我怎么能得到MemberInfo
这个名字给出的方法呢?
答案 0 :(得分:4)
如果从FilterAttribute继承自定义属性,它将具有OnActionExecuted和OnActionExecuting方法。它将在一般的OnActionExecuted和OnActionExecuting之前执行。
示例:
public class DataAccessAttribute: FilterAttribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.IsChildAction)
{
return;
}
var controller = (YourControllerType)filterContext.Controller;
controller.DocumentSession = Storage.Instance.OpenSession();
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.IsChildAction)
{
return;
}
var controller = (YourControllerType)filterContext.Controller;
documentSession = controller.DocumentSession;
if (documentSession != null && filterContext.Exception == null)
{
documentSession.SaveChanges();
}
documentSession.Dispose();
}
答案 1 :(得分:1)
为什么不让DataAccess
属性继承自ActionFilterAttribute,以便将ActionExecuting / Executed方法放在属性而不是Controller上?
Example of how to do it with NHibernate使用动作过滤器在基本控制器上设置会话。它是使用NHibernate完成的,但非常类似于你需要做的事情,它是由Ayende编写的,他是我相信的RavenDB作者之一。