2016-12-12 80 views
1

我有一個客戶視圖模型,它具有用於選擇國家,地區和語言的下拉列表。我正在使用ViewComponent爲下拉菜單加載必要的數據,它的功能就像一個魅力。我的問題是,當他們在頁面上的多個客戶端模型時,我正在對外部API進行多次調用以接收相同的數據。我試圖將Component.InvokeAsync部分放入緩存標籤幫助器中,但它也保留了第一次調用時的元素命名,並弄亂了模型綁定。有沒有辦法避免多次調用相同的數據?重複查看組件數據

下面是代碼的樣子。沒什麼特別的。意見只是綁定屬性,並沒有什麼特別的地方。

[ViewComponent(Name = "LocationSelector")] 
public class LocationSelector : ViewComponent 
{ 
    private readonly ILocationService locationsService; 

    public LocationSelector(ILocationService locationService) 
    { 
     this.locationsService = locationService; 
    } 

    public async Task<IViewComponentResult> InvokeAsync() 
    { 
     var locationManager = new LocationSelectorViewModel(); 
     locationManager.Areas = await this.locationsService.GetAreas(); 
     locationManager.Countries = await this.locationsService.GetCountries(); 
     return View("Default", locationManager); 
    } 
} 

而這個組件在客戶模型中被調用。問題是我可能在我的頁面中有多個客戶,他們都會向服務請求完全相同的數據。

@await Component.InvokeAsync(nameof(LocationSelector)) 
+0

http://sscce.org/ – Yoda

回答

1

您應該考慮緩存數據。您可以使用IMemoryCache imeplemenation。我更喜歡創建自己的抽象層,我會在任何需要的地方使用它。

public interface ICache 
{ 
    T Get<T>(string key, Func<T> updateExpression = null, int cacheDuration=0);  
} 
public class InMemoryCache : ICache 
{ 
    readonly IMemoryCache memoryCache; 
    public InMemoryCache(IMemoryCache memoryCache) 
    { 
     this.memoryCache = memoryCache; 
    } 
    public T Get<T>(string key, Func<T> updateExpression = null,int cacheDuration=0) 
    { 
     object result; 
     if (memoryCache.TryGetValue(key,out result)) 
     { 
      return (T) result; 
     } 
     else 
     { 
      if (updateExpression == null) 
      { 
       return default(T); 
      } 
      var data = updateExpression(); 
      if (data != null) 
      { 
       var options = new MemoryCacheEntryOptions 
       { 
        AbsoluteExpiration = DateTime.Now.AddSeconds(cacheDuration) 
       }; 
       this.memoryCache.Set(key, data, options); 
       return data; 
      } 
      return default(T); 
     } 
    } 
} 

現在在啓動類的ConfigureServices方法中,啓用緩存並定義我們的自定義ICache-InMemoryCache映射。

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddTransient<ICache, InMemoryCache>(); 
    services.AddMemoryCache(); 
} 

現在,您可以將ICache注入任何類並使用它來獲取/存儲數據。

public class LocationSelector : ViewComponent 
{ 
    private readonly ILocationService locationsService; 
    private readonly ICache cache; 
    public LocationSelector(ILocationService locationService,ICache cache) 
    { 
     this.locationsService = locationService; 
     this.cache = cache; 
    } 

    public async Task<IViewComponentResult> InvokeAsync() 
    { 
     var locationManager = new LocationSelectorViewModel(); 

     var areas = await this.cache.Get(CacheKey.Statuses,() => 
                this.locationsService.GetAreas(),360); 
     locationManager.Areas = areas; 

     return View("Default", locationManager); 
    } 
}