Enterprise Library In-depth analysis and flexible application (9): Personally feel more serious about cachingcallhandler bug
Microsoft Enterlib's Policy injection Application Block (PIAB) is a lightweight AOP framework that you can use to create custom Callhandler to implement certain crosscutting logic. and applied to the target method in a custom attribute or configuration. Piab itself also provides a series of Callhandler, in which Cachingcallhandler directly using the cache of httpruntime to implement a method-level based caching. However, Piab released to now, Cachingcallhandler has a problem: if the target method has an out parameter and the return type is not void, the IndexOutOfRangeException is thrown, and if the return type is void, Out parameters are also not cached. I don't know what Microsoft is thinking about this, anyway I think it's an unforgivable bug.
I. Recurring problems
This question is also reproduced, in order to compare us first to look at the normal situation of cachingcallhandler performance. Here I define a simple interface: Imembershipservice, which contains a method GetUserName returns user Name based on the incoming user ID. Membershipservice implements this interface, and in order to make sure that the results of the method execution are cached, I let each execution return a GUID. Cachingcallhandler is applied directly to the GetUserName method in the form of custom attributes.
1: using System;
2: using System.Threading;
3: using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;
4: namespace CachingCallHandler4OutParam
5: {
6: public interface IMembershipService
7: {
8: string GetUserName(string userId);
9: }
10:
11: public class MembershipService : IMembershipService
12: {
13: [CachingCallHandler]
14: public string GetUserName(string userId)
15: {
16: return Guid.NewGuid().ToString();
17: }
18: }
19: }
Now, in the main method, write the following code: through Policyinjection's Create<ttype, Tinterface> creates a proxy object that can be intercepted by Piab, and passing the same arguments in an infinite loop to invoke the GetUserName method. From the output we see that the returned username are the same, thus proving that the results of the first execution are cached successfully.
1: using System;
2: using System.Threading;
3: using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;
4: namespace CachingCallHandler4OutParam
5: {
6: class Program
7: {
8: static void Main(string [] args)
9: {
10: IMembershipService svc = PolicyInjection.Create<MembershipService, IMembershipService>();
11: while(true)
12: {
13: Console.WriteLine(svc.GetUserName("007"));
14: Thread.Sleep(1000);
15: }
16: }
17: }
18: }
Output results:
E1E8EA0F-7620-4879-BA5D-33356568336E
E1E8EA0F -7620-4879-BA5D-33356568336E
E1E8EA0F-7620-4879-BA5D-33356568336E
E1E8EA0F-7620-4879-BA5D-33356568336E
E1E8EA0F-7620-4879-BA5D-33356568336E
E1E8EA0F-7620-4879-BA5D-33356568336E