.NETGURU
Type Resolution blues - TypeDescriptor.GetConverter fails for external assembly
Messages   Related Types
This message was discovered on microsoft.public.dotnet.framework.clr.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
Post a new message to this list...

Jürgen Weiss
Hi folks,
I have a problem with obtaining the TypeConverter for a Control which is defined
in an external assembly. The problem is that TypeDescriptor.GetConverter() fails
to retrieve the proper converter instance, whereas creating the converter manually
by inspecting the TypeConverter attribute of the property and instantiating the
instance through its construcor works fine.

To make it even weirder the problem only occurs if the code is used in an Active X
Control run from internet explorer - if the control is instantiated from a managed
windows application both approaches lead to the same result.

Here is my code:
-- TestControl.cs, part of a ControlLibrary
using System;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace TypeRes
{
public class TestControl : System.Windows.Forms.Label
{
public MyPropertyType myProperty = new MyPropertyType();
}

[TypeConverter(typeof(MyTypeConverter))]
public class MyPropertyType
{
public string value;
}

public class MyTypeConverter : TypeConverter
{
}
}

-- ActiveXCtrl.cs, part of another Control Library
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.ComponentModel;
using System.Reflection;

namespace TypeRes
{
[Guid("7785814e-401b-4901-a5e6-247e08928582")]
[ProgId("TypeRes.Test.ActiveXCtrl")]
public class ActiveXCtrl : System.Windows.Forms.UserControl
{
public ActiveXCtrl()
{
TypeRes.TestControl control = new TypeRes.TestControl();
Type propertyType = control.myProperty.GetType();

// use TypeDescriptor class to get hold of the converter
object converter1 = TypeDescriptor.GetConverter(propertyType);

// do it manually by examining the TypeConverter attribute of the property type
object[] attr = propertyType.GetCustomAttributes(typeof(TypeConverterAttribute), true);
TypeConverterAttribute ta = attr[0] as TypeConverterAttribute;

Type converterType = Type.GetType(ta.ConverterTypeName);
ConstructorInfo[] ci = converterType.GetConstructors();

object converter2 = ci[0].Invoke(new object []{});;

if (converter1.GetType() != converter2.GetType())
MessageBox.Show(
"!!! The converter types do not match !!!\n\n" +
converter1.GetType().ToString() + " != " + converter2.GetType().ToString());
else
MessageBox.Show(
"Both converters are of type " + converter1.GetType().ToString());
}
}
}

-- TestPage.htm
HTML>
<BODY>
<OBJECT classid="clsid:7785814e-401b-4901-a5e6-247e08928582">
</OBJECT>
</BODY>
</HTML>

-- TestApp.cs, Windows Application
using System;

namespace TypeRes
{
class TestApp
{
[STAThread]
static void Main(string[] args)
{
TypeRes.ActiveXCtrl comCtrl = new TypeRes.ActiveXCtrl();
}
}
}

Now, if I run the test application, the message box shows
"Both converters are of type TypeRes.MyTypeConverter"
If I open TestPage.htm, the message is
"!!! The converter types do not match !!!
System.ComponentModel.TypeConverter != TypeRes.MyTypeConverter"

????
Obviously TypeDescriptor.GetConverter is not able to instantiate the proper
type converter and returns a default implementation.

With the help of the wonderful .Net Reflector tool and a bit of assembly debugging
I found that TypeDescriptor.GetConverter calls the GetTypeFromName method
of the internal class System.ComponentModel.TypeDescriptor.ComponentEntry
which in turn calls Type.GetType(typeName) where typeName is the fully qualified
name of the MyTypeConverter type. The strange thing is that Type.GetType returns
null if called from the System.dll assembly but retrieves a proper value if called from
application code!!!

I would appreciate very much if someone of the CLR experts could shed some light
on this issue.
Thanks for your help!
- Jürgen

Reply to this message...
 
    
Mike Harsh[MSFT] (VIP)
This looks like a bug in the GetCOnverter method. Please use the MSDN product feedback center to report this bug. Using the MSDN
feedback center will allow you to track this bug through its lifespan and will also allow others to vote for it.

http://lab.msdn.microsoft.com/ProductIT Certification

Thanks
- mike
--------------------
[Original message clipped]

__

This posting is provided "AS IS" with no warranties and confers no rights.

Reply to this message...
 
    
Jürgen Weiss
Thanks a lot for the prompt feedback.
I've submitted the bug report (in case someone is interested: the bug id is FDBK14969)

"Mike Harsh[MSFT]" <Click here to reveal e-mail address> schrieb im Newsbeitrag news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
 
    
Jürgen Weiss
Today I found a workaround for this problem: registering a handler for the AssemblyResolve event
seems to help. See the excerpt from the problem report:
Workaround Description:
The problem seems to go away if one registers a handler for the AssemblyResolve event of the current AppDomain. The handler simply
searches the loaded assemblies of the calling domain.

Two questions remain:
- Why is the behavior depending on whether the control runs in IE
- Why is AssemblyResolve invoked for an assembly which has already been resolved (loaded)

Workaround Steps:
Add following code to ActiveXCtrl class:

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
AppDomain domain = (AppDomain)sender;

foreach (Assembly asm in domain.GetAssemblies())
{
if (asm.FullName == args.Name)
return asm;
}

return null;
}

public ActiveXCtrl()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

TypeRes.TestControl control = new TypeRes.TestControl();
Type propertyType = control.myProperty.GetType();

// use TypeDescriptor class to get hold of the converter
object converter1 = TypeDescriptor.GetConverter(propertyType);

"Jürgen Weiss" <Click here to reveal e-mail address> schrieb im Newsbeitrag news:cheqrv$o71$Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
 
 
System.AppDomain
System.ComponentModel.TypeConverter
System.ComponentModel.TypeConverterAttribute
System.ComponentModel.TypeDescriptor
System.Reflection.ConstructorInfo
System.ResolveEventArgs
System.ResolveEventHandler
System.Type
System.Windows.Forms.Label
System.Windows.Forms.MessageBox
System.Windows.Forms.UserControl




ExamGuru IT Solutions - .Net Guru is owned and operated by ExamGuru, Inc., the man behind .Net Guru. If you're in the market for bespoke software or software consultancy, why not get him and his highly trained team to help? - www.examguru.net/ITCertification
Ad


Need Dot Net Interview Questions?
Ask ExamGuru, Inc. for advice and help on Passing .Net Interviews
.Net Projects
Best-of-breed application framework for .NET projects, developed by ExamGuru, Inc. and ExamGuru IT
Free .net Help
Commission ExamGuru, Inc. and his team for your next bespoke software project
FogBUGZ
The only bug tracking system carefully crafted with one goal in mind: helping teams create great software.
Awesome Tools
If you don't know about these, you're missing out... IT Certification Questions
IT Interview Questions
Free Oracle 10g Training
MCSE Boortcamp
Cisco Study Guides
Cheap Study Guides
Exact Questions
Dot Net Interview Questions
Oracle OCP
Cheap Travel
Designer Perfumes - Wholesale Prices
Free Programming Tutorials
 
ExamGuru IT Solutions - .Net Guru is owned and operated by ExamGuru, Inc., the man behind .Net Guru. If you're in the market for bespoke software or software consultancy, why not get him and his highly trained team to help? - www.examguru.net/ITCertification
 Copyright © ExamGuru, Inc. 2001-2006
Contact Us - Terms of Use - Privacy Policy - www.dot-net-guru.com - www.examguru.net - www.oraclesource.net - www.itinterviews.net - www.examguru.net/ITCertification