7

I have the CompileAssemblyFromSource working for code that only references assemblies that my program (that compiles it) uses. It works beautifully.

However, if I need to compile code that has a "using blah;" statement, it won't be able to find blah and say it is missing a resource.

So if it is "System.Windows.Forms", and I say "compilerparams.ReferencedAssemblies.Add("System.Windows.Forms.dll")", it works.

So I can parse the code file and get all the "using" parameters, but how do I know that those are supposed to be "*.dll" adding, or they are namespaces elsewhere or whatnot? Is there a way for .NET to take in "System.Windows.Forms" and spit back out "System.Windows.Forms.dll" because that's what it needs and so on?

Nick
  • 739
  • 11
  • 22
  • There is no way to find what assembly contains your classes because namespaces can spawn across the asseblies and someone could create the DLL with exactly the same class name and namespaces you use, so your code couldn't compile. To solve an issue, you have to provide binaries, say, satellite assemblies, to be included as a reference along with your source code in the same manner, Visual Studio holds the references (including hashes) – Alan Turing Sep 30 '11 at 03:04
  • What about `Assembly.GetAssembly(typeof(MyType))`?? You would have to know which types were actually in use, not just the using statements, because a single namespace can come from multiple assemblies per @ArturMustafin – mellamokb Sep 30 '11 at 04:22
  • @mellamokb: If you code looks like this : `Assembly.GetAssembly(typeof(MyType))`, it means that type `MyType` is known at complie time (required for use by the `typeof` statement), either the code itself or in the source being compiled, which is not the case. In your case, you have to provide resolution method for the AppDomain.AssemblyResolve event handler to locate and download assemblies. But, anyway, as it is said, you cannot rely only on a source code to resolve the issue – Alan Turing Sep 30 '11 at 05:03
  • In your source code System.Windows.Forms can be a custom class `Forms`, located withing namespace `System.Windows` in a custom assembly not in a GAC (or it CAN be in a GAC, but with different signed key, even with the same assembly/file version), named `System.Windows.Forms.dll`, So there is no way to take string "System.Windows.Forms" and get corresponding assembly – Alan Turing Sep 30 '11 at 05:07
  • Eventually, there is a way, but you should provide full assemby name (including version number, public signature, etc.) as it stored usually in a project files. Generally, without addtional info only KNOWN assemblies in GAC can be loaded at runtime. Even so you have to use AssemblyInfo class to provide an assembly name and get the Assembly object to reference to – Alan Turing Sep 30 '11 at 05:12

1 Answers1

2
  1. Read the article How the Runtime Locates Assemblies
  2. Before compiling the code load all the assemblies found in the locations mentioned in point 1
  3. Load all the types in all the assemblies and keep a dictionary of namespace, type pair
  4. When a using is encountered in the source try adding reference of assemblies from the dictionary in 3
Muhammad Hasan Khan
  • 34,648
  • 16
  • 88
  • 131