Interceptor pattern can be used for addressing cross cutting
concerns in the application that happens at either the beginning or end of a
method. For e.g. checking the validity of the input parameters before executing
the method and throwing exceptions, catching and logging exceptions etc. These
situations can be encapsulated in a reusable component that can be processed by
the compiler and produce executable code (AOP).
Unity allows developers to implement the idea of
interception by allowing creation of objects that can add some extra code on
the target method before or after the regular execution of these target
methods. In this post, I'll show how to create a Session handler for ASP.Net
using the interface interception mechanism provided by unity application block,
that will allow you to address encapsulate the logic for checking session for a
value before execution of the method and returning back the value from session
if available. The same handler can be used to also add the return value to the
session if not available so that this value can be retrieved next time.
Creating the session handler
public class SessionHandler : ICallHandler
{
private readonly string _sessionKey;
public SessionHandler(string
sessionKey)
{
_sessionKey = sessionKey;
}
public ISessionService
SessionService
{
get { return Container.Instance.Resolve<ISessionService>(); }
}
public IMethodReturn
Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
if (SessionService.Contains(_sessionKey))
{
input.CreateMethodReturn(SessionService.Get(_sessionKey));
return getNext()(input, getNext);
}
var returnValue = getNext()(input, getNext);
SessionService.Add(_sessionKey,
returnValue.ReturnValue);
return returnValue;
}
public int Order { get; set; }
}
The session handler uses the session service which
encapsulates the actual Session object to add/ remove values from the
session. You can also use the
HttpContext.Current.Session object here.
Creating the Attribute for the handler
public class SessionDependencyAttribute : HandlerAttribute
{
private readonly string _sessionKey;
public SessionDependencyAttribute(string sessionKey)
{
_sessionKey = sessionKey;
}
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new SessionHandler(_sessionKey);
}
}
Creating a service and using the SessionHandler we created.
public interface IMockService
{
[SessionDependency("TestKey")]
string GetValue(bool
flag);
}
public class MockService : IMockService
{
public string
GetValue(bool flag)
{
return flag ? "True"
: "False";
}
}
Configuring the Unity container
_container = new UnityContainer();
_container.AddNewExtension<Interception>();
_container
.RegisterType<ISessionService, SessionService>()
.RegisterType<IMockService, MockService>()
.RegisterType<MockPresenter>()
.Configure<Interception>().SetDefaultInterceptorFor<IMockService>(new
InterfaceInterceptor());
Test cases
[TestMethod]
public void
MethodShouldReturnValueFromSessionIfValueDoesNotExistsAndAddToSession()
{
var service = Container.Instance.Resolve<IMockService>();
var actual = service.GetValue(true);
Assert.IsTrue(SessionService.Contains("TestKey"));
}