Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Visual Studio.NET / IDE / May 2006

Tip: Looking for answers? Try searching our database.

IDesignerHost.GetType()

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Mark Olbert - 20 Apr 2006 15:59 GMT
I originally posted this over in the base Framework forum, but the MS folks there said that IDesignerHost is implemented by Visual
Studio, so I thought I'd post the questions here to see if anyone can answer them.

Here's an example of a solution that demonstrates, conceptually, some questions/issues with IDesignerHost.GetType():

ProjectA (assembly name AssemblyA):
    ComponentA

ProjectB (assembly name AssemblyB):
    references ProjectA
    ComponentB
        CustomDesignerB (for ComponentB)

Within CustomDesignerB, you would expect to have to call IDesignerHost.GetType("ProjectA.ComponentA, AssemblyA") in order to create
a Type representing ProjectA.ComponentA.

Calling IDesignerHost.GetType("ProjectA.ComponentA") works just as well. In fact, from a little bit of testing it appears that you
never have to specify the assembly in the IDesignerHost.GetType() call, provided the Type you're creating is defined in an assembly
referenced in ProjectB.

That's sort of understandable: whatever routine searches for the metadata used to create a Type probably starts by looking in the
current project (ProjectB, in my example) and the assemblies it references.

But what's really weird is that IDesignerHost.GetType("ProjectA.ComponentA, AssemblyB") works just as well. Apparently, if the
metadata search can find the information it needs from the Type name, minus the assembly add-on, it ignores the assembly add-on.

I discovered this by accident; I meant to do the call as IDesignerHost.GetType("ProjectA.ComponentA, AssemblyA"), but goofed up.

At this point my main interest is in understanding how IDesignerHost.GetType() does its work, since it looks like what I need, but
the documentation on it is pretty sparse. I like that it can create Types at design-time which are defined in the source code of the
project I'm building (I need that capability in some of my custom designers and UITypeEditors). But I'd like to know more details,
so I can see if it may cause some problems for me down the road.

Do you have access to any information on the "guts" of how IDesignerHost.GetType() works, and how it differs from Type.GetType()?
They do behave differently!

In my example, calling Type.GetType("ProjectA.ComponentA, AssemblyA") or Type.GetType("ProjectA.ComponentA") within CustomDesignerB
returns a null...unless you first call IDesignerHost.GetType(), after which Type.GetType() works just fine. I presume that means
IDesignerHost.GetType() is loading metadata from the current project someplace where Type.GetType() can access it, but that
Type.GetType() isn't smart enough to do that load itself.

- Mark
Steven Cheng[MSFT] - 21 Apr 2006 07:40 GMT
Hi Mark,

Thank you for posting.

Glat that you've made further progress on this. As for the IDesignerHost
interface, the concrete implemention for VS IDE is the
System.ComponentModel.Design.DesignerHost class, and the GetType method of
this class internally query another design-time interface,
"ITypeResolutionService" and call this interface's GetType method.  And for
VS IDE, the detailed implemenation on this interface is a pure VS IDE
specific one , named "VsItemTypeResolutionService", which is in the
Microsoft.VisualStudio.Web.dll assembly. Based on my inspecting on the type
(if you have interesting, we can check the code logic through the reflector
tool)'s GetType method, it is AssemblyName sensitive, so if we passed a
wrong assemblyName in the Type Name, it will return Null. I've tested this
in my local projects. Actually the detailed code logic of the type
searching is like below:

1. check the type name to see whether it is assemblyname qualified:

2. If assembly named qualified, first check the cachedTypes through the
full typename, if not exists, type load the type from the specific
assemby....

3. If not assembly name qualified, also check Type CAche first, then, check
all the available assemblies one by one ....

So I'm also feeling a bit strange that it return the type instance
regardless of the wrong assembly name.  Anyway, such detailed codelogic is
always encapsulated and hidden from the users(through abstract interface).

Hope this helps.

Regards,

Steven Cheng
Microsoft Online Community Support

==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================

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

Signature

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Mark Olbert - 24 Apr 2006 04:00 GMT
Steven,

(This still refers to my earlier extended example).

I am pulling my hair on getting this design time Type/run time Type stuff to work properly! IDesignerHost.GetType() won't work if I
pass it an assembly-qualified name. It only works if I pass it a Type name without any assembly name...and it won't work all the
time then, either.  But at runtime, Type.GetType() won't work without the assembly-qualified name!

Can you please explain to me what's going on? What are the specific rules for declaring a Type name so that it can be created at
design time via IDesignerHost.GetType() and at run time via Type.GetType()?

- Mark
Steven Cheng[MSFT] - 24 Apr 2006 12:01 GMT
Thank you for the response Mark,

The IDesignerHost.GetType method can accept  assemblyQualifiedname for the
typeName. There must be something else cause it fail to get the t ype. Are
you using the code(or the editor) it in ASP.NET project or  winform
project? For winform project, the project will have a default namespace and
assembly Name setting for the main assembly compiled for the project, so we
can use it as the assembly name passed to the GetType method's typename
parameter. For type in class library, I think we can always correctly get
the type instance through IDesignerHost.GetType with AssemblyQualifiedname,
yes?  

For ASP.NET project(2.0), it is a bit different, since there is no
precompiled assembly, and no fixed assembly name setting in project.
However, the ASP.NET provide two keyword to let us use to represent the
ASP.NET dynamic compiled assembly (for types in the application, e.g in
App_Code folder).  The two keywords are "App_Code" and "__code".  So for a
certain custom type in App_Code folder. e.g  a class named TestObjectClass,
we can use the following AssemblyQualifiedName to reference it:

"TestObjectClass, __code"

or "TestObjectClass, App_Code"

and if we do not provide assembly name, the IDE will search all the
available referenced assemblies for that type(also include the current
project itself.

Regards,

Steven Cheng
Microsoft Online Community Support

==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================

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

Signature

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Steven Cheng[MSFT] - 27 Apr 2006 13:10 GMT
Hi Mark,

How are you doing on this? Does the further info in my last reply helps
some? If still anything we can help, please feel free to post here.

Regards,

Steven Cheng
Microsoft Online Community Support

==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================

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

Signature

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Mark Olbert - 27 Apr 2006 17:06 GMT
Steven,

It was helpful, thanks. However, I'm still wrestling with an oddity (which I think won't be a problem when I release the product I'm
working on, and has a workaround during development).

I have a solution which contains a number of wizard libraries (i.e., one for each custom wizard), which are then loaded at startup
by an application. Each of the wizard libraries relies on a base wizard library. When I debug the base wizard library using a
separate instance of VS2005 (which is working on the solution with the multiple wizard libraries) I get some odd effects with
IDesignHost.GetType(). Here's a text diagram of the situation:

First instance of VS2005:
    Solution: BaseWizardLibrary
        Project: BaseWizardProject
            defines a BaseWizard class
    debug this library using the "multilibrary" solution

Second instance of VS2005
    Solution: MultiWizardApplication
        Project1:
            references BaseWizardLibrary
            defines CustomWizard1, derived from BaseWizard
        Project2:
            references BaseWizardLibrary
            defines CustomWizard2, derived from BaseWizard
        ...
        ProjectApp:
            references Project1, Project2, etc.

If I make a change to the BaseWizardLibrary, launch a second instance of VS2005 on the MultiWizardApplication, and call
IDesignerHost.GetType() from within the designer of one of the custom wizards, I get back a Type, but it is not considered to be
derived from BaseWizard (even though it is).

I thought this was odd, so I added the following to the designer code (the designer is defined in the BaseWizard assembly):
    Type junk = typeof(BaseWizard);

When the debugger hits this line there's an error thrown (resulting in a null value being returned). The message says something
about BaseWizard being defined in two different assemblies (two different GUID-like values are contained in the error message).

The workaround I've found is this: whenever I make a change to the BaseWizard solution, always do a full compile of the
MultiWizardApplication before opening one of the designers on a wizard in the MultiWizardApplication. Apparently, VS2005 only
updates the reference to the BaseWizardLibrary in the active project of the MultiWizardApplication solution when VS2005 starts up.
You have to do a full compile to get the other references updated (and if you don't do that, you have stale versions of the
BaseWizardLibrary lying around the solution, causing the problem).

Are you familiar with this behavior?

- Mark
Steven Cheng[MSFT] - 01 May 2006 12:14 GMT
Thanks for the followup Mark.

Glad to be of assistance. As for the further problem you mentioned, I'd
like to think it as the cache of the IDE since for those types which are
under designing, it could be changed, and when the designer get loaded,
only a certain version of the type/assembly is loaded. So if we make
further changes, the designerview may not get refreshed immediately.  In
addition to the doing full compilation on all the projects in solution, you
can also try close the designer and reopen it after any referenced
dependent projects assemblies get updated and recompiled. Anyway, this does
coupled with the internal code logic, I also haven't thorough view over the
exact implementation.

Regards,

Steven Cheng
Microsoft Online Community Support

==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================

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

Signature

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.