Tell me the best way to find the assembly. For example, there are 1k assemblies (* .dll) in the folder and you need to select for example two special assemblies. How do you want to mark (attributes? It seems like it will slowly search with reflexes) for specific assemblies for quick search in another program?

Maybe there is some way to add something in the meta-table of the assembly so that you can very quickly read and understand this assembly, what you need, or not?

  • one
    Maybe you use MEF if you need to search not for assemblies, but types in them. - Vlad
  • @Vlad, I first need to understand from which assembly these types to take .. using MEF, you can identify the desired assembly? - Anton Komyshan
  • You can force MEF to find the type you want in the build directory, for example. - Vlad
  • @Vlad, and how long will it take? You see, maybe the situation is this: I don’t know the type initially, the type is marked with an attribute, the attribute is in a different assembly, so be it with such a script? Never worked with MEF. - Anton Komyshan

4 answers 4

You can use the Mono.Cecil library (also available via NuGet) and use it to analyze assemblies .

For the test, I took almost all the assemblies from the GAC , copied them to get ~ 1 thousand assemblies, added several copies of my libraries with the required attribute and executed the following code:

 var assemblys = Directory.GetFiles("C:\\dlls\\") .Select(AssemblyDefinition.ReadAssembly) .Where(assembly => assembly.CustomAttributes.Any(ca=> ca.AttributeType.Name == "MyCustomAttribute")) .ToList(); 

He gave the result in ~ 600 milliseconds (measured with Stopwatch ). It seems to me that this may be enough for you.

  • Thanks, yes it looks like this is what I need! - Anton Komyshan
  • one
    Similarly, Cecil can read information from assemblies without downloading them. - andreycha

The main loss of speed will be when the assembly is loaded into the domain. Further analysis of the assembly, as compared with its loading, is cheap, so that there is at least an attribute to hang on, anything. If you go this way, do not forget to do it in a separate appdomene, then to unload unnecessary assemblies.

What can you think of without downloading all the assemblies to the domain:

  • The quickest option would be to search for an assembly simply by name.
  • Sign the assembly with a specific key. When searching, read the key and compare it with the necessary one.
  • Mark assemblies with a dummy version (for example, 127.0.0.1). When searching read version.
  • Try to add a few bytes in dll, having encoded your marker in them, without damaging the assembly. Then open the assembly as a stream byte and read markers.
  • The first option is not an approach since the name is not known. The second option looks attractive. Thank. - Anton Komyshan
  • @AntonKomyshan updated the answer, look at the other options. - andreycha

I faced a similar problem, and solved it for myself with the help of a static definition of the necessary libraries.

That is, when compiling / installing the program, a special utility determines which of the assemblies should be downloaded, and puts this data into a special place (for example, a file). Now the main program should simply read this file and load the necessary assemblies, without the need for run-time testing.

When adding assemblies to a directory (or deleting from it), the same utility should be automatically launched, which will update the list. There is no need to allow the user to add / remove assemblies.


On the other hand, if you are writing a plug-in system, you may not need to reinvent the wheel, and use the built-in System.AddIn framework .

    I do not know whether this solution is suitable for your problem. But the meaning is approximately as follows:

    You will need an interface that describes the functionality of the classes that will be loaded from assemblies:

     public interface ISomeTypeInterface { string Name { get; } } 

    After that in assemblies you declare types as follows:

     [Export(typeof(ISomeTypeInterface))] public class SomeType1 : ISomeTypeInterface { public string Name { get { return "Hello, world!"; } } } 

    Further, in the place where you need to collect it all write:

     class SomeClass { [ImportMany] private ISomeTypeInterface[] SomeTypes { get; set; } } void ComposeParts() { var someClass = new SomeClass(); // Каталог, в котором нужно искать типы можно настраивать более тонко, используя других наследников ComposablePartCatalog или создавая своих using (var catalog = new DirectoryCatalog(".")) using (var container = new CompositionContainer(catalog)) { container.ComposeParts(someClass); } foreach (var t in someClass.SomeTypes) { Console.WriteLine(t.Name); } } 

    If this type of algorithm works for you, then I would advise using MEF. I can not say about the speed of work. We did not have to speed up this mechanism, although it is often used thickly.

    • Thanks, interesting solution, but for now the ApInvent solution suits me best. As for the time and for the need to change something with already written assemblies. - Anton Komyshan