Question

I'm not sure if this can be done, as logically it doesn't make sense to me. I've been testing out Postsharp aspects and AOP in general, and I can greatly see the benefits they can bring to a codebase.

I use RavenDB (document database) and sometimes I have 'tasks' which basically they would have to create a session object, do some logic, and then call session.SaveChanges() after. This would be extremely beneficial for a TaskAspect which would basically do the session creation and calls .SaveChanges() after.

The main issue is that sometimes, when new documents are created in the business logic, one needs to call session.Store(newObject). The issue is that the session is not available in the actual method, as it would have been created in the MethodInterceptionAspect.

Below is a very basic TaskAspect implementation and sample logic:

[Serializable]
public class TaskAspect : MethodInterceptionAspect
{
    public override void OnInvoke(MethodInterceptionArgs args)
    {
        var session = RavenUtil.CreateSession();

        args.Proceed();

        session.SaveChanges();
        session.Dispose();
        base.OnInvoke(args);
    }

}

public class SampleLogic
{
      [TaskAspect]
      public void CreateItem()
      {
            var product = new Product();
            session.Store(product);   //<---- how can I obtain this session, as it is created in the aspect??

      }


}

The issue as you can see is that the call to args.Proceed() doesn't know about the session. Any ideas how one can pass such information? Does it make sense first of all, or is this logic flawed and I shouldn't be using aspects for this?

One thought that came to mind was to store the session in a ThreadStatic variable, but I think it is very 'ugly'.

Était-ce utile?

La solution

As you mentioned, you could use a [ThreadStatic] field (the type would probably need to be Stack<Session>).

You could also define a parameter in your method (perhaps set a default null value) and have the aspect set the parameter before calling Proceed. To set the parameter, use args.Arguments.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top