2013-02-15 12 views
5

मैं अपने Application_Start में यह है:एएसपी.नेट एमवीसी और मेमोरी कैश - मैं इसका उपयोग कैसे करूं?

var crumbsCache = new MemoryCache("breadCrumbsNames"); 
var crumbsList = new List<CacheItem> 
        { 
         //list of new CacheItem(); 
        }; 
foreach (var cacheItem in crumbsList) 
{ 
    crumbsCache.Add(cacheItem, new CacheItemPolicy()); 
} 

अब, मेरी नियंत्रकों में मैं यह कर रहा हूं:

var cache = new MemoryCache("breadCrumbsNames"); 
var cacheItem = cache.GetCacheItem("nameOfCacheItem"); 

लेकिन तब cacheItem हमेशा रिक्त है, क्या मैं गलत कर रहा हूँ?

+0

इस चेक http://www.deanhume.com/home/blogpost/object-caching----net -4/37 – Mate

उत्तर

8

आप प्रत्येक नियंत्रक में MemoryCache का एक नया उदाहरण बना रहे हैं। चूंकि यह नया है, इसमें कुछ भी नहीं है, यही कारण है कि आप मूल्य हमेशा शून्य होते हैं। आपको उसी उदाहरण तक पहुंचने की आवश्यकता है जिसे आपने Application_Start में बनाया था। MemoryCache.Default का उपयोग करने में देखें।

+0

लेकिन वास्तव में 'MemoryCache.Default' क्या है? अगर मैं memcache के दो अलग-अलग उदाहरण स्थापित करूंगा, तो 'MemoryCache.Default' कैसे पता चलेगा कि कौन सा डिफ़ॉल्ट है? – ojek

+0

मेमोरी कैश सेट करें।आप जिस उदाहरण का उपयोग करना चाहते हैं उसके बराबर डिफ़ॉल्ट। –

10

मुझे लगता है कि आपके लिए एक बेहतर विकल्प Ninject या कुछ अन्य निर्भरता इंजेक्शन ढांचे का उपयोग करना होगा ताकि आपके MemoryCache को नियंत्रकों में आवश्यकतानुसार इंजेक्ट किया जा सके।

आप अपने एएसपी.नेट एमवीसी प्रोजेक्ट में Ninject और Ninject.Mvc3 (और कोई अन्य संबंधित बिट्स) जोड़कर शुरू करेंगे। यदि आप विजुअल स्टूडियो में काम कर रहे हैं, तो आप ऐसा करने के लिए NuGet का उपयोग कर सकते हैं। यह काफी दर्द रहित और अच्छी तरह से स्वचालित है।

public interface IMemoryCacheService 
{ 
    MemoryCache MemoryCache 
    { 
     get; 
     set; 
    } 
} 

और::

अगले कदम के रूप में एक अंतरफलक के कुछ प्रकार में अपने MemoryCache रैप करने के लिए, हो जाएगा

public class MemoryCacheService : IMemoryCacheService 
{ 
    public MemoryCacheService() 
    { 
     MemoryCache = new MemoryCache(); 
    } 

    public MemoryCache MemoryCache 
    { 
     get; 
     set; 
    } 
} 

तो फिर तुम एक Ninject भीतर बाध्यकारी परिभाषित ताकि Ninject जानता है जब आपको IMemoryCacheService के प्रकार की आवश्यकता होती है, तो आपको MemoryCacheService का उदाहरण देना चाहिए।

मैं यहां अपना खुद का निंजा कॉन्फ़िगर क्लास पेस्ट कर दूंगा। जो आपके प्रोजेक्ट में बनाया जाएगा वह बहुत ही समान होगा और App_Start नामक फ़ोल्डर में होगा (यदि आप NuGet का उपयोग करते हैं तो स्वचालित रूप से बनाया जाएगा)। जिस श्रेणी को निनजेक्ट डिफ़ॉल्ट रूप से बनाता है उसे NinjectWebCommon कहा जाता है।

public class HomeController : Controller 
{ 
    public ActionResult Foo() 
    { 
     ... 
    } 

    ... 
} 

लिए:

public static class NinjectConfig 
{ 
    private static readonly Bootstrapper bootstrapper = new Bootstrapper(); 

    public static void Start() 
    { 
     DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); 
     DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); 

     bootstrapper.Initialize(CreateKernel); 
    } 

    public static void Stop() 
    { 
     bootstrapper.ShutDown(); 
    } 

    private static IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 

     kernel.Bind<Func<IKernel>>() 
       .ToMethod(context =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>() 
       .To<HttpApplicationInitializationHttpModule>(); 
     kernel.RegisterServices(); 

     return kernel; 
    } 

    private static void RegisterServices(this IKernel kernel) 
    { 
     kernel.Bind<IMemoryCacheService>() 
       .To<MemoryCacheService>() 
       .InSingletonScope(); 
       // InSingletonScope() is important so Ninject knows 
       // to create only one copy and then reuse it every time 
       // it is asked for 

     // ignore the stuff below... I have left it in here for illustration 
     kernel.Bind<IDbTransactionFactory>() 
       .To<DbTransactionFactory>() 
       .InRequestScope(); 
     kernel.Bind<IDbModelContext>() 
       .To<DbModelContext>() 
       .InRequestScope(); 
     kernel.Bind<IDbModelChangeContext>() 
       .To<DbModelChangeContext>() 
       .InRequestScope(); 
     kernel.Bind<IUserContext>() 
       .To<UserContext>() 
       .InRequestScope(); 

     kernel.BindAttributeAndFilter<IgnoreNonAjaxRequestsFilter, IgnoreNonAjaxRequestsAttribute>(); 
     kernel.BindAttributeAndFilter<ProvideApplicationInfoFilter, ProvideApplicationInfoAttribute>(); 
     kernel.BindAttributeAndFilter<ProvideSessionInfoFilter, ProvideSessionInfoAttribute>(); 
     kernel.BindAttributeAndFilter<UseDialogLayoutFilter, UseDialogLayoutAttribute>(); 
     kernel.BindAttributeAndFilter<CheckResourceAccessFilter, CheckResourceAccessAttribute>(); 
     kernel.BindAttributeAndFilter<CheckResourceStateFilter, CheckResourceStateAttribute>(); 
    } 

    private static void BindAttributeAndFilter<TFilter, TAttribute>(this IKernel kernel) 
    { 
     kernel.BindFilter<TFilter>(FilterScope.Action, null) 
       .WhenControllerHas<TAttribute>(); 
     kernel.BindFilter<TFilter>(FilterScope.Action, null) 
       .WhenActionMethodHas<TAttribute>(); 
    } 
} 

अंत में, अपने नियंत्रक से बदल जाएगा

public class HomeController : Controller 
{ 
    private IMemoryCacheService memoryCacheService; 

    public HomeController(IMemoryCacheService memoryCacheService) 
    { 
     this.memoryCacheService = memoryCacheService; 
    } 

    public ActionResult Foo() 
    { 
     // use this.memoryCacheService in your controller methods... 
    } 

    ... 
} 

कहो, तुम भी IEmailService उपर्युक्त रणनीति का पालन नामक एक और सेवा है और यह आपको IEmailServiceHomeController में भी उपलब्ध होना चाहता था, फिर:

public class HomeController : Controller 
{ 
    private IMemoryCacheService memoryCacheService; 
    private IEmailService emailService; 

    public HomeController(IMemoryCacheService memoryCacheService, IEmailService emailService) 
    { 
     this.memoryCacheService = memoryCacheService; 
     this.emailService = emailService; 
    } 

    public ActionResult Foo() 
    { 
     // use this.memoryCacheService in your controller methods... 
     // and also use this.emailService in your controller methods... 
    } 

    ... 
} 

निंजा एएसपी.नेट एमवीसी नियंत्रक फैक्ट्री को स्वचालित रूप से नियंत्रक कन्स्ट्रक्टर को इंजेक्शन वाले तर्क प्रदान करने के लिए बदल देगा।

मुझे लगता है कि दृष्टिकोण इस तरह की लंबी अवधि में वैश्विक चर ध्यान में रखते हुए बेहतर है, आदि

+3

मुझे राय है कि यह ज्यादातर स्थितियों के लिए मूल्य से अधिक ओवरहेड जोड़ता है। [जोड़ने के लिए संपादित: यह वितरित कैश के लिए उपयुक्त हो सकता है।] रयान बायर्न द्वारा वर्णित मेमोरी कैश.डिफॉल्ट का उपयोग करें। –

+0

यदि मैं ईमानदार हूं, तो मैंने विशिष्ट प्रश्न का उत्तर देने के बजाय सही दृष्टिकोण को चित्रित करने के लिए उपर्युक्त सभी को लिखा है। मूल समस्या यह थी कि ओपी एक नियंत्रक में एक वस्तु बनाने की कोशिश कर रहा था (जो प्रति अनुरोध होगा) जबकि उसे एक सिंगलटन की आवश्यकता थी। आम तौर पर, हम स्थैतिक वर्गों/गुणों का उपयोग करने के बजाय निर्भरताओं को इंजेक्शन देना चाहते हैं। –

+1

आगे, यदि आप रायन बायर्न के उत्तर पर ओपी द्वारा टिप्पणी पढ़ते हैं, तो यह स्पष्ट है कि (शायद ओपी से अनजान) ओपी सिर्फ एक उचित प्रारंभिक वैश्विक चर के बजाय डीआई तंत्र की तलाश में है। –

संबंधित मुद्दे