castle windsor interceptor on method that is calling by another method
Asked Answered
S

2

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.

Shriver answered 7/7, 2015 at 8:2 Comment(2)
You should resolve the Business instance from the container and not new it up yourself.Elenoraelenore
Than you qujck. Actually I did it. I just want to make the code simple. I used installer for implementation.Shriver
T
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.

Tremolite answered 7/7, 2015 at 9:9 Comment(3)
YEs, It seems not easy but It should be some way. I couldn't find any solution. Everybody calls the method directly. :|Shriver
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.Shriver
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.Tremolite
E
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

Elenoraelenore answered 7/7, 2015 at 11:1 Comment(4)
thank you, I see what you mean. I shouldn't call GetAll() inside Add() method. However I don't have any idea.Shriver
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.Elenoraelenore
I will put GetAll Method in seperate class. Thank you Jacob and Qujck.Shriver
@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.Lockridge

© 2022 - 2024 — McMap. All rights reserved.