Discussion:
enum visibility across assemblies
(too old to reply)
dave
2009-09-28 16:01:02 UTC
Permalink
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??
Scott M.
2009-09-29 17:21:12 UTC
Permalink
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
Post by dave
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
2009-09-29 17:48:01 UTC
Permalink
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.
Post by Scott M.
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
Post by dave
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??
Chris Taylor
2009-10-01 10:40:02 UTC
Permalink
Hi,

Can you post a sample of the current declaration of one of the enums that
you are referring to?
--
Chris Taylor
http://taylorza.blogspot.com
http://twitter.com/taylorza
Post by dave
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.
Post by Scott M.
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
Post by dave
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
2009-10-01 11:11:01 UTC
Permalink
namespace myproject.Objects
{
public enum eMinMax { Min, Max };//for max/min description on
performance requirements

}
Post by Chris Taylor
Hi,
Can you post a sample of the current declaration of one of the enums that
you are referring to?
--
Chris Taylor
http://taylorza.blogspot.com
http://twitter.com/taylorza
Post by dave
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.
Post by Scott M.
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
Post by dave
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??
Jie Wang [MSFT]
2009-10-05 08:49:11 UTC
Permalink
Hi Dave,

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:
***@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

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.
dave
2009-10-05 12:05:01 UTC
Permalink
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:

e.Value = Enum.Parse(Type.GetType(type), stringvalue);

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:

e.Value = (eCkt)Enum.Parse(typeof(eCkt), stringvalue);


the exception:

System.ArgumentNullException occurred
Message="Value cannot be null.\r\nParameter name: enumType"
Source="mscorlib"
ParamName="enumType"
StackTrace:
at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
InnerException:

the stack:

mscorlib.dll!System.Enum.Parse(System.Type enumType, string value, bool
ignoreCase) + 0x2c3 bytes
mscorlib.dll!System.Enum.Parse(System.Type enumType, string value) + 0x7
bytes
TERA.Controls.dll!TERA.Controls.Tree.TERATreeView.propertyBag_GetValue(object sender = {TERA.Controls.Tree.PropertyBag}, TERA.Controls.Tree.PropertySpecEventArgs e = {TERA.Controls.Tree.PropertySpecEventArgs}) Line 67 + 0x36 bytes C#
TERA.Controls.dll!TERA.Controls.Tree.PropertyBag.OnGetValue(TERA.Controls.Tree.PropertySpecEventArgs
e = {TERA.Controls.Tree.PropertySpecEventArgs}) Line 872 + 0x1a bytes C#

TERA.Controls.dll!TERA.Controls.Tree.PropertyBag.PropertySpecDescriptor.GetValue(object
component = {TERA.Controls.Tree.PropertyBag}) Line 796 + 0xe bytes C#

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.GetPropEntries(System.Windows.Forms.PropertyGridInternal.GridEntry
peParent =
{System.Windows.Forms.PropertyGridInternal.SingleSelectRootGridEntry
TERA.Controls.Tree.PropertyBag}, object obj =
{TERA.Controls.Tree.PropertyBag}, System.Type objType) + 0x38c bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.CreateChildren(bool diffOldChildren = false) + 0xc6 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.SingleSelectRootGridEntry.CreateChildren() + 0x13 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.InternalExpanded.set(bool value) + 0x79 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.SingleSelectRootGridEntry.SingleSelectRootGridEntry(System.Windows.Forms.PropertyGridInternal.PropertyGridView
gridEntryHost, object value,
System.Windows.Forms.PropertyGridInternal.GridEntry parent,
System.IServiceProvider baseProvider,
System.ComponentModel.Design.IDesignerHost host,
System.Windows.Forms.Design.PropertyTab tab,
System.Windows.Forms.PropertySort sortType) + 0x86 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.Create(System.Windows.Forms.PropertyGridInternal.PropertyGridView
view, object[] rgobjs, System.IServiceProvider baseProvider,
System.ComponentModel.Design.IDesignerHost currentHost,
System.Windows.Forms.Design.PropertyTab tab,
System.Windows.Forms.PropertySort initialSortType) + 0x69 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGrid.UpdateSelection()
+ 0x14a bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGrid.RefreshProperties(bool clearCached) + 0x92 bytes
System.Windows.Forms.dll!System.Windows.Forms.PropertyGrid.Refresh(bool
clearCached) + 0x6d bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGrid.SelectedObjects.set(object[] value) + 0x92e bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGrid.SelectedObject.set(object value) + 0x4d bytes

TERA.Controls.dll!TERA.Controls.Tree.TERATreeView.OnMouseUp(System.Windows.Forms.MouseEventArgs
e = {X = 154 Y = 300 Button = Left}) Line 1081 + 0x2d bytes C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref
System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int
clicks) + 0x28f bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref
System.Windows.Forms.Message m) + 0x885 bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x10 bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes

System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr
hWnd, int msg = 514, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes
[Native to Managed Transition]
[Managed to Native Transition]

System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x24e bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int
reason = -1, System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x177 bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int
reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) + 0x31 bytes
TERAApp.exe!TERAApp.Program.Main() Line 17 + 0x1d bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile,
System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x3a bytes

Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object
state) + 0x66 bytes

mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext
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
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.PropertyDescriptorGridEntry.TypeConverter.get() + 0x20 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.GetPropertyTextValue(object value = Shield) + 0x2f bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.GetPropertyTextValue() + 0x1c bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.PropertyGridView.SelectRow(int row = 3) + 0x18d bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.PropertyGridView.SelectGridEntry(System.Windows.Forms.PropertyGridInternal.GridEntry
gridEntry, bool fPageIn) + 0xb8 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.PropertyGridView.OnGridEntryValueClick(object s, System.EventArgs e) + 0x64 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.RaiseEvent(object key, System.EventArgs e) + 0x41 bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.OnValueClick(System.EventArgs e) + 0x2a bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.GridEntry.OnMouseClick(int
x, int y, int count, System.Windows.Forms.MouseButtons button) + 0x18f bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry.OnMouseClick(int
x, int y, int count, System.Windows.Forms.MouseButtons button) + 0xdf bytes

System.Windows.Forms.dll!System.Windows.Forms.PropertyGridInternal.PropertyGridView.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.PropertyGridView.WndProc(ref System.Windows.Forms.Message m) + 0x20b bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x10 bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes

System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr
hWnd, int msg = 513, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes
[Native to Managed Transition]
[Managed to Native Transition]

System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x24e bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int
reason = -1, System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x177 bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int
reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) + 0x31 bytes
TERAApp.exe!TERAApp.Program.Main() Line 17 + 0x1d bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile,
System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x3a bytes

Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object
state) + 0x66 bytes

mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext
executionContext, System.Threading.ContextCallback callback, object state) +
0x6f bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes
Hi Dave,
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
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.
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.
Jie Wang [MSFT]
2009-10-06 11:13:46 UTC
Permalink
Hi Dave,

This line:

e.Value = Enum.Parse(Type.GetType(type), stringvalue);

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:
***@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

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.
dave
2009-10-06 11:37:02 UTC
Permalink
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.
Post by Jie Wang [MSFT]
Hi Dave,
e.Value = Enum.Parse(Type.GetType(type), stringvalue);
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
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.
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.
Günter Prossliner
2009-10-06 12:31:53 UTC
Permalink
Hello Dave!
Post by dave
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.

see:
[Type.GetType Method (String) (System)]
http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx

"
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.
"
Post by dave
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).

check out:

[Type.AssemblyQualifiedName Property (System)]
http://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname.aspx


Another option would be to traverse the *loaded* assemblies for a specific
type.

Maybe with a "cool" C# 3.0 Implementation:

static Type GetType(string partialName) {
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a=>a.GetTypes())
.First(t=>t.Name == partialName);
}


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.

static void LoadAllReferences() {
var allReferences =
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetReferencedAssemblies())
.Distinct(AssemblyNameEqualityComparer.Default);

foreach (var reference in allReferences)
Assembly.Load(reference);
}

class AssemblyNameEqualityComparer : IEqualityComparer<AssemblyName> {

public static AssemblyNameEqualityComparer Default = new
AssemblyNameEqualityComparer();

public bool Equals(AssemblyName x, AssemblyName y) {
return x.FullName == y.FullName;
}

public int GetHashCode(AssemblyName obj) {
return obj.FullName.GetHashCode();
}

}



OK?
GP
dave
2009-10-06 14:10:01 UTC
Permalink
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.
Post by Günter Prossliner
Hello Dave!
Post by dave
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.
[Type.GetType Method (String) (System)]
http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx
"
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.
"
Post by dave
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).
[Type.AssemblyQualifiedName Property (System)]
http://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname.aspx
Another option would be to traverse the *loaded* assemblies for a specific
type.
static Type GetType(string partialName) {
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a=>a.GetTypes())
.First(t=>t.Name == partialName);
}
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.
static void LoadAllReferences() {
var allReferences =
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetReferencedAssemblies())
.Distinct(AssemblyNameEqualityComparer.Default);
foreach (var reference in allReferences)
Assembly.Load(reference);
}
class AssemblyNameEqualityComparer : IEqualityComparer<AssemblyName> {
public static AssemblyNameEqualityComparer Default = new
AssemblyNameEqualityComparer();
public bool Equals(AssemblyName x, AssemblyName y) {
return x.FullName == y.FullName;
}
public int GetHashCode(AssemblyName obj) {
return obj.FullName.GetHashCode();
}
}
OK?
GP
Günter Prossliner
2009-10-06 14:45:56 UTC
Permalink
Hello dave!
Post by dave
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");



OK?
GP
Jie Wang [MSFT]
2009-10-07 11:27:46 UTC
Permalink
Hi GP,

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\nType {0} found!", t.ToString());

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.

Regards,
Jie
Günter Prossliner
2009-10-07 11:55:07 UTC
Permalink
Hello Jie Wang!
Post by Jie Wang [MSFT]
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
Post by Jie Wang [MSFT]
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.


GP
dave
2009-10-07 12:06:01 UTC
Permalink
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.
Post by Jie Wang [MSFT]
Hi GP,
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*.
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
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\nType {0} found!", t.ToString());
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.
Regards,
Jie
Jie Wang [MSFT]
2009-10-08 04:13:07 UTC
Permalink
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.

The Remark section on this page
(http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx) provides a very
detailed description of the behaviors and rules.

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:
***@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

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.
Jie Wang [MSFT]
2009-10-07 11:35:06 UTC
Permalink
Hi Dave,

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:
***@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

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.
Loading...