Fermer

mars 23, 2021

Mises à niveau de Sitecore: une mini-série partie 4 ORM et autres mises à jour de dépendances


Pour ceux d'entre vous qui mettent à niveau une instance Sitecore pour la première fois, bienvenue dans la partie la plus difficile de la mise à niveau. La mise à niveau de votre base de code pour continuer à fonctionner exactement comme avant la mise à niveau peut s'avérer assez difficile. Les nouvelles versions de vos dépendances peuvent supprimer des classes et des fonctions que vous avez beaucoup utilisées tout au long de la solution. Lorsque vous essayez d'estimer le temps nécessaire pour mettre à niveau votre base de code, vous devrez prendre en compte les versions actuelles de toutes vos dépendances et déterminer les versions de ces dépendances vers lesquelles vous devrez effectuer la mise à niveau. Cet article de blog fournira des conseils sur la mise à niveau de votre base de code et sur la manière de traiter l'éléphant dans la pièce, les ORM (Object Relational Mappers).

Mise à jour des dépendances de Sitecore

La première chose à faire est de mettre à jour le Framework cible de tous les projets de votre solution. Pour ce faire dans Visual Studio, cliquez simplement avec le bouton droit sur un projet et ouvrez ses propriétés. Mettez ensuite à jour le paramètre Target Framework de votre projet pour qu'il corresponde à la version .NET requise par votre nouvelle version de Sitecore. Le menu ressemblera à la capture d'écran ci-dessous:

 Targetframework

Après avoir mis à jour ce paramètre, déchargez et rechargez chaque projet dans la solution. Accédez ensuite au gestionnaire de packages Nuget pour la solution. Connectez-vous au flux Sitecore Nuget. Désinstallez les packages Sitecore Nuget. Ensuite, installez les mêmes packages Sitecore Nuget en utilisant la version compatible avec la nouvelle version de Sitecore vers laquelle vous effectuez la mise à niveau. Installez ces packages avec le comportement de dépendance défini sur le plus bas.

 Sitecorenuget

AVERTISSEMENT: n'installez pas simplement la dernière version du package Nuget et vaquez à votre journée. La dernière version du package correspondra à la dernière version de Sitecore. Vous n'êtes peut-être pas en train de passer à la dernière version de Sitecore.

Après avoir mis à jour les références Nuget, vous devrez alors parcourir votre code dans chacun de vos projets. Vous devrez vous assurer que vos appels et implémentations d'API Sitecore sont toujours pris en charge par la nouvelle version de Sitecore. Sinon, vous devrez ajuster votre code en conséquence pour que votre site fonctionne comme il le faisait sur l'ancienne version. Je prendrais également le temps de m'assurer que l'un des projets fait référence à l'ancienne version de Sitecore. Cela se produit généralement si les références Sitecore ont été ajoutées sans utiliser Nuget. Veillez à installer les références Sitecore à des projets comme ceux-ci via Nuget Package Manager.

Mise à jour des dépendances non-Sitecore

Suivez les mêmes étapes décrites ci-dessus pour mettre à niveau vos dépendances non-Sitecore. Accédez d'abord au gestionnaire de packages Nuget et assurez-vous d'installer les mêmes versions mises à niveau dans les projets si nécessaire. Vérifiez ensuite que tous les projets n'avaient aucune de ces dépendances installée sans Nuget. Mettez à jour en conséquence.

 Sitecore - Comprendre les approches de développement: un Outlook Sitecore

Certaines de vos dépendances peuvent ne pas avoir une version de package Nuget compatible avec votre nouvelle version de Sitecore. Et alors? Vous avez quelques options. Vous pouvez attendre le processus de mise à niveau jusqu'à ce que le package Nuget soit disponible. Cela peut ne jamais arriver si cette dépendance n'est plus maintenue. Même s'il est en cours de maintenance, il se peut qu'il ne soit pas disponible dans le délai imparti pour terminer la mise à niveau. Cela vous laisse avec les deux autres options. Vous avez la possibilité de télécharger la version actuelle de la dépendance et de la rendre compatible avec votre nouvelle version de Sitecore. La dernière option (nucléaire) dont vous disposez consiste à supprimer cette dépendance et à implémenter votre propre code pour exécuter ses fonctionnalités. Je ne recommande pas l'option finale à moins que cela ne soit absolument nécessaire. Mettre à jour la dépendance vous-même sera probablement le chemin à suivre.

Qu'est-ce qu'un ORM?

ORM signifie Object Relational Mapper. Dans Sitecore, les ORM les plus populaires sont Glass Mapper et Synthesis. Ces outils vous permettent de mapper facilement les données créées par le contenu sur un élément à un objet C # fortement typé. Ce sont des bibliothèques impressionnantes qui sont faciles à utiliser. Par exemple, je peux construire un objet comme celui-ci avec Glass Mapper:

[SitecoreType(TemplateID = MySampleGlassItemId, AutoMap = true)]
 public class MySampleGlassObject: ItemBase
{
     chaîne virtuelle publique Title {get; ensemble; }
     chaîne virtuelle publique Text {get; ensemble; }
     chaîne virtuelle publique Description {get; ensemble; }
} 

Je peux ensuite récupérer mon élément Sitecore avec ces trois propriétés avec un simple appel qui le castera vers l'objet ci-dessus.

 MySampleGlassObject myObject = _mvcContext.GetDatasourceItem  (); 

Avec des décorateurs de propriété tels comme [SitecoreChildren]vous pouvez même récupérer des tonnes d'éléments qui sont automatiquement mappés à des objets C # sans qu'un développeur ait à récupérer chaque champ individuel.

Pour conserver ORM ou ne pas conserver ORM

Lors de la mise à niveau de votre solution, utilise un ORM, vous aurez deux voies à suivre: se débarrasser de l'utilisation de l'ORM ou mettre à niveau l'ORM. Dans un monde idéal, il serait évident de vouloir mettre à niveau l'ORM pour garder toutes vos implémentations intactes avec peu de mise à jour. Malheureusement, nous ne sommes pas dans un monde idéal. La version la plus récente de l'ORM peut supprimer les méthodes qu'elle prenait auparavant en charge. Votre base de code peut nécessiter une mise à jour sérieuse pour contourner ces fonctions désormais obsolètes.

La mise à niveau de votre ORM peut être une tâche extrêmement difficile. Par exemple, les changements entre Glass Mapper 4 et Glass Mapper 5 sont significatifs. Les étapes à suivre sont bien documentées dans ce blog ici . Le GlassController n'existe plus dans Glass Mapper 5. Si tous vos contrôleurs dépendent de l'utilisation de ce contrôleur (ou si vous avez même d'autres dépendances basées sur l'utilisation de ce contrôleur), vous devrez trouver une solution. J'ai écrit un contrôleur de remplacement que vous pouvez utiliser pour remplacer le GlassController maintenant inexistant. Si vous ne l'utilisez pas, vous devrez rédiger votre propre travail similaire à l'article de blog lié. D'autres changements tels que la suppression du décorateur IsLazy pourraient nécessiter des changements radicaux dans tout votre code, en particulier pour les composants nécessitant un mappage automatique de tonnes d'éléments enfants.

Le point que j'essaie de faire ici est que la mise à niveau d'un ORM peut même pas vaut votre temps. Même après avoir réussi à compiler votre code à l'aide de l'ORM mis à jour, vous devrez ensuite tester fortement vos sites pour vous assurer que le comportement du site est toujours le même qu'avant. Dépanner et diagnostiquer les problèmes attribués à votre ORM est assez difficile.

Ce casse-tête peut être évité en supprimant la dépendance de votre solution à un ORM. Cela peut sembler un défi de taille. Après tout, il faudrait mettre à jour chaque composant pour se débarrasser de sa dépendance à l'ORM. Cependant, je dirais qu'une fois que vous obtenez le modèle de développement, cela devient un travail très facile et insensé à parcourir. Cela rendra les futures mises à jour encore plus faciles car vous aurez une dépendance en moins à mettre à jour. Cela évite également d'avoir à parcourir des problèmes de configuration ORM obscurs. Si la mise à niveau de l'ORM nécessite beaucoup de réécriture de code, pourquoi ne pas simplement réécrire complètement l'ORM? Je vais aller plus loin ici et recommander de concevoir toutes les solutions futures sans utiliser d'ORM pour rendre les mises à niveau aussi indolores que possible.

À quoi ressemblera votre code sans ORM?

Votre base de code sera contiennent beaucoup plus d'appels d'API Sitecore. Revenons à l'exemple de code de Glass Mapper que j'ai utilisé pour récupérer un objet avec les propriétés Title, Text et Description. Pour récupérer ces valeurs de propriété sans Glass Mapper, cela ressemblerait à ceci:

 var header = myItem.Fields ["Header"] .Value;
var text = myItem.Fields ["Text"] .Value;
var description = myItem.Fields ["Description"] .Value; 

Très simple, non? Je pense que oui. Cependant, comment pouvons-nous nous assurer que ces champs sont modifiables dans l'éditeur d'expérience? Les ORM fournissent des méthodes faciles à utiliser pour y rendre chaque champ individuellement modifiable. Avec juste l'API Sitecore à notre jetable, je recommande d'utiliser des cadres d'édition personnalisés ou des boutons d'expérience personnalisés.

Garder Glass Mapper et remplacer GlassController

Si vous choisissez de conserver Glass Mapper comme dépendance et que vous devez remplacer le GlassController , le code ci-dessous fera l'affaire!

 using Glass.Mapper;
en utilisant Glass.Mapper.Sc;
en utilisant Glass.Mapper.Sc.Web.Mvc;
en utilisant Sitecore.Data.Items;
en utilisant Sitecore.Mvc.Controllers;
en utilisant le système;
using System.Diagnostics.CodeAnalysis;

namespace MyBlogNamespace
{
    Public class ReplacementGlassController: Controller
    {
        public IMvcContext MvcContext {get; ensemble; }
        public ISitecoreService SitecoreService {get; ensemble; }

        public IGlassHtml GlassHtml {get; ensemble; }

        public IRenderingContext RenderingContextWrapper {get; ensemble; }

        [ExcludeFromCodeCoverage]
        public ReplacementGlassController (IMvcContext mvcContext, ISitecoreService sitecoreService)
          : this (mvcContext, sitecoreService, nouveau RenderingContextMvcWrapper ())
        {
            
        }

        public ReplacementGlassController (
          IMvcContext mvcContext,
          ISitecoreService sitecoreService,
          IRenderingContext renderingContextWrapper)
        {
            MvcContext = mvcContext;
            GlassHtml = mvcContext? .GlassHtml;
            SitecoreService = sitecoreService;
            RenderingContextWrapper = renderingContextWrapper;
        }

        /// 
        /// Renvoie soit l'élément spécifié par le DataSource, soit l'élément de contexte actuel
        /// 
        ///  L'élément de mise en page. 
        [ExcludeFromCodeCoverage]
         public virtual Item LayoutItem
        {
            obtenir
            {
                renvoyer DataSourceItem ?? ContextItem;
            }
        }

        /// 
        /// Renvoie soit l'élément spécifié par l'élément de contexte actuel
        /// 
        ///  L'élément de mise en page. 
        [ExcludeFromCodeCoverage]
         Élément public virtuel ContextItem
        {
            obtenir
            {
                return Sitecore.Context.Item;
            }
        }

        /// 
        /// Renvoie l'élément spécifié par la source de données uniquement. Renvoie null si aucun ensemble de sources de données
        /// 
        [ExcludeFromCodeCoverage]
         élément virtuel public DataSourceItem
        {
            obtenir
            {
                if (! RenderingContextWrapper.HasDataSource)
                    return null;
                return Sitecore.Context.Database.GetItem (RenderingContextWrapper.GetDataSource ());
            }
        }

        ///  Renvoie l'élément de contexte comme fortement typé 
        /// 
         /// 
         protected T GetContextItem  (bool isLazy = false, bool inferType = false) où T: class
        {
            return MvcContext.GetContextItem  (nouveau GetKnownOptions ()
            {
                InferType = inferType,
                Lazy = isLazy? LazyLoading.Enabled: LazyLoading.Disabled
            });
        }

        ///  Renvoie l'élément de source de données fortement typé 
        /// 
         /// 
         protected T GetDataSourceItem  (bool isLazy = false, bool inferType = false) où T: class
        {
            if (! RenderingContextWrapper.HasDataSource)
                retourne la valeur par défaut (T);
            string dataSource = RenderingContextWrapper.GetDataSource ();
            if (chaîne.IsNullOrEmpty (source de données))
                retourne la valeur par défaut (T);
            return SitecoreService.GetItem  (dataSource, options => new GetKnownOptions ()
            {
                InferType = inferType,
                Lazy = isLazy? LazyLoading.Enabled: LazyLoading.Disabled
            });
        }

        ///  Renvoie l'élément de mise en page comme fortement typé 
        /// 
         /// 
         protected T GetLayoutItem  (bool isLazy = false, bool inferType = false) où T: class
        {
            if (! RenderingContextWrapper.HasDataSource)
                return GetContextItem  (isLazy, inferType);
            return GetDataSourceItem  (isLazy, inferType);
        }

        Protégé virtuel T GetRenderingParameters  () où T: classe
        {
            string renderingParameters = RenderingContextWrapper.GetRenderingParameters ();
            if (! renderingParameters.HasValue ())
                renvoie la valeur par défaut (T);
            return GlassHtml.GetRenderingParameters  (renderingParameters);
        }

        ///  Renvoie l'élément de source de données. 
        /// 
         /// 
         /// 
         /// 
         [Obsolete("Use GetDataSourceItem")]
        protégé virtuel T GetRenderingItem  (bool isLazy = false, bool inferType = false) où T: class
        {
            return GetDataSourceItem  (isLazy, inferType);
        }

        /// 
        /// si le contexte de rendu et la source de données ont été définis, renvoie alors l'élément de source de données, sinon renvoie l'élément de contexte.
        /// 
        /// 
         /// 
         /// 
         /// 
         [Obsolete("Use GetLayoutItem")]
        protégé virtuel T GetControllerItem  (bool isLazy = false, bool inferType = false) où T: class
        {
            return GetLayoutItem  (isLazy, inferType);
        }
    }
} 

Vous devrez ensuite parcourir tous vos contrôleurs qui dépendent du GlassController et mettre à jour leurs constructeurs pour recevoir une dépendance injectée IMvcContext et ISitecoreService. Après cela, vous devrez faire en sorte que tout votre code fonctionne sans les fonctions Glass désormais obsolètes. Vous ne savez pas comment mettre en œuvre l'injection de dépendances? Restez à l'écoute pour mon prochain blog pour expliquer comment faire!

Remarques de clôture

Cette partie de la mise à jour prend du temps. Vous rencontrerez des problèmes où certaines dépendances ne sont pas déployées ou ne sont pas référencées correctement. Vous rencontrerez des tonnes d'écrans jaunes de la mort. Sois patient. Essayez de garder l'esprit clair et de faire un pas à la fois. Réussir la mise à niveau d'une solution est un bon sentiment et une réussite bien méritée.






Source link