85 votes

C#/.NET: Est-il un moyen de forcer tous les assemblys référencés à être chargé dans le domaine de l'application?

Mes projets sont mis en place comme ceci:

  • Projet "Définition"
  • Projet "Mise En Œuvre"
  • Projet De "Consommateur"

Projet de "Consommateur", de références à la fois "Définition" et "mise en Œuvre", mais n'est pas statique de référence de tous les types de "mise en Œuvre".

Lorsque l'application démarre, le Projet de "Consommateur", les appels à une méthode statique dans "Définition", qui a besoin de trouver des types de "mise en Œuvre"

Est-il un moyen pour que je puisse la force de l'assembly référencé pour être chargé dans le Domaine de l'Application sans connaître le chemin d'accès ou le nom, et de préférence sans avoir à utiliser un acteur à part entière du CIO cadre?

92voto

Daniel Schaffer Points 14707

Cela semblait faire l'affaire:

        var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
        var loadedPaths = loadedAssemblies.Select(a => a.Location).ToArray();

        var referencedPaths = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll");
        var toLoad = referencedPaths.Where(r => !loadedPaths.Contains(r, StringComparer.InvariantCultureIgnoreCase)).ToList();
        toLoad.ForEach(path => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(path))));

Comme Jon l'a noté, la solution idéale serait de devez répéter dans les dépendances de chacun des chargés assemblées, mais dans mon scénario je n'ai pas à m'en soucier.


Mise À Jour: Le Managed Extensibility Framework (Système D'.ComponentModel) inclus dans .NET 4 a beaucoup plus de facilités pour l'accomplissement des choses comme ça.

64voto

Jon Skeet Points 692016

Vous pouvez utiliser Assembly.GetReferencedAssemblies pour obtenir un AssemblyName[], puis appelez Assembly.Load(AssemblyName) sur chacun d'eux. Vous aurez besoin de répéter, bien sûr - mais de préférence à garder la trace des assemblées que vous avez déjà chargé :)

16voto

Meirion Hughes Points 1855

Si vous utilisez Fody.Costura, ou de toute autre assemblée de la fusion de la solution, de la accepté de répondre ne fonctionnera pas.

Les charges suivantes les Assemblys Référencés de tout actuellement chargés de l'Assemblée. La récursivité est laissé à vous.

var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();

loadedAssemblies
    .SelectMany(x => x.GetReferencedAssemblies())
    .Distinct()
    .Where(y => loadedAssemblies.Any((a) => a.FullName == y.FullName) == false)
    .ToList()
    .ForEach(x => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(x)));

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