web-dev-qa-db-fra.com

deux différents DLL avec le même espace de noms

J'ai deux fichiers DLL qui ont le même espace de noms mais qui ont des méthodes et des types différents. Comment puis-je référencer les deux DLL dans mon projet et utiliser leurs méthodes et types?

Par ailleurs, ces deux DLL ont des méthodes et des types avec le même nom mais une implémentation différente et des méthodes et des types uniques.

62
user415789

Il n'y a rien de spécial à faire - il suffit de les référencer et d'utiliser les types. Les espaces de noms peuvent s'étendre sur plusieurs assemblages sans problème, car ce ne sont pas vraiment des types opaques. Un espace de noms n'est qu'un moyen d'ajouter un préfixe commun à tous les types qu'il contient, vous permettant d'avoir plusieurs types du même nom sous différents espaces de noms. (Le framework ne les voit pas comme ayant les mêmes noms, car il voit le nom "complet" de tout - qui a un alias et un espace de noms attachés à l'avant.)

Dans les rares cas où vous référencez 2 assemblys qui ont les mêmes noms de type et les mêmes espaces de noms (tels que 2 versions différentes de la même dll) - vous pouvez distinguer l'assembly à utiliser pour un type donné en utilisant un alias. L'alias par défaut pour toutes les références est global, mais vous pouvez spécifier votre propre alias pour n'importe quel assembly lorsque vous le référencez (à l'aide d'un commutateur de compilation - ou utilisez simplement la boîte de propriétés dans Visual Studio) - et disposez d'un extern alias <name> clause en haut de votre fichier de code où vous l'utilisez - vous accéderez aux types de différents assemblys avec <name>::MyNamespace.Type

87
Mark H

Si vous avez 2 types avec exactement le même nom (notez que le nom inclut l'espace de noms) mais dans différentes DLL et que vous souhaitez les utiliser tous les deux, vous pouvez le faire.

Réponse courte

Vous avez du type Acme.Foo dans 2 DLL différentes et vous souhaitez les utiliser. Donnez à la référence un alias dans la fenêtre des propriétés de référence (Affichage | Fenêtre Propriétés) puis utilisez-la comme ceci:

extern alias TheAliasYouGaveTheReference

TheAliasYouGaveTheReference::Acme.Foo f = new 
    TheAliasYouGaveTheReference::Acme.Foo();

L'espace de noms par défaut est global pour tout programme C # mais notez ci-dessus que nous utilisons l'alias que nous avons créé au lieu de global.

La meilleure approche consiste à [~ # ~] et non [~ # ~] à entrer dans une situation comme celle-ci en premier lieu, si les deux assemblages vous appartiennent, alors ne créez pas 2 types avec exactement le même nom dans exactement le même espace de noms. Mais parfois, nous ne contrôlons pas le code source, pour ces périodes, la solution ci-dessus peut être utilisée.

Réponse longue

Je copie la plupart de l'article de ici donc il est enregistré ici au cas où l'article ne serait plus disponible.

Comment vous situez-vous dans une telle situation?

Tout d'abord, voici comment vous pouvez reproduire le scénario afin qu'il soit vraiment clair de quoi nous parlons:

  1. Créez une bibliothèque de classes C # appelée FooVersion1
  2. Remplacez le code du modèle dans Class1.cs par ce qui suit:

    using System;
    
    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
        }
    }
    
  3. Cliquez avec le bouton droit sur la solution dans l'Explorateur de solutions et sélectionnez Ajouter | Nouveau projet

  4. Sauvegardez le projet en cours (applicable uniquement en express)
  5. Sélectionnez une bibliothèque de classes dans la boîte de dialogue du nouveau projet et changez le nom du projet en FooVersion2 et appuyez sur OK
  6. Remplacez le code dans Class1.cs par ce qui suit:

    using System;
    
    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
    
            public void Goo()
            {
                Console.WriteLine("Goo");
            }
        }
    }
    

Utilisation du type dans Application

Ok maintenant nous avons 2 assemblages différents contenant Acme.Foo. Créons maintenant une application console et essayons de les utiliser chacune.

  1. Cliquez avec le bouton droit sur la solution dans l'Explorateur de solutions et sélectionnez Ajouter | Nouveau projet
  2. Sélectionnez une application console et appelez-la Consumer
  3. Cliquez avec le bouton droit sur Consumer et sélectionnez "Définir comme projet de démarrage"
  4. Cliquez avec le bouton droit sur le nœud de références dans le projet Consumer et sélectionnez "Ajouter une référence"
  5. Cliquez sur l'onglet projets et sélectionnez plusieurs fois FooVersion1 et FooVersion2 Cliquez sur OK
  6. Ajoutez la ligne suivante à Main dans le type de programme du projet Consumer:

    Acme.Foo f = new Acme.Foo();
    

Générez la solution via Ctrl + Maj + B (ou F6) Notez que vous obtenez deux erreurs de génération [comme indiqué ci-dessous]:

enter image description here

Le correctif

Voici comment nous pouvons y remédier:

  1. Ouvrez l'Explorateur de solutions et sélectionnez FooVersion1 dans le dossier Références du projet Consumer
  2. Appuyez sur F4 (ou sélectionnez Affichage | Fenêtre Propriétés)
  3. Remplacez la propriété Alias ​​par FooVersion1
  4. Créez la solution
  5. Maintenant, tout se construira correctement, car Acme.Foo se réfère sans ambiguïté à FooVersion2
  6. Ajoutez la directive suivante en haut de Program.cs dans le projet Consumer:

    extern alias FooVersion1;
    
  7. Changez l'utilisation d'Acme.Foo pour:

    FooVersion1::Acme.Foo f = new FooVersion1::Acme.Foo();
    f.Bar();
    
  8. Notez que lorsque vous tapez "f", la liste d'achèvement ne contient que les méthodes de FooVersion1 d'Acme.Foo (notamment elle n'inclut pas Goo)

  9. Générez la solution et tout se construira correctement
  10. Enfin, ajoutez le code suivant sous f.Bar () dans Program.cs du projet Consumer:

    Acme.Foo f2 = new Acme.Foo();
    f2.Goo();
    
  11. Notez que la liste d'achèvement de f2 contient Goo.

  12. Générez à nouveau à l'aide de Ctrl + Maj + B et notez qu'il n'y a toujours pas d'erreur de génération
27
CodingYoshi

vous pouvez utiliser la fonction d'alias de l'option de compilation/reference (Import Metadata) (Options du compilateur C #) pour résoudre vos problèmes, lisez ici pour plus de détails

5
Hiber