i have a solution with several c# projects in it to group common stuff like custom controls in one assembly, common object definitions in another one, xml conversion stuff in another one... trying to keep common stuff grouped together. I created a new 'objects' assembly to collect up the solutions common objects and definitions and ran into a problem with enumerations. when i move a cs file that has a bunch of common enumerations declared at the namespace level from my common controls assembly to the new objects assembly the property pages that use the enumerations break. This is a PropertyGrid control that is being filled with dynamically generated property information. This works fine when the enum is in the same assembly as the code that generates the dynamic property list, but when the enum is moved it throws a null argument error in the GetDescriptor method of System.ComponentModel.TypeDescriptor. It appears that the framework code doesn't have access to the enum types in the new assembly, but did in the other one. Is there something that has to be done to the enum declarations to make them visible at a higher level??
Rather than attempting to move the source code files into your solutions, why don't you just have your projects reference the assembly that's got the object you want to use?
-Scott
"dave" <eprid...@newsgroup.nospam> wrote in message
>i have a solution with several c# projects in it to group common stuff like > custom controls in one assembly, common object definitions in another one, > xml conversion stuff in another one... trying to keep common stuff grouped > together. I created a new 'objects' assembly to collect up the solutions > common objects and definitions and ran into a problem with enumerations. > when i move a cs file that has a bunch of common enumerations declared at > the > namespace level from my common controls assembly to the new objects > assembly > the property pages that use the enumerations break. This is a > PropertyGrid > control that is being filled with dynamically generated property > information. > This works fine when the enum is in the same assembly as the code that > generates the dynamic property list, but when the enum is moved it throws > a > null argument error in the GetDescriptor method of > System.ComponentModel.TypeDescriptor. It appears that the framework code > doesn't have access to the enum types in the new assembly, but did in the > other one. Is there something that has to be done to the enum > declarations > to make them visible at a higher level??
maybe i wasn't specific enough.. i am not moving between solutions. this is a single solution where i have several class library assemblies to group together things like controls, business objects, xml conversion code, and other things. What i was moving was a file of enums from one project/class library to a different more generic project/class library that made more sense... ALL of my uses of the enums work just fine, all the projects can reference the other class library and get the enums just fine, including the old one which is where the dynamic properties were generated. The problem is that it looks like the framework componentmodel methods can't seem to make the connection to the different class library for those enums.
"Scott M." wrote: > Rather than attempting to move the source code files into your solutions, > why don't you just have your projects reference the assembly that's got the > object you want to use?
> -Scott
> "dave" <eprid...@newsgroup.nospam> wrote in message > news:C461A6E7-51EF-4783-875C-179E10D53021@microsoft.com... > >i have a solution with several c# projects in it to group common stuff like > > custom controls in one assembly, common object definitions in another one, > > xml conversion stuff in another one... trying to keep common stuff grouped > > together. I created a new 'objects' assembly to collect up the solutions > > common objects and definitions and ran into a problem with enumerations. > > when i move a cs file that has a bunch of common enumerations declared at > > the > > namespace level from my common controls assembly to the new objects > > assembly > > the property pages that use the enumerations break. This is a > > PropertyGrid > > control that is being filled with dynamically generated property > > information. > > This works fine when the enum is in the same assembly as the code that > > generates the dynamic property list, but when the enum is moved it throws > > a > > null argument error in the GetDescriptor method of > > System.ComponentModel.TypeDescriptor. It appears that the framework code > > doesn't have access to the enum types in the new assembly, but did in the > > other one. Is there something that has to be done to the enum > > declarations > > to make them visible at a higher level??
> maybe i wasn't specific enough.. i am not moving between solutions. this > is > a single solution where i have several class library assemblies to group > together things like controls, business objects, xml conversion code, and > other things. What i was moving was a file of enums from one > project/class > library to a different more generic project/class library that made more > sense... ALL of my uses of the enums work just fine, all the projects can > reference the other class library and get the enums just fine, including > the > old one which is where the dynamic properties were generated. The problem > is > that it looks like the framework componentmodel methods can't seem to make > the connection to the different class library for those enums.
> "Scott M." wrote:
>> Rather than attempting to move the source code files into your solutions, >> why don't you just have your projects reference the assembly that's got >> the >> object you want to use?
>> -Scott
>> "dave" <eprid...@newsgroup.nospam> wrote in message >> news:C461A6E7-51EF-4783-875C-179E10D53021@microsoft.com... >> >i have a solution with several c# projects in it to group common stuff >> >like >> > custom controls in one assembly, common object definitions in another >> > one, >> > xml conversion stuff in another one... trying to keep common stuff >> > grouped >> > together. I created a new 'objects' assembly to collect up the >> > solutions >> > common objects and definitions and ran into a problem with >> > enumerations. >> > when i move a cs file that has a bunch of common enumerations declared >> > at >> > the >> > namespace level from my common controls assembly to the new objects >> > assembly >> > the property pages that use the enumerations break. This is a >> > PropertyGrid >> > control that is being filled with dynamically generated property >> > information. >> > This works fine when the enum is in the same assembly as the code that >> > generates the dynamic property list, but when the enum is moved it >> > throws >> > a >> > null argument error in the GetDescriptor method of >> > System.ComponentModel.TypeDescriptor. It appears that the framework >> > code >> > doesn't have access to the enum types in the new assembly, but did in >> > the >> > other one. Is there something that has to be done to the enum >> > declarations >> > to make them visible at a higher level??
> "dave" <eprid...@newsgroup.nospam> wrote in message > news:90892B46-D2A7-4043-821C-0B74CD990748@microsoft.com... > > maybe i wasn't specific enough.. i am not moving between solutions. this > > is > > a single solution where i have several class library assemblies to group > > together things like controls, business objects, xml conversion code, and > > other things. What i was moving was a file of enums from one > > project/class > > library to a different more generic project/class library that made more > > sense... ALL of my uses of the enums work just fine, all the projects can > > reference the other class library and get the enums just fine, including > > the > > old one which is where the dynamic properties were generated. The problem > > is > > that it looks like the framework componentmodel methods can't seem to make > > the connection to the different class library for those enums.
> > "Scott M." wrote:
> >> Rather than attempting to move the source code files into your solutions, > >> why don't you just have your projects reference the assembly that's got > >> the > >> object you want to use?
> >> -Scott
> >> "dave" <eprid...@newsgroup.nospam> wrote in message > >> news:C461A6E7-51EF-4783-875C-179E10D53021@microsoft.com... > >> >i have a solution with several c# projects in it to group common stuff > >> >like > >> > custom controls in one assembly, common object definitions in another > >> > one, > >> > xml conversion stuff in another one... trying to keep common stuff > >> > grouped > >> > together. I created a new 'objects' assembly to collect up the > >> > solutions > >> > common objects and definitions and ran into a problem with > >> > enumerations. > >> > when i move a cs file that has a bunch of common enumerations declared > >> > at > >> > the > >> > namespace level from my common controls assembly to the new objects > >> > assembly > >> > the property pages that use the enumerations break. This is a > >> > PropertyGrid > >> > control that is being filled with dynamically generated property > >> > information. > >> > This works fine when the enum is in the same assembly as the code that > >> > generates the dynamic property list, but when the enum is moved it > >> > throws > >> > a > >> > null argument error in the GetDescriptor method of > >> > System.ComponentModel.TypeDescriptor. It appears that the framework > >> > code > >> > doesn't have access to the enum types in the new assembly, but did in > >> > the > >> > other one. Is there something that has to be done to the enum > >> > declarations > >> > to make them visible at a higher level??
The GetDescriptor method is an internal method of the TypeDescriptor class. One of its overloads takes a Type and a String as its parameters. If the Type parameter is null, it will throw an ArgumentNullException.
So now we need to find out who called this method and passed in null. It could be any of the Get* public methods of the TypeDescriptor class.
Did you got this exception at design time or runtime?
Could you show me the call stack of the exception so we can narrow down the cause of the problem?
Thanks, Jie Wang
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and suggestions about how we can improve the support we provide to you. Please feel free to let my manager know what you think of the level of service provided. You can send feedback directly to my manager at: msd...@microsoft.com.
Note: MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 2 business days is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
I have continued with development that has unfortunately changed the symptom a bit. This may be easier to diagnose now... as before, this is a propertygrid that is filled with dynamically generated property descriptors, some of which are these enumerated types. When the class declaring the enums is in the same assembly as the property grid control it all works fine, when i move the enums declaration to my 'objects' assembly where i would like to have my generic objects and definitions i get black boxes in the property grid where there should be enum lists. i now have to manually enable breaking when exceptions are thrown to catch the exception since something is catching it normally. it now breaks on my line:
which is in the function that is getting the value to put in the property grid. 'type' is the name of the type which is correct, and stringvalue is one of the values in the enum... as i said this works when the enum is in the same assembly as this code. what is interesting is other uses of the enums don't throw error in this function, for instance this line doesn't throw an error and returns a proper value:
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.Executi onContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes --------------------------------------------------------------------------- -------------------- Note, i can still get the argumentnullexception in getdescriptor if i click on one of the black boxes in the property grid, that does crash the app with a call stack like this:
> System.dll!System.ComponentModel.TypeDescriptor.GetDescriptor(System.Type type, string typeName = "type") Line 1555 C#
System.dll!System.ComponentModel.TypeDescriptor.GetConverter(System.Type type) Line 1468 + 0x10 bytes C# System.dll!System.ComponentModel.PropertyDescriptor.Converter.get() Line 100 + 0x14 bytes C#
System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntr y.OnMouseClick(int x, int y, int count, System.Windows.Forms.MouseButtons button) + 0x18f bytes
System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.Property DescriptorGridEntry.OnMouseClick(int x, int y, int count, System.Windows.Forms.MouseButtons button) + 0xdf bytes
System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.Property GridView.OnMouseDown(System.Windows.Forms.MouseEventArgs me) + 0x15b bytes System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseDown(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) + 0xcf bytes System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x86e bytes
System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.Property GridView.WndProc(ref System.Windows.Forms.Message m) + 0x20b bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.O nMessage(ref System.Windows.Forms.Message m) + 0x10 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.W ndProc(ref System.Windows.Forms.Message m) + 0x31 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallba ck(System.IntPtr hWnd, int msg = 513, System.IntPtr wparam, System.IntPtr
Looks like Type.GetType returns null, which means the method couldn't find the type defined in your variable "type".
Could you check the value of "type" at that time and see if its value (should be an assembly-qualified name of the "eMinMax" enum) matches the correct assembly-qualified name of the enum that has been moved to the new assembly?
Thanks, Jie Wang
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and suggestions about how we can improve the support we provide to you. Please feel free to let my manager know what you think of the level of service provided. You can send feedback directly to my manager at: msd...@microsoft.com.
Note: MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 2 business days is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
ah, that is where the rub is... if i break at that line and look at the string in 'type', then yes that assembly knows about that type. it is properly referenced and can be used just fine. however, you are right, the Type.GetType function can't find the enum definition when it is in a different assembly. My best guess about what is happing is that the GetType function only looks in the current assembly instead of all assemblies referenced to find the value of the enum? I am hoping that there is a setting somewhere i haven't found, an attribute that can be added to the enum, or some kind of compiler directive that would let an enum be found at runtime from a referenced assembly and not just from the current assembly itself.
> Looks like Type.GetType returns null, which means the method couldn't find > the type defined in your variable "type".
> Could you check the value of "type" at that time and see if its value > (should be an assembly-qualified name of the "eMinMax" enum) matches the > correct assembly-qualified name of the enum that has been moved to the new > assembly?
> Thanks, > Jie Wang
> Microsoft Online Community Support
> Delighting our customers is our #1 priority. We welcome your comments and > suggestions about how we can improve the support we provide to you. Please > feel free to let my manager know what you think of the level of service > provided. You can send feedback directly to my manager at: > msd...@microsoft.com.
> Note: MSDN Managed Newsgroup support offering is for non-urgent issues > where an initial response from the community or a Microsoft Support > Engineer within 2 business days is acceptable. Please note that each follow > up response may take approximately 2 business days as the support > professional working with you may need further investigation to reach the > most efficient resolution. The offering is not appropriate for situations > that require urgent, real-time or phone-based interactions. Issues of this > nature are best handled working with a dedicated Microsoft Support Engineer > by contacting Microsoft Customer Support Services (CSS) at > http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx > ================================================== > This posting is provided "AS IS" with no warranties, and confers no rights.
> My best guess about what is > happing is that the GetType function only looks in the current > assembly instead of all assemblies referenced to find the value of > the enum?
Not exactly. Type.GetType() searches the current Assembly and mscorlib.
" Parameters typeName The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace. "
> I am hoping that there is a setting somewhere i haven't > found, an attribute that can be added to the enum, or some kind of > compiler directive that would let an enum be found at runtime from a > referenced assembly and not just from the current assembly itself.
There is nothing like that. For the Type.GetType(name) method you have to use the AssemblyQualifiedName of the Type if it's not declared within the current assembly or mscorlib.
check "typeof(EnumType).AssemblyQualifiedName" for the right declaration. If the Assembly has no strong-name it is just "Namespace.Typename, AssemblyName", but for Assemblies with a strong name you have to include the version and the publickeytoken as well like "Namespace.Typename, AssemblyName, Version=x.y, PublicKeyToken=XXXX". There are also other attributes which may be signicifant (like the culture).
But be aware of the fact that this method doesn't try to load the Type if it is not already loaded (what Type.GetType actually does). Of cause you may load all references Assemblies before, but I won't recommend this to you, since this would be a very "heavyweight" operation.
well, i tried loading the specific assembly before doing the GetType call and that didn't fix it. Then i tried adding in the assembly qualified name and that got me access, but is requiring a lot of changes to the code and i would worry about future compatibility issues when future revisions of assemblies are generated.... it would look like that might tie the generic objects assembly changes to the property grid assembly anyway. Since that property grid is probably the only place i need type information from the enums i'll probably just leave the definitions in that assembly.
> > My best guess about what is > > happing is that the GetType function only looks in the current > > assembly instead of all assemblies referenced to find the value of > > the enum?
> Not exactly. Type.GetType() searches the current Assembly and mscorlib.
> " > Parameters > typeName > The assembly-qualified name of the type to get. See > AssemblyQualifiedName. > If the type is in the currently executing assembly or in > Mscorlib.dll, > it is sufficient to supply the type name qualified by its namespace. > "
> > I am hoping that there is a setting somewhere i haven't > > found, an attribute that can be added to the enum, or some kind of > > compiler directive that would let an enum be found at runtime from a > > referenced assembly and not just from the current assembly itself.
> There is nothing like that. For the Type.GetType(name) method you have to > use the AssemblyQualifiedName of the Type if it's not declared within the > current assembly or mscorlib.
> check "typeof(EnumType).AssemblyQualifiedName" for the right declaration. If > the Assembly has no strong-name it is just "Namespace.Typename, > AssemblyName", but for Assemblies with a strong name you have to include the > version and the publickeytoken as well like "Namespace.Typename, > AssemblyName, Version=x.y, PublicKeyToken=XXXX". There are also other > attributes which may be signicifant (like the culture).
> But be aware of the fact that this method doesn't try to load the Type if it > is not already loaded (what Type.GetType actually does). Of cause you may > load all references Assemblies before, but I won't recommend this to you, > since this would be a very "heavyweight" operation.
> well, i tried loading the specific assembly before doing the GetType > call and that didn't fix it.
I think you missed the point.
Type.GetType() *never* seaches any other assembly then the executing assembly and mscorlib, regardless of which assemblies being loaded.
Eigher you take the AssemblyQualifiedName (which you don't like), or you find the Type by traversing the Types of the loaded Assemblies by a method like the one I've posted before:
class TypeUtil { static Type GetLoadedTypeByName(string partialName) { return AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a=>a.GetTypes()) .First(t=>t.Name == partialName);
} }
usage:
Type enumType = TypeUtil.GetLoadedTypeByName("Namespace.EnumType");
With respect, your statement "Type.GetType() *never* seaches any other assembly then the executing assembly and mscorlib, regardless of which assemblies being loaded." is *wrong*.
According to the MSDN document on Type.GetType method:
You can use the GetType method to obtain a Type object for a type in another assembly, if the you know its namespace-qualified name. GetType causes loading of the assembly specified in typeName.
And here I can prove it with a simple console app that demonstrates the behavior:
public static void Main() { Console.WriteLine("Before GetType, the list of loaded assemblies:\r\n");
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { Console.WriteLine(asm.ToString()); }
Type t = Type.GetType("System.Xml.XmlDocument, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
Console.WriteLine("\r\nAfter GetType, the list of loaded assemblies:\r\n");
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { Console.WriteLine(asm.ToString()); }
}
As long as you provide the valid namespace-qualified name and CLR can find that corresponding assembly and load it, it will work. Not just mscorlib and the running assembly as you said.
To make GetType work, the corresponding assembly must be loaded rather than just referenced in your project. Referencing an assembly at design time doesn't necessarily mean it will be loaded at runtime. If you don't load it, then you need to make sure the CLR can find and load it for you by namespace-qualified name.
Regarding the design, I agree that you'd probably stick the enum with your grid if it is only used by that control.
Regards, Jie Wang
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and suggestions about how we can improve the support we provide to you. Please feel free to let my manager know what you think of the level of service provided. You can send feedback directly to my manager at: msd...@microsoft.com.
Note: MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 2 business days is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
> With respect, your statement "Type.GetType() *never* seaches any other > assembly then the executing assembly and mscorlib, regardless of which > assemblies being loaded." is *wrong*.
Sorry, the statement should rather be:
Type.GetType() *never* seaches any other assembly then the executing assembly and mscorlib, regardless of which assemblies being loaded *if you don't use the AssemblyQualifiedName*.
I've missed this part of the sentence here, but I've described it correctly in my original post:
>> For the Type.GetType(name) method you have to use the >> AssemblyQualifiedName >> of the Type if it's not declared within the current assembly or mscorlib. > As long as you provide the valid namespace-qualified name and CLR can > find that corresponding assembly and load it, it will work. Not just > mscorlib and the running assembly as you said.
Yes, absolutly. But Dave just want to use the Name of the Type, without qualified names.
so if the assembly is loaded do i need the assembly qualified name for gettype or just the namespace.enum name?? When i try dumping loaded assemblies in my main the assembly with my enum definitions was already loaded but the property grid couldn't find them using the namespace.enum name.
> With respect, your statement "Type.GetType() *never* seaches any other > assembly then the executing assembly and mscorlib, regardless of which > assemblies being loaded." is *wrong*.
> According to the MSDN document on Type.GetType method:
> You can use the GetType method to obtain a Type object for a type in > another assembly, if the you know its namespace-qualified name. GetType > causes loading of the assembly specified in typeName.
> And here I can prove it with a simple console app that demonstrates the > behavior:
> public static void Main() > { > Console.WriteLine("Before GetType, the list of loaded assemblies:\r\n");
> As long as you provide the valid namespace-qualified name and CLR can find > that corresponding assembly and load it, it will work. Not just mscorlib > and the running assembly as you said.
Let's take a look at the parameter description of Type.GetType(string typeName) method:
typeName Type: System.String
The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.
So unless the type is the currently executing assembly or in mscorlib, you must provide the assembly-qualified name. And of course, always provide the assembly-qualified name will be safe all the time.
Delighting our customers is our #1 priority. We welcome your comments and suggestions about how we can improve the support we provide to you. Please feel free to let my manager know what you think of the level of service provided. You can send feedback directly to my manager at: msd...@microsoft.com.
Note: MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 2 business days is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.