5 votes

Tâche MSBuild pour charger mon assembly et construire une configuration NHibernate sérialisée

Ce que j'espérais être une heure ou deux de travail s'est transformé en une véritable débâcle, sans aucun résultat en vue.

Problème : j'essaie de sérialiser une copie de ma configuration NHibernate et de la stocker dans... le projet qui a été utilisé pour la générer !

Solution du manuel actuel : J'ai un projet Foo qui

  • contient une série de fichiers DomainObject.Map.cs
  • Fait référence à un fichier "nhconfig.bin" à intégrer en tant que ressource.
  • Contient une méthode statique FooGenerateNHConfig qui crée un objet Configuration et le sérialise dans nhconfig.bin.

Pour le générer, je :

  1. (la première fois seulement : créez un fichier nhconfig.bin vide qui servira de placeholder).
  2. Construire Foo.
  3. Appeler un test unitaire qui appelle FooGenerateNHConfig.
  4. Reconstruire Foo.
  5. Déployer l'application.

J'essaie d'automatiser cela et je pensais que ce serait simple :

  1. Créer un projet Foo.BuildSupport qui fait référence à Foo.
  2. Définir une tâche X qui appellera FooGenerateNHConfig.
  3. Mettre en place une cible AfterCompile qui appellerait X.

Malheureusement, j'obtiens maintenant deux erreurs.

  1. Tout d'abord, une exception quelque peu étrange :

    FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
    ---> System.Runtime.Serialization.SerializationException: Unable to find assembly 'FluentNHibernate, Version=1.1.0.685, Culture=neutral, PublicKeyToken=8aa435e3cb308880'.

    Je pense que c'est FluentNHibernate qui se plaint de ne pas trouver l'assembly FluentNHibernate ?

  2. Une fois que j'ai exécuté la tâche depuis visual studio la première fois, visual studio (devenv.exe) verrouille ma Foo.BuildSupport.dll ET ma Foo.exe (probablement parce qu'il les considère comme des bibliothèques de support et non comme les bibliothèques de construction proprement dites), de sorte que je ne peux pas les reconstruire. En général, c'est parce que vs supposez (et probablement à juste titre) que la bibliothèque BuildSupport est assez statique et ne dépend pas de la bibliothèque

Quel est le meilleur moyen d'automatiser un tel processus ? Je n'ai que quelques idées préliminaires pour l'instant, mais la seule chose à laquelle je pense est de construire un exécutable entièrement séparé qui sera exécuté par msbuild (j'ai vu une tâche pour faire l'équivalent de cela, mais je ne la trouve pas maintenant), ou quelque chose de plus impliqué impliquant un domaine d'application séparé et l'appel manuel de la fonction via la réflexion. Mais avant d'aller plus loin dans cette voie, est-ce que j'ai raté quelque chose de plus facile et de plus évident ?

2voto

Boog Points 1099

J'ai eu un problème très similaire à celui-ci. Mon problème était lié à la désérialisation par MSBuild de Xml vers des classes contenues dans un assemblage tiers. Il ne pouvait pas résoudre l'assemblage nécessaire pour que la sérialisation fonctionne, même si les assemblages faisaient partie du projet et qu'il n'avait aucun problème à les résoudre en dehors de la sérialisation. Je ne peux pas donner une description plus technique du problème, mais j'ai trouvé ce bout de code qui a résolu le problème pour moi,

        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            Assembly ayResult = null;
            string sShortAssemblyName = args.Name.Split(',')[0];
            Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (Assembly ayAssembly in ayAssemblies)
            {
                if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0])
                {
                    ayResult = ayAssembly;
                    break;
                }
            }
            return ayResult;
        }

        public Constructor()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }

Je pense que la raison pour laquelle cela fonctionne pour moi est que mon application résout les Assemblages en dehors de la sérialisation, donc je surcharge le callout AssemblyResolution pour le renvoyer vers les bons Assemblages que, pour une raison quelconque, il n'utilise pas de lui-même.

J'espère que cela vous sera utile !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X