AOP through Unity interceptors - Logging

The first thing we think when talking about interception is logging. Let's see an implementation of a Logger.

But before introducing the Logger implementation, let us scaffold a console sample project.

public interface IFoo
    {
        FooItem GetItem(string name);
    }

    public interface IStore
    {
        StoreItem Get(int id);

        IEnumerable<StoreItem> GetAll();

        void Save(StoreItem item);
       
        void ThrowException();
    }

    public class FooImpl : IFoo
    {
        public FooItem GetItem(string name)
        {
            return new FooItem { Name = name };
        }
    }

    public class StoreImpl : IStore
    {
        public StoreItem Get(int id)
        {
            Thread.Sleep(1000);
            return new StoreItem { Id = id, Name = "Fake name" };
        }

        public IEnumerables<StoreItem> GetAll()
        {
            Thread.Sleep(2000);

            return new List&ltStoreItem>()
            {
                new StoreItem {Id = 1, Name = "Fake Item 1"},
                new StoreItem {Id = 2, Name = "Fake Item 2"},
                new StoreItem {Id = 3, Name = "Fake Item 3"}
            };
        }

        public void Save(StoreItem item)
        {
            Thread.Sleep(1500);
        }

        public void ThrowException()
        {
            Thread.Sleep(500);
            throw new Exception("Sample exception");
        }
    }

    public class FooItem
    {
        public string Name { get; set; }
    }

    public class StoreItem
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

Now we can play with unity. In the Program.cs, write this:

static void Main(string[] args)
        {
            using (var container = new UnityContainer())
            {
                container.AddNewExtension<Interception>();

                // Register
                container.RegisterType<IStore, Storeimpl>(
                    new Interceptor<InterfaceInterceptor>(),
                    new InterceptionBehavior<LoggingInterceptionBehavior>());

                container.RegisterType<IFoo fooimpl="">(
                    new Interceptor(),
                    new InterceptionBehavior<LoggingInterceptionBehavior>());

                // Resolve
                IStore store = container.Resolve<IStore>();
                IFoo foo = container.Resolve<IFoo>();

                // Call
                store.Get(1);
                store.Get(2);
                store.Get(1);
                store.GetAll();
                store.Save(null);

                try
                {
                    store.ThrowException();
                }
                catch { }

                foo.GetItem("Whatever");

                Console.WriteLine("END");
                Console.ReadLine();
            }
        }

Finally, here is the implementation of the LoggingInterceptionBehavior:

public class LoggingInterceptionBehavior : IInterceptionBehavior
    {
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            var arguments = JsonConvert.SerializeObject(input.Arguments);
            WriteLog(String.Format("Invoking method {0}", input.MethodBase), arguments);

            var result = getNext()(input, getNext);

            if (result.Exception != null)
            {
                WriteLog(String.Format("Method {0} threw exception {1}", input.MethodBase, result.Exception.Message));
            }
            else
            {
                var returnValue = JsonConvert.SerializeObject(result.ReturnValue);
                WriteLog(String.Format("Method {0} returned successfully", input.MethodBase), returnValue);
            }

            return result;
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public bool WillExecute
        {
            get { return true; }
        }

        private void WriteLog(string message, string args = null)
        {
            var utcNow = DateTime.UtcNow;

            Console.WriteLine(
                "[{0}]-[{1}]: {2} {3}",
                utcNow.ToShortDateString(),
                utcNow.ToLongTimeString(),
                message,
                args);
        }
    } 

Comments

Popular posts from this blog

EMGU with Xamarin Forms guide [part 1]

[Xamarin Forms] Custom bottom bordered entry (iOS & Android)

Xamarin.Forms device unique ID...