web-dev-qa-db-fra.com

Variables d'application dans ASP.NET Core 2.0

Comment dois-je procéder pour définir et accéder aux variables à l'échelle de l'application dans ASP.NET Core 2.0?

Détails: J'ai une variable, appelons-la CompanyName, qui réside dans la base de données et est utilisée littéralement sur chaque page. Je ne veux pas accéder à la base de données chaque fois que j'ai besoin d'afficher le nom de l'entreprise. Il y a 100 ans, j'aurais réglé Application["CompanyName']=CompanyName mais je comprends que ce n'est pas la façon de faire les choses dans .NET Core. Quelle serait l'alternative?

14
Laurie Dickinson

Beaucoup a progressé au cours des 100 dernières années. Il y a quelque temps, je crois en ASP.NET 1.0, l'objet Application dans ASP classic a été remplacé par caching (bien que l'objet Application ait été laissé en arrière) compatibilité avec ASP classic).

AspNetCore a a remplacé le mécanisme de mise en cache d'ASP.NET et l'a rendu compatible avec les DI, mais il est toujours très similaire à l'état des choses dans ASP.NET. La principale différence est que vous devez maintenant l'injecter au lieu d'utiliser la propriété statique HttpContext.Current.Cache.

Enregistrez le cache au démarrage ...

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMemoryCache();
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvcWithDefaultRoute();
    }
}

Et vous pouvez l'injecter comme ...

public class HomeController : Controller
{
    private IMemoryCache _cache;

    public HomeController(IMemoryCache memoryCache)
    {
        _cache = memoryCache;
    }

    public IActionResult Index()
    {
        string companyName = _cache[CacheKeys.CompanyName] as string;

        return View();
    }

Ensuite, pour le faire fonctionner à l'échelle de l'application, vous pouvez utiliser un filtre ou middleware combiné avec certains sorte de modèle d'actualisation du cache:

  1. Tenter d'obtenir la valeur du cache
  2. Si la tentative échoue
    • Rechercher les données de la base de données
    • Repeupler le cache
  3. Renvoie la valeur

public string GetCompanyName()
{
    string result;

    // Look for cache key.
    if (!_cache.TryGetValue(CacheKeys.CompanyName, out result))
    {
        // Key not in cache, so get data.
        result = // Lookup data from db

        // Set cache options.
        var cacheEntryOptions = new MemoryCacheEntryOptions()
            // Keep in cache for this time, reset time if accessed.
            .SetSlidingExpiration(TimeSpan.FromMinutes(60));

        // Save data in cache.
        _cache.Set(CacheKeys.CompanyName, result, cacheEntryOptions);
    }

    return result;
}

Bien sûr, vous pouvez nettoyer cela et créer un service avec des propriétés fortement typées en tant que wrapper autour de votre cache injecté dans les contrôleurs, mais c'est l'idée générale.

Notez également qu'il y a un cache distribué au cas où vous voudriez partager des données entre les serveurs Web.

Vous pouvez également utiliser une méthode statique ou une instance de classe enregistrée statiquement, mais notez si l'hébergement sur IIS que la statique ( sortira du cadre chaque fois que le le pool d'applications recycle . Pour que cela fonctionne, vous devez vous assurer que vos données sont remplies à nouveau à l'aide d'un modèle de rafraîchissement similaire.

La principale différence est qu'avec la mise en cache, il existe des paramètres de délai d'attente qui peuvent être utilisés pour optimiser la durée de stockage des données dans le cache (soit une limite de temps ferme ou une expiration glissante).

12
NightOwl888

Vous pouvez créer une classe Singleton appelée ApplicationWideSettings. Donnez à cette classe des propriétés publiques. Initialisez toutes les valeurs dont vous avez besoin une fois puis utilisez-les en accédant à la seule instance de votre classe via:

ApplicationWideSettings.Instance.PropertyName;

Assurez-vous simplement que l'espace de noms de la classe ApplicationWideSettings est référencé lorsque vous souhaitez y accéder.

Je préfère cela aux paramètres globaux/statiques car vous avez une classe pour enregistrer toutes vos données disponibles à l'échelle mondiale.

Si vous n'êtes pas sûr de ce qu'est un Singleton, je peux simplement vous suggérer de consulter cet article de Jon Skeet:

C # en profondeur: implémentation du modèle singleton en C #

5
Paul Weiland