CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

David Hayden [MVP C#]

         .NET Tutorials, Patterns, and Practices

Simplify Caching with Tag Matching Rule in Policy Injection Application Block

In my last post:

Simplify Caching using the Policy Injection Application Block: Aspect-Oriented Programming Opportunities

I gave an example of using the Policy Injection Application Block to remove the pre- and post-processing code that is associated with simple caching in your applications. The Policy Injection Application Block removed the clutter associated with caching from your code to better reveal its intention and simplify maintenance.

Before the Policy Injection Application Block:

 

public class Service : IService
{
    public Data GetData()
    {
        // Pre-Processing
        Are Results in Cache? If yes, return cached results.
        
        // Real-time Expensive Processing
        Nope. Get data from datastore.

        // Post-Processing
        Cache for X minutes and Return Results.
    }
}

 

After the Policy Injection Application Block:

 

public class Service : IService
{
    [CachingCallHandler(0, 30, 0)]
    public Data GetData()
    {   
        Get data from datastore.
    }
}

 

Tag Matching Rule

Using the CachingCallHandler we were able to cleanse our code, but we still need to change source code if we want to change the caching interval. Given that the caching interval on this particular method is expected to be volatile, it would be ideal to change the caching interval through meta-data in an external file that can be modified without requiring any source code changes. We also like the idea of an attribute on this method as a hint to other developers that caching is indeed happening here, but we aren't handling it in the method itself. The Tag Matching Rule in the Policy Injection Application Block provides us this wonderful capability.

Let's remove the CachingCallHandlerAttribute from the method and put a TagAttribute that will still invoke caching, but instead grab the caching interval from our Web.config file instead of in the attribute itself.

 

public class Service : IService
{
    [Tag("CacheResults")]
    public Data GetData()
    {   
        Get data from datastore.
    }
}

 

Now we will jump into the new Enterprise Library Visual Studio-Integrated Configuration Editor and configure our caching policy in the Web.config file.

 

Policy Injection Application Block Caching

 

Notice we still specify the interval as 30 minutes, but now it is in the Web.config where we can change it easily without changing source code and recompiling. We could have just as easily specified an external file other than Web.config as well.

The way we create this service has not changed. We still use the factory as opposed to creating it explicitly. Under the covers the Policy Injection Application Block may pass you a proxy class if it finds that you want it to intercept some method calls and do some pre- and post- processing. In this case it reads the policies in the Web.config, notices the TagAttribute on the GetData Method, and intercepts the call to do caching for you.

 

IService service = PolicyInjection.Create<Service,IService>();

 

What has changed is now we can modify the caching interval in the Web.config file without changing code. You can do it via the graphical editor or just change the XML yourself:

 

<add name="CachingPolicy">
    <matchingRules>
        <add match="CacheResults" name="Tag Attribute Matching Rule" />
    </matchingRules>
    <handlers>
        <add expirationTime="00:30:00" name="Caching Handler" />
    </handlers>
</add>

 

This is a nice way to manage caching intervals when you expect it to be volatile or you just want the option to change it via configuration.

 

Conclusion

Enterprise Library is a good tool for your toolbox when your applications could benefit from these types of features.

If you find yourself using the Policy Injection Application Block, there is an Effective Policy Viewer for the Policy Injection Application Block that can help you understand what policies are tied to classes when using configuration.

Don't forget about the Day of Patterns & Practices in Tampa, Florida on May 25th :) Register here.

by David Hayden

 



Comments

Ayende Rahien said:

You have just taken something that was very explicit, and turned it into implict.

You now have to worry about mispelling, case sensitivity, miscofiguration, etc.

In my opinion, you didn't gain anything from this.

# April 21, 2007 12:41 PM

David Hayden said:

I disagree 200%.

I gained the ability to change the caching interval in a configuration file while still maintaining a hint about caching being done via an attribute. I now don't have to change source code to change the caching interval, and a team of developers new to the Policy Injection Application Block can feel at ease that I am flagging policies until they feel comfortable about a configuration-only option which is my next post :)

Yes there are disadvantages ( case sensitivity not being one of them, however ), but this is definitely a great intermediate solution when a development team is new to the Policy Injection Application Block and doesn't want to hide the intentions about what is happening in code in a configuration file and a requirement is that the caching interval needs to be changed via configuration.

I would agree that it is not as explicit as the other attribute and a configuration only option, but don't broadly discount the option as I am sure it has merits even beyond the one I mention above.

# April 21, 2007 2:29 PM

Ayende Rahien said:

If there is a need to configure the caching interval from the configuration, why not:

[Cacheable]

It is explicit, clear, and doesn't take away anything.

My main objection is that you went from the explicit to the implicit. Now you no longer have a caching attribute, you have a tagged caching, etc.

I don't see the value here.

# April 22, 2007 5:25 AM

David Hayden said:

I guess the simple answer is because [Cacheable] does not exist in the Policy Injection Application Block and [Tag("...")] does exist.

# April 22, 2007 10:32 AM

Tom Hollander said:

You could easily build a [Cacheable] attribute and use the Custom Attribute Matching Rule to look for it. But at the end of the day I don't think this offers a lot of advantages over the Tag approach.

# April 22, 2007 6:11 PM
Check out Devlicio.us!

This Blog

Syndication

News

CodeBetter.Com Home