Clash between custom delegate and Func when importing?

Jul 31, 2009 at 11:16 AM

I've been playing around with importing/exporting custom delegates and found a problem. I define a custom delegate and have a class that exports both the custom delegate and an equivalent Func:

public delegate int CustomDelegate(double a);

public class DelegateExporter
{
	[Export(typeof(Func<double, int>))]
	public Func<double, int> MyFunc = a => 1;

	[Export(typeof(CustomDelegate))]
	public CustomDelegate MyCustomDelegate = a => 2;
}

Now an [Import(typeof(CustomDelegate))] fails with an error:

More than one exports were found that match the constraint '((exportDefinition.ContractName = "System.Int32(System.Double)") && (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") && "System.Int32(System.Double)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))'.

Clearly I can add different contract names to my exports to distinguish them. Other than that, is there any other way to distinguish the two exports, or is this just a limitation of MEF?

In fact, I've just just tried modifying the above sample to have 

public delegate int CustomDelegate1(double a);

and

public
delegate int CustomDelegate2(double a);

This also fails. This seems like a serious limitation to using delegates within MEF, or am I missing something?

Thanks

Akash

Jul 31, 2009 at 5:00 PM

Hi,

The best option in this case is to use named contracts.

        [Export("abc")]
        public Func<double, int> MyFunc = a => 1;
 
        [Export("def")]
        public CustomDelegate MyCustomDelegate = a => 2;

Delegates are treated specially by MEF so that method exports can be used without annotating them with delegate types.

E.g. we treat:

                [Export]

                public int MyFunction(int a);

and:

                [Export(typeof(Func<int, int>))]

                public int MyFunction(int a);

..as the same thing.

Cheers,

Nick

From: akashchopra [mailto:notifications@codeplex.com]
Sent: Friday, July 31, 2009 3:19 AM
To: Nicholas Blumhardt
Subject: Clash between custom delegate and Func when importing? [MEF:64096]

From: akashchopra

I've been playing around with importing/exporting custom delegates and found a problem. I define a custom delegate and have a class that exports both the custom delegate and an equivalent Func:

public delegate int CustomDelegate(double a);
 
public class DelegateExporter
{
        [Export(typeof(Func<double, int>))]
        public Func<double, int> MyFunc = a => 1;
 
        [Export(typeof(CustomDelegate))]
        public CustomDelegate MyCustomDelegate = a => 2;
}

Now an [Import(typeof(CustomDelegate))] fails with an error:

More than one exports were found that match the constraint '((exportDefinition.ContractName = "System.Int32(System.Double)") && (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") && "System.Int32(System.Double)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))'.

Clearly I can add different contract names to my exports to distinguish them. Other than that, is there any other way to distinguish the two exports, or is this just a limitation of MEF?

In fact, I've just just tried modifying the above sample to have

public delegate int CustomDelegate1(double a);

and

public
delegate int CustomDelegate2(double a);

This also fails. This seems like a serious limitation to using delegates within MEF, or am I missing something?

Thanks

Akash

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Developer
Jul 31, 2009 at 5:40 PM

Just to followup with what Nick said. The reason these delegates are treated the same is because of the way we generate contract names for methods/delegates. We generate the contract name purely based on the signature of the method/delegate, the type doesn't come into play. One reason for this is because if you simply put an Export attribute on a method (without specifying a contract name/type), there isn't any way to really generate a contract name from a type because the method itself matches lots of different delegate types. We considered generating a contract name from Func<...> in these cases, which is what we once did, but that ended up being very limiting and blocked us from supporting custom delegates.

So if you want your method export do be distiguished from other such delegates of matching signatures then you will need to specify a string name like Nick suggested.

HTH,
Wes

Jul 31, 2009 at 8:21 PM

Nick, Wes,

Thanks for the explanations - it all makes sense now. I think I'll stick with to using Func instead of custom delegates but just make the contract name the same as the custom delegate I would have declared.

Akash