Skip to content

Instantly share code, notes, and snippets.

@Rookian
Created September 3, 2012 18:40
Show Gist options
  • Save Rookian/3612026 to your computer and use it in GitHub Desktop.
Save Rookian/3612026 to your computer and use it in GitHub Desktop.
Dynamic Interception
public class RepositoryInterceptor : IInterceptor
{
private readonly MemoryCache _memoryCache;
public RepositoryInterceptor()
{
_memoryCache = new MemoryCache("repositoryCache");
}
public void Intercept(IInvocation invocation)
{
var cacheKey = GenerateCacheKey(invocation.Method.Name, invocation.Arguments);
if (_memoryCache.Get(cacheKey) != null)
{
invocation.ReturnValue = _memoryCache[cacheKey];
return;
}
invocation.Proceed();
_memoryCache[cacheKey] = invocation.ReturnValue;
}
private static string GenerateCacheKey(string methodName, ICollection arguments)
{
if (arguments == null || arguments.Count == 0)
return methodName;
var argumentsKey = JsonConvert.SerializeObject(arguments);
return methodName + "#" + argumentsKey;
}
}
@Rookian
Copy link
Author

Rookian commented Sep 3, 2012

Type is not expected, and no contract can be inferred: CachingWithDynamicProxy.ByIdSpecification

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Caching;
using Castle.DynamicProxy;
using ProtoBuf;
using StructureMap;

namespace CachingWithDynamicProxy
{
class Program
{
static void Main()
{
var container = new Container();
Booting(container);

        var personService = container.GetInstance<PersonService>();

        personService.DoSomething();
        personService.DoSomethingElse();
    }

    private static void Booting(Container container)
    {
        container.Configure(config =>
        {
            var proxyGenerator = new ProxyGenerator();

            config.For<IRepository>().EnrichAllWith(
                repository => proxyGenerator.CreateInterfaceProxyWithTarget(repository, new RepositoryInterceptor())).
                Use<Repository>();
        });
    }
}

public class RepositoryInterceptor : IInterceptor
{
    private readonly MemoryCache _memoryCache;

    public RepositoryInterceptor()
    {
        _memoryCache = new MemoryCache("repositoryCache");
    }

    public void Intercept(IInvocation invocation)
    {
        var cacheKey = GenerateCacheKey(invocation.Method.Name, invocation.Arguments);
        if (_memoryCache.Get(cacheKey) != null)
        {
            invocation.ReturnValue = _memoryCache[cacheKey];
            return;
        }
        invocation.Proceed();

        _memoryCache[cacheKey] = invocation.ReturnValue;
    }

    private static string GenerateCacheKey(string methodName, ICollection arguments)
    {
        if (arguments == null || arguments.Count == 0)
            return methodName;

        using (var memoryStream = new MemoryStream())
        {
            Serializer.Serialize(memoryStream, arguments);
            var argumentsKey = Convert.ToBase64String(memoryStream.ToArray());

            return methodName + "#" + argumentsKey;
        }
    }
}

public class PersonService
{
    private readonly IRepository _repository;

    public PersonService(IRepository repository)
    {
        _repository = repository;
    }

    public void DoSomething()
    {
        var person = _repository.GetBySpecification(
            new ByIdSpecification
                {
                    Id = 1,
                    Persons = new List<Person>(new[]
                        {
                            new Person
                                {
                                    Id = 2
                                },
                            new Person {Id = 1}
                        })
                });
    }

    public void DoSomethingElse()
    {
        var person = _repository.GetBySpecification(
            new ByIdSpecification
                {
                    Id = 1,
                    Persons = new List<Person>(new[]
                        {
                            new Person
                                {
                                    Id = 2
                                },
                            new Person
                                {
                                    Id = 1
                                }
                        })
                });
    }
}

[Serializable]
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}

[Serializable]
public class Address
{
    public string Street { get; set; }
    public int Number { get; set; }
    public string Citry { get; set; }
}


public interface IRepository
{
    Person GetById(int id);
    IEnumerable<Person> GetAll();
    Person GetBySpecification(ByIdSpecification byIdSpecification);
}

public class Repository : IRepository
{
    private readonly List<Person> _inMemoryList;

    public Repository()
    {
        _inMemoryList = new List<Person>
        {
            new Person { Id = 1, Name = "Alex" }, 
            new Person { Id = 2, Name = "Thomas" }
        };
    }

    public Person GetById(int id)
    {
        return _inMemoryList.FirstOrDefault(x => x.Id == id);
    }

    public Person GetBySpecification(ByIdSpecification byIdSpecification)
    {
        return _inMemoryList.FirstOrDefault(x => x.Id == byIdSpecification.Id);
    }

    public IEnumerable<Person> GetAll()
    {
        return _inMemoryList;
    }
}

public class ByIdSpecification
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Person> Persons { get; set; }
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment