12

Apologies if I'm missing something obvious, but when I create a new type with Reflection.Emit, how do I specify what namespace it should be in?

ie..

AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "TestDynamic";

AssemblyBuilder assemblyBuilder = 
    AppDomain.CurrentDomain.DefineDynamicAssembly(
        assemblyName,   
        AssemblyBuilderAccess.Save);

ModuleBuilder moduleBuilder =    
    AssemblyBuilder.DefineDynamicModule("TestDynamic", "TestDynamic.dll");

TypeBuilder myTestInterface =
    moduleBuilder.DefineType("MyTestInterface", 
    TypeAttributes.Public | TypeAttributes.Interface, typeof(object));

How do I give a namespace for myTestInterface?

Binary Worrier
  • 50,774
  • 20
  • 136
  • 184

2 Answers2

17

Define it where you define the type:

moduleBuilder.DefineType("MyNamespace.MyTestInterface",
               TypeAttributes.Public | TypeAttributes.Interface,
                typeof(object));
Aliostad
  • 80,612
  • 21
  • 160
  • 208
0

Just put it before the "short" typename. "Namespace.Subnamespace.Type"

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • That's simply not true, types are identified per scope (assembly, module, or another type if the type is nested), namespace and name. – Jb Evain Nov 18 '10 at 15:16
  • i forgot to add the assembly. still, the CLR doesn't know anything about namespaces as far as i know. – Botz3000 Nov 19 '10 at 07:49
  • The ECMA-335 specifies that types are identified by their fullname within the scope of their respective assemblies. Their fullname being constructed from the metadata of the types that is composed of the namespace and the name, which are stored as two distinct entities. That's quite a bit different from not knowing anything. In the case of SRE, the implementation will simply split the fullname for you based on the simple rule edicted in the ECMA 335 (split at last dot). – Jb Evain Nov 19 '10 at 10:54
  • The ECMA-335 says "While some programming languages introduce the concept of a namespace, the only support in the CLI for this concept is as a metadata encoding technique. Type names are always specified by their full name relative to the assembly in which they are defined." So for the runtime, it's just a way of storing the full typename. Also, it says: "The full name of the type need not be stored directly. Instead, it can be split into two parts at any included “.”" So it's entirely up to your compiler if typename and namespace are really stored separately (also, at which position). – Botz3000 Nov 19 '10 at 11:26
  • There's a difference between the fully qualified name of the type, which is what you query to retrieve a type, based on its fullname + its assembly fullname (which is the part of the ECMA 335 that you quote is about), and the internals of the CLR which indeeds make the distinction between namespaces and names. The runtime is perfectly able to differentiate two types: (namespace: "Foo" name: "Bar"), and (namespace: "" name:"Foo.Bar") in the same assembly. It wouldn't be able to differentiate them if as you claim, it didn't know about namespaces. – Jb Evain Nov 19 '10 at 17:02
  • Have you tried it? i just created an IL file with one type namespace: "Foo" name:"Bar.Baz" and another type with namespace:"Foo.Bar" name:"Baz", both with a method "Main". I tried to process this file with ilasm, and i got a "Duplicate Method declaration"-Error. In fact, when i changed the method name of the second type and then compiled it, it turned out that both classes were compiled into one single class. Also, the ECMA-335 says: "There shall be no duplicate rows in the TypeDef table, based on TypeNamespace+TypeName (unless this is a nested type - see below) [ERROR]" – Botz3000 Nov 22 '10 at 08:29
  • Of course I tried :) You can generate one very easily with Cecil, and both types will work just fine. Of course you'll have issues with stuff like Type.GetType, but it doesn't mean it's not possible. – Jb Evain Nov 23 '10 at 12:14
  • Hmm, i have not tried Cecil yet. I am sure that it is possible to store two such types using the provided metadata tables, but i think that most other languages and tools will have difficulty using those types. Because as the spec stated, TypeNamespace is just used as a metadata encoding technique. And from my understanding, having two such types in the same assembly would still violate the requirement, as there would be duplicates based on TypeNamespace+TypeName, right? So that would not be a CLS-Compliant assembly. – Botz3000 Nov 23 '10 at 12:28
  • It definitely won't be CLS compliant. For what it's worth, peverify doesn't complain in this case, it only complains if there's two types with the same namespace and the same name. But sure, most languages (that work on name references) will be completely confused. Tools that work on tokens will work though. – Jb Evain Nov 23 '10 at 23:23
  • It seems to me that there is no way to differentiate between two such types even using IL assembler (in its text representation). Anyway, i edited my answer. :) leaving CLS compliance aside, you're right, of course. – Botz3000 Nov 24 '10 at 07:39