Interface inheritance and property Binding DialogBox: Bug?
Hi all,
here is my class hierarchy:
I've got the class WorkerObject that implements the interface IWorker
the interface IWorker inherits from the interface IPerson
My workflow have a property IWorker
But when I try to bind an activity property to a field of my IWorker property, I can't see the fields of the IPerson interface.
I've read that WF is strongly typed but I don't think it's a normal behavior.
What do you think of this?
Antoine
[467 byte] By [
AntoineF] at [2007-12-25]
Antoine,
I just tested this locally by creating two interfaces: IWorker inheriting from IPerson, each one with a string property. Then I declared a variable of type IWorker in my workflow and initialized it to an instance of a class implementing the interfaces and then opened up the designer.
I was able to bind a string property of an activity to either of the properties in my IWorker field. That is, I was able to see both the properties defined by IWorker as well as those defined by IPerson; so it would appear it is working correctly, at least on the .NET FX RC1 version I'm using now (which I think maps to the RC5 WF extensions?).
Do make sure you're trying to bind to the correct variable type. Remember that the binding dialog might filter out some members if they don't match the of the property being bound.
Hi,
thx for testing. I had a doubt so I made a little application that show the bug. I sent it to you by mail.
Can you give me your opinion please?
Thx
For those who are interrested in, here are the app and a screenshot:
http://willem77.free.fr/interface_inheritance_bug.JPG
http://willem77.free.fr/interface_inheritance_bug.zip
i just tried to bind the message property of the activty1 to the Name property of the iworker property of the workflow
Antoine,
Never mind my previous response. I just checked with the sample code you emailed me and indeed this is a problem.
Here's the issue: If you want to bind to a member of an object that is a property of your workflow that is declared using an Interface type (and not an concrete type), the activity binding dialog will only show you those members explicitly declared by that interface type and won't show any members declared by any interface types it inherits from.
The same does *not* happen by the way for abstract classes.
So yes, I would agree with Antoine this is a bug.
Antoine: You can report the bug on the MS Connect site for WF:
https://connect.microsoft.com/wf
Once you reported it, let us know; I'll gladly vote and validate it.
ok i sent it.
I didn't receive a confirmation mail so I don't know if it has worked...
If I have no news i will retry a report tomorow.
here is the title of the bug i reported:
"Interface inheritance and property binding dialogbox"
Thx for your help Tomas
Both properties are being display for the Worker class because you have made them public properties.Interfaces don’t implement properties, methods, events or indexers they only define them, see the C# spec here for more info.What I get from that is that you will only ever see the members defined in an interface when you get them, like with Type.GetProperties().As an example if you choose to explicitly implement the IWorker interface you will have the following.Notice that Nom is a member of the IPerson interface and not IWorker as you would expect if interface inheritance was the same as with a class.
public class Worker : IWorker
{
#region IWorker Members
string IWorker.Company
{
get
{
throw new Exception("The method or operation is not implemented.");
}
set
{
throw new Exception("The method or operation is not implemented.");
}
}
#endregion
#region IPerson Members
string IPerson.Nom
{
get
{
throw new Exception("The method or operation is not implemented.");
}
set
{
throw new Exception("The method or operation is not implemented.");
}
}
#endregion
}
If you don’t explicitly implement the interface, like you have the following are Worker class implementation are the same:
namespace InheritedInterface
{
public interface IPerson
{
string Nom{get; set;}
}
public interface IWorker : IPerson
{
string Company { get; set;}
}
public class Worker : IWorker
{
string company = string.Empty;
public string Company
{
get { return this.company; }
set { this.company = value; }
}
string nom = string.Empty;
public string Nom
{
get { return this.nom; }
set { this.nom = value; }
}
}
}
namespace SeparateInterfaces
{
public interface IPerson
{
string Nom { get; set;}
}
public interface IWorker
{
string Company { get; set;}
}
public class Worker : IWorker, IPerson
{
string company = string.Empty;
public string Company
{
get { return this.company; }
set { this.company = value; }
}
string nom = string.Empty;
public string Nom
{
get { return this.nom; }
set { this.nom = value; }
}
}
}
Tom,
While what you say is technically correct, I believe it leads to confusing behavior for the developer. Yes, it's true that IWorker won't implement the Nom property in IPerson, *but*, since IWorker "inherits" IPerson, then you do have the guarantee that whatever implemented IWorker will also have implemented IPerson, and thus the expectation from the user's perspective will be to see the properties defined by both.
Just something to keep in mind.
This is a general issue with .NET / reflection then and not the bind dialog.Try the following:
PropertyInfo[] properties = typeof(IWorker).GetProperties();
foreach (PropertyInfo property in properties)
{
Console.WriteLine(string.Format("IWorker property - {0}", property.Name));
}
Tom,
I'm very well aware that's how reflection works; I got you the first time :). But I certainly agree the binding dialog could go a bit further and walk the interface inheritance chain (which is trivial) to present this data in order to make binding more flexible. I just say it because the UI is supposed to make our lifes easier, not limit us further :)
Hi Tom,
I agree with you that it is a .Net general issue, but in this case, it really limits us.
I can't even bind manually the property of the parent interface...
Can you tell us if you plan to change this behavior for the final release of WF?
Thank you
Antoine
Thomas and Tom,
I'm working with Antoine on this issue.
This issue is really a showstopper for us because all our business objects are exposed as interfaces rather than classes. Behind these interfaces, we have either real implementation classes or proxies depending on the deployment scenario (2 tier or 3 tier). Because of this architecture choice, we have to bind on interfaces rather than classes and this bug prevents us from using our BOs seamlessly in workflows.
We are aware of the introspection issue with interfaces (not specific to properties in fact, methods are handled the same way), but this is not a valid excuse for not displaying the correct property list in the binding dialog. When you use this dialog, you want to get the complete list of properties, regardless of whether the type is a class or an interface. So, this is a bug .
Antoine has posted the issue in the connect bug tracking system. The comment id is #225822. So, if you want to vote for it, it will help us
.
Bruno.