2

ravendbストレージのバックエンドとして使用しています。パターンを使用してunit of workいるため、セッションを開いてアクションを実行し、結果を保存してセッションを閉じる必要があります。私は自分のコードをきれいに保ちたいので、各アクションで明示的にセッションの開始と終了を呼び出さないようにしたいので、このコードを次のようにOnActionExecutingandOnActionExecutedメソッドに配置します。

    #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]存在する場合は open にすることDocumentSessionでした。

では、ステートメントOnActionExecutedを介してアクション名 (メソッド名) を取得できます。filterContext.ActionDescriptor.ActionNameしかし、リフレクションを使用して特定のクラスのメソッドの属性を取得するにはどうすればよいですか?

Attribute.GetCustomAttributesそれが呼び出しである可能性があることがわかりましたが、最も近いMemberInfoのはメソッドのオブジェクトが必要です。MemberInfoしかし、名前で指定されたメソッドでこれを取得するにはどうすればよいですか?

4

2 に答える 2

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();
}
于 2012-10-25T08:41:17.863 に答える
1

コントローラーの代わりに属性に ActionExecuting/Executed メソッドを配置できるように、DataAccess属性をActionFilterAttributeから継承しないのはなぜですか?

NHibernateでアクション フィルターを使用してベース コントローラーにセッションを設定する方法の例。これは NHibernate を使用して行われますが、必要なことと非常によく似ており、RavenDB の作成者の 1 人である Ayende によって書かれています。

于 2012-10-25T08:40:55.163 に答える