Click to See Complete Forum and Search --> : [RESOLVED] Interesting Interface Error or Not Error At All


ekaluc
April 2nd, 2008, 07:31 PM
Hello friends,

I am experiencing a problem. A kind of problem I never saw or heard. I need to explain what is happening in detail. Source code also provided.

This problem appears to happen only in debugging and after rebuilding the project. When Visual Studio is closed and reopened, there seems to be no problem until the next rebuild of the project. Let me explain.

In short problem is:
In debug, rebuild the debugged code and break any code inside ComponentLinkTypeEditor class (coded below). After that in Watch window if you type "(IComponentLink)" and press enter then VS says:

The type 'ComponentLink.IComponentLink' exists in both '{20DADBC7-399F-4BC8-8FD8-9BC8936FB68F}' and '{20C1CE10-0B62-4A87-9670-1E8BA5D15186}'

why this can be happen?

For detailed explanation please follow:

I have an interface like this:


public interface IComponentLink
{
Component GetComponent();
}


This interface used to construct a link between an extender control (code shown below) and any component which implements IComponentLink. The extender control exists in a seperate project. One of the properties of my extender control has the type of IComponentLink interface.


namespace TextBoxHelper
{
[Serializable()]
[ProvideProperty("HelpTexts", typeof(string))]
public class TextBoxHelpProvider : ToolTip, IExtenderProvider
{

private IComponentLink _componentLink = null;
[Browsable(true)]
[EditorAttribute(typeof(FormLinkTypeEditor), typeof(UITypeEditor))]
public IComponentLink ComponentLink
{
get
{
return _componentLink;
}
set
{
this._componentLink = value;
}
}

public TextBoxHelpProvider()
{
}

public TextBoxHelpProvider(IComponentLink formLink)
: this()
{
this._componentLink = formLink;
}

#region IExtenderProvider Members

bool IExtenderProvider.CanExtend(object extendee)
{
if (extendee.GetType() == typeof(TextBox))
{
return true;
}
else
{
return false;
}
}

void tb_TextChanged(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
if (String.IsNullOrEmpty(tb.Text))
{
}
else
{
}
}
}
}


I needed a design time functionality to set the ComponentLink property of my extender control. Implementation of a custom Type Editor needed for this case. This custom type editor required to provide a Listbox in the property grid and when its drop down button pressed it supposed to list all the components on the design environment which implements IComponentLink.

To provide the required functionality my custom type editor coded as shown below:


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using ComponentLink;
using System.ComponentModel;

namespace TextBoxHelper
{
public class ComponentLinkTypeEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}

public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService editorService = null;

if (provider != null)
{
editorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
}

if (editorService != null)
{
ComponentLinkEditorControl selectionControl = new ComponentLinkEditorControl(value, editorService);


//The Code Required to List All Components which implements
//IComponentLink

if (context != null && context.Instance != null)
{
IComponentLink componentLink = null;

foreach (Component component in context.Container.Components)
{
if (component != null)
{
componentLink = component as IComponentLink;

if (componentLink == null)
{
continue;
}
else
{
selectionControl.InnerItemList.Items.Add(componentLink);
}
}
}
}


editorService.DropDownControl(selectionControl);
value = selectionControl.SelectedComponentLink;
}
return value;
}
}
}


Everything worked perfect but...
After I rebuilt my project, the components which implement IComponentLink interface stop being listed. The higlighted and italic code line above shows the code which is responsible for that error.

When debugging put this line to Watch window and you get:
The type 'ComponentLink.IComponentLink' exists in both '{20DADBC7-399F-4BC8-8FD8-9BC8936FB68F}' and '{20C1CE10-0B62-4A87-9670-1E8BA5D15186}'

I could not able to understand and solve this problem. Any help will be appreciated. Thank you.

Mutant_Fruit
April 2nd, 2008, 08:08 PM
Looks like you're ending up with two versions of the same library being in use at the same time. Does that sound possible?

ekaluc
April 2nd, 2008, 08:38 PM
Hi Mutant Fruit,

As you say, somehow, IComponentLink interface acted as it has got two different implementations. When I try this:


component.GetType().GetInterface("IComponentLink")


at Watch Window it seems it is ok. The above code returns the type of the interface. However, casting to IComponentLink is not possible. The thing I really wonder is, why everything works at the start (closing and opening Visual Studio and loading project back) and broken just after rebuilding the project again.

Thank you.

Mutant_Fruit
April 2nd, 2008, 08:51 PM
One part of your project is referencing an old build of your library, another part is referencing a new build. I have no idea what's causing it, but that's the issue.

The types will match up, but the assembly versions are different. This is what prevents you from casting. You need to ensure that you are using the one build of the library in all affected software.

ekaluc
April 2nd, 2008, 09:41 PM
Hey Mutant,

I figured it out!

Explanation (I am not good at this). If I do not misrecall, after each rebuild Visual Studio assign a different version number for assemblies in increasing fashion. If what I recall is true, then when the solution initially loaded into the Visual Studio, Visul Studio use already built assembly. But if we rebuild the project, then the version number of the assembly changes so the old version and new version collapses. I just disabled option for rebuilding the IComponentLink project (I moved it to a seperate project just to avoid rebuilding it again). Now everything seems to be fine. But I still wish to find a way to programatically solving this one.

Thank you very much Mutant. You helped me to focus and recall a simple but important thing. Take care.