Using EntLib5.0 (unity+interception+caching) to implement the Caching mechanism available in the project

Source: Internet
Author: User

See a lot of the garden introduction caching articles, most of them only introduce the basic mechanism, for the cache update and dependency part, is simply to implement the Icacheitemrefreshaction interface, which in the actual project is far from enough. In the actual project, the following 3 points should be considered at least:

    1. External data: Data that is taken from other systems through external services. We can't control it, and we don't know when it's going to be updated. For this part of the data, we use a timed update policy, the default 1 hours Update 1 times, configurable.
    2. Internal data: The data generated by the system itself can be fully controlled. For this part of the data, we implement the Icacheitemrefreshaction interface, once invalid, immediately re-fetch.
    3. How the internal data triggers the update: Which actions trigger which cache invalidation, such as add/delete/update[user][s]->get[user][s] failure, should be configurable.

then proceed separately.

0. Preface

The following discussion is divided into 2 chunks, one of which is the construction of the environment, including using unity to provide service instances + interception with unity. After this piece, you can realize caching in the way of AOP, this part of the garden is a lot of articles, I briefly pass a bit. The second is the implementation of caching, respectively, from the external data cache + Internal cache + Internal trigger Update 3 part to discuss.

1, the construction of the environment

1.1. Using Unity to provide service examples

This part is actually using unity to achieve iinstanceprovider, and then with Iendpointbehavior and the like, to achieve the integration of WCF and unity. The core code is as follows:

1  Public class unityinstanceprovider:iinstanceprovider{2    Public Object getinstance (InstanceContext context, Message msg) {3     return UnityWrapper.Instance.Resolve (servicetype); 4   }5 }

See Artech for a follow-up tour of WCF (7): Integration with the Enterprise Library Unity container through the WCF extension implementation.

1.2. Provide interception (ie piab,policyinjection) with unity

We're going to have to spit it out here first. EntLib, backwards compatibility is too poor, completely does not conform to the usual style of Microsoft. Each big version on a bunch of breaking changes and deprecated, really a bit depressed. Of course, they also have difficulties, such as EntLib6 in the caching, is included in the NET40, indeed can only give up. All right, back to the chase. Fortunately, EntLib's own Help documentation is very detailed , the problem should be prioritized to manual to see the relevant content.

EntLib4.1 's Piab module, in EntLib5, was completely based on Unity's interception, which was simply canceled in EntLib6. Here we use the configuration in the ENTLIB5 to implement the policy injection, the core configuration is as follows:

1 <Unity>2 <sectionextensiontype= "Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration "/>3 <Assemblyname= "Service"/>4 <namespacename= "Service"/>5 <aliasalias= "Cachingcallhandler"type= "Service.Unity.CachingCallHandler, Service"/>6 <Containername= "UnityContainer">7   <extensiontype= "interception" />8   <interception>9     <Policyname= "Caching">Ten       <Matchingrulename= "Allservicematch"type= "Namespacematchingrule"> One         <Constructor> A           <paramname= "NamespaceName"value= "Service"/> -         </Constructor> -       </Matchingrule> the       <Callhandlername= "Cachingservice"type= "Cachingcallhandler"/> -     </Policy> -   </interception> -   <Registertype= "IService1"> +     <Interceptortype= "Transparentproxyinterceptor" /> -     <policyinjection/> +   </Register> A </Container> at </Unity>

Here is a detail, for the convenience of configuration, 1 is available in EntLib with the entlibconfig.exe,2 is in the VS menu->xml-> architecture, Add unityconfiguration20.xsd or EnterpriseLibrary.Configuration.xsd, so there's a smart tip. If you cannot find an. xsd file in the EntLib installation directory, you can use everything to search for it.

2, the realization of caching

2.1. External Data cache

External data is our uncontrolled data and when updates are uncertain. We take a time-updated strategy, the frequency of the update depends mainly on the frequency of external data changes, such as our project depends on the external data base, change less, so only 1 hours or even half a day to update.

Originally, I thought absolutetime was what I wanted. (Note: Slidingtime is the first time a user hits the cache and then slips for a period of time before it expires), but it is only known by Ilspy to view the internal code. EntLib does not automatically trigger the Icacheitemrefreshaction interface when the user accesses the cache, and then determines whether the time expires, if it expires, and then triggers the refreshaction. The code is as follows:

1 namespacemicrosoft.practices.enterpriselibrary.caching{2  Public classcache{3  Public ObjectGetData (stringkey) {4   if(cacheitem.hasexpired ()) {5      This. Inmemorycache.remove (key);6Refreshactioninvoker.invokerefreshaction (CacheItem, cacheitemremovedreason.expired, This. Instrumentationprovider);7      This. instrumentationprovider.firecacheexpired (1L);8}}}}

This kind of user experience is certainly a little bit worse, not to allow users to enjoy the full benefits of caching, we use a Timer to automatically update the cache, note that you should be using System.Threading.Timer instead of System.Timers.Timer. The code is as follows://We use custom Timercacheattribute to identify such methods

1 varAtts = input. Methodbase.getcustomattributes (typeof(Timercacheattribute),false);2 if(Atts. Length >0){3Refreshtimerutil.instance[key] =NewTimer (E = {4     Object[] args = E as Object[];5     if(args = =NULL|| Args. Length! =2)return;6 7     varTmpinput = args[0] asimethodinvocation;8     varTmpnext = args[1] asgetnexthandlerdelegate;9     varTmpreturn =Tmpnext (Tmpinput, tmpnext);Ten     if(Tmpreturn.exception = =NULL) { One CacheWrapper.Instance.Add (key, tmpreturn.returnvalue); A     } -   }, -   New Object[] {input, getNext}, the TimeSpan.Zero, -   NewTimeSpan (1,0,0)); -}

2.2. Internal data cache

Internal data can be directly inserted into the cache, and then quietly waiting for additions and deletions to change the operation to set it to expire.

1 CacheWrapper.Instance.Add (Key, Methodreturn.returnvalue,2  cacheitempriority.normal,  3   new cacherefreshaction {input = input, GetNext = GetNext});

Of course, to implement the Icacheitemrefreshaction interface, the code is as follows:

1 [Serializable]2  Public classcacherefreshaction:icacheitemrefreshaction {3    PublicImethodinvocation Input {Get;Set;}4    PublicGetnexthandlerdelegate GetNext {Get;Set;}5    Public voidRefresh (stringRemovedkey,ObjectExpiredvalue, CacheItemRemovedReason Removalreason) {6     if(Input = =NULL|| GetNext = =NULL)return;7     varMethodreturn =GetNext () (Input, GetNext);8     if(Methodreturn.exception = =NULL) {9 CacheWrapper.Instance.Add (Removedkey, Methodreturn.returnvalue,Ten Cacheitempriority.normal, One         Newcacherefreshaction {input = input, GetNext =GetNext}); A     } -   } -}

It is said that MemoryCache does not need to implement ISerializable, while the other caching either implement ISerializable or hit [Serializable] tags. However, this way of implementation, Imethodinvocation and getnexthandlerdelegate visual serialization are slightly troublesome, fortunately, we only use the MemoryCache, you can first regardless of, and then break through.

2.3. Internal data Trigger Update

Finally, there is a trigger update, how to achieve similar add/delete/update[user][s]->get[user][s] effect? The general idea is: 1) determine whether the method name Startwith keyword (add/delete/update), 2) intercept the target keyword user, and generate the corresponding complex form users;3) and get and other actions stitching into cachekey, All hit CacheKey are set to expire (Cachemanager.remove) to trigger the corresponding refreshaction. The code is as follows:

1 varentity =string. Empty;2 foreach(varActinchconfigutil.action) {3   if(Methodname.startswith (Act)) {4entity =methodname.substring (Act. Length);5      Break;6 }}7 8 varentities =pluralutil.pluralize (entity);9 if(entities = = entity) entities =pluralutil.singularize (entity);Ten foreach(varPrefixinchconfigutil.prefix) { OneCacheWrapper.Instance.RemoveStartWith (prefix +entity); ACacheWrapper.Instance.RemoveStartWith (prefix +entities); -}

Here the generation of the complex code is borrowed from EntityFramework, please see Englishpluralizationservice.

If there is an incorrect place, please criticize it!

Using EntLib5.0 (unity+interception+caching) to implement the Caching mechanism available in the project

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.