Question

J'ai appris que pour charger un singleton paresseux, voici le modèle à utiliser:

private MyObject()
{
}

public static MyObject Instance
{
    get { return SingletonCreator.CreatorInstance; }
}

private static class SingletonCreator
{
    private static readonly MyObject _instance = new MyObject();

    public static MyObject CreatorInstance
    {
        get { return _instance; }
    }
}

Mais un modèle plus simple serait:

private static readonly MyObject _instance = new MyObject();

private MyObject()
{
}

public static MyObject Instance
{
    get { return _instance; }
}

Ce ne serait pas un chargement paresseux. Mais est-ce vraiment quelque chose qui devrait me préoccuper dans une application Web?

Était-ce utile?

La solution

Sauf si vous avez des méthodes statiques ne nécessitant pas le singleton, il suffit d'inclure un constructeur statique pour rendre la classe paresseuse. Sans le constructeur statique, c'est toujours surtout paresseux.

Voir ma page d'implémentation singleton pour plus de détails et d'options.

Normalement, le code que vous avez indiqué au bas de la question est assez paresseux, à moins que vous ne ne vouliez vraiment pas initialiser le singleton, à moins qu'il ne soit utilisé. (En gros, avec beforefieldinit , le JIT s'assurera généralement que chaque type utilisé dans une méthode est initialisé; sans beforefieldinit , il doit attendre la première utilisation réelle de la classe. pendant son exécution, voir ma beforefieldinit pour plus d'informations. - Mais l’important est qu’il n’est toujours pas possible d’initialiser tous les singletons dès que l’assemblage est chargé, ou quoi que ce soit du genre.)

Autres conseils

Le chargement paresseux implique généralement que vous chargez quelque chose dans une base de données. Ce que vous faites est généralement appelé " initialisation différée " (techniquement, "l'initialisation différée" est une méthode de mise en oeuvre d'un modèle de chargement différé).

En ce qui concerne vos questions initiales: tout d’abord, vous n’avez pas besoin d’un singleton. Si vous en avez toujours besoin, voici comment devrait être fait correctement. Troisièmement, vous n'avez pas besoin d'un singleton.

C'est bien beau, mais le chargement paresseux a pour but d'éviter le chargement de ressources (généralement non gérées) (frapper une base de données, le système de fichiers, etc.) jusqu'à ce que vous en ayez besoin, ce qui vous évitera de les charger de manière préventive lorsque vous ne l'utiliserez pas. Pas vraiment besoin. L'utilisation du modèle singleton, en soi, n'implique pas nécessairement un chargement paresseux, car vous pouvez créer assez correctement l'instance gérée à tout moment.

L'aspect de chargement paresseux entre en jeu si vous n'accédez à des ressources que lorsque vous appelez la méthode appropriée; si, lorsque cette instance de singleton est créée, elle effectue toute une série de requêtes de base de données et cache le résultat, le chargement n'est pas paresseux pour moi.

En ce qui concerne les scénarios ORM, le chargement différé fait généralement directement référence au report de la charge d'un autre objet dans une relation jusqu'au premier accès, ce qui évite d'effectuer une deuxième requête potentiellement inutile.

Encore une fois, si vous savez que vous allez naviguer dans cette relation au cours de votre utilisation de l'objet (c'est-à-dire si vous avez récupéré un utilisateur afin de répertorier son Posts ou quelque chose du genre), alors vous voudrez probablement demander à votre ORM de charger les objets liés en même temps, ce qui le poussera généralement à exécuter une requête unique avec une jointure, plutôt que de passer en boucle et d'effectuer plusieurs opérations. requêtes plus tard; dans ce cas, vous ne voulez pas vraiment de chargement paresseux.

Veillez à ne pas confondre le chargement de la page, la session et la durée de vie de l'application. Cela dit, êtes-vous sûr de vouloir utiliser une instance singleton statique? Une fois créé, il restera actif jusqu’à ce que l’application (le serveur Web) soit fermée ou que vous exécutiez iisreset .

Pensez à le mettre en cache dans HttpContext.Current.Items si vous voulez une instance chargée paresseusement par page, ou peut-être dans HttpContext.Current.Session si vous en voulez une. par utilisateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top