This time I would like to familiarize you with two interesting concepts of Unity (IoC Container) which you can find very useful.
Interceptors allow programmers to run some functionality before or after a selected piece of code. This approach is called Aspect-Oriented Programming (AOP) and its main goal is to increase modularity through separation of cross-cutting concerns e.g. logging messages before and after a code execution. The following example shows how easy you can apply logging in a method using a [MethodHandler()] attribute.
ServiceLocator is an excellent concept of the Unity but I do not like the fact that it can be easily abused and overdosed. An example below shows two different approaches for creating an instance of a Logger class. First one is using constructor injection and the second one is using ServiceLocator (have a look at the constructors). The only one case scenario when ServiceLocator seems to be very useful is a situation when we have a class created outside of the Unity and this class needs access to the other types registered in a container. An example below shows how to make ServiceLocator aware of the Unity.
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: IUnityContainer unity = new UnityContainer();
6: UnityServiceLocator locator = new UnityServiceLocator(unity);
7: ServiceLocator.SetLocatorProvider(() => locator);
8:
9: unity.AddNewExtension<Interception>();
10: unity.RegisterType<ILogger, Logger>();
11: unity.RegisterType<ITest, Test>().Configure<Interception>().SetDefaultInterceptorFor<ITest>(new InterfaceInterceptor());
12:
13: unity.Resolve<ITest>().Execute();
14: Console.ReadKey();
15: }
16: }
17:
18: public class Test : ITest
19: {
20: public void Execute()
21: {
22: Console.WriteLine("Execute Method Body");
23: }
24: }
25:
26: public interface ITest
27: {
28: [MethodHandler()]
29: void Execute();
30: }
31:
32: public class CallHandler : ICallHandler
33: {
34: private IUnityContainer _container;
35: private ILogger _logger;
36:
37: public CallHandler(IUnityContainer container, ILogger logger)
38: {
39: _logger = logger;
40: }
41:
42: public CallHandler()
43: {
44: _logger = ServiceLocator.Current.GetInstance<ILogger>();
45: }
46:
47: public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
48: {
49: _logger.LogPreMessage(input.MethodBase.Name);
50: IMethodReturn methodReturn = getNext()(input, getNext);
51: _logger.LogPostMessage(input.MethodBase.Name);
52: return methodReturn;
53: }
54:
55: public int Order
56: {
57: get;
58: set;
59: }
60: }
61:
62: public class MethodHandlerAttribute : HandlerAttribute
63: {
64: public MethodHandlerAttribute()
65: {
66: }
67:
68: public override ICallHandler CreateHandler(IUnityContainer container)
69: {
70: return new CallHandler(container);
71: }
72: }
73:
74: interface ILogger
75: {
76: void LogPreMessage(string msg);
77: void LogPostMessage(string msg);
78: }
79:
80: class Logger : ILogger
81: {
82: public void LogPreMessage(string msg)
83: {
84: Console.WriteLine("Pre -> " + msg);
85: }
86:
87: public void LogPostMessage(string msg)
88: {
89: Console.WriteLine("Post -> " + msg);
90: }
91: }
92: }
Useful links: