6

Interceptor

public class CachingInterceptor : IInterceptor
{

    public void Intercept(IInvocation invocation)
    {
       // code comes here.... 
    }

}

Business Layer

public class Business : IBusiness
{
     public void Add(string a)
        {

             var t= GetAll();             
             // code comes here.... 

        }

     [CacheAttribute]
     public string GetAll()
        {
             // code comes here.... 

        }

}

Class

public class JustForTest
{

     public JustForTest(IBusiness business)
            {

               //if GetAll is invoked directly caching works fine.
               business.GetAll();

               //if GetAll is invoked over Add method caching doesn't work.
               business.Add();                      

            }

  }

add method calls GetAll method. If I invoke GetAll method directly, caching works. If Add method calls GetAll Method, caching doesn't work.

Thank You for helping.

  • You should resolve the `Business` instance from the `container` and not `new` it up yourself. – qujck Jul 07 '15 at 08:25
  • Than you qujck. Actually I did it. I just want to make the code simple. I used installer for implementation. – Murat Cabuk Jul 07 '15 at 08:31

2 Answers2

4

Interface proxies are created by wrapping proxy target object so with interfaces this is not possible.

You can intercept calls on the same objects, but only for class proxy (provided the method is virtual). See answer to a similar question.

You could also try to structure your code differently, move logic that needs to be cached to services that can be cached without using it's own functions.

Community
  • 1
  • 1
Jakob
  • 536
  • 4
  • 16
  • YEs, It seems not easy but It should be some way. I couldn't find any solution. Everybody calls the method directly. :| – Murat Cabuk Jul 07 '15 at 10:03
  • Thank you Jacob. I checked your answer. Actually i'm not professional in Castle. is it ok just modifying my method as virtual. Also I read Krzysztof's answer but it is not clear. – Murat Cabuk Jul 07 '15 at 12:57
  • You can mark the method as virtual but then your client needs to depend on the concrete type and not the interface. A bit ugly and untestable. I would try to change the architecture. – Jakob Jul 07 '15 at 13:09
4

The problem here is that the line

var t= GetAll();

is inside the class Business. It can be more clearly written as

var t = this.GetAll();

this is not an intercepted/wrapped instance.

Try dividing the responsibilities of the Business class as suggested here and here

qujck
  • 14,388
  • 4
  • 45
  • 74
  • thank you, I see what you mean. I shouldn't call GetAll() inside Add() method. However I don't have any idea. – Murat Cabuk Jul 07 '15 at 13:04
  • I assume `GetAll` is a query that returns some data. If `GetAll` was a separate class (a query) that was injected into `Business` then you would not have the problem you are faced with. – qujck Jul 07 '15 at 13:40
  • I will put GetAll Method in seperate class. Thank you Jacob and Qujck. – Murat Cabuk Jul 07 '15 at 14:44
  • 2
    @MuratCabuk: If you read the adviced articles, you don't even need interception at all. You can do this in a much more clean and elegant way using decorators. – Steven Jul 07 '15 at 20:07