views:

83

answers:

2

Given an assembly that contains

namespace Foo{public class Bar;}

How could I create an Action<Foo.Bar> from another assembly without referencing the first assembly at compile time?

+2  A: 

You can't call it Action<Foo.Bar> in your calling code, since you won't have access to that type definition if you don't reference it at compile time. Since Delegates are contravariant, you can return an Action<Object> and use that, or use Action<IBar> where the IBar interface is defined in a referenced assembly, and implemented by Foo.Bar.

If you do return an Action<Object>, you'd either have to use Foo.Bar members via reflection (or dynamic if using C# 4.0) or use cast it to Foo.Bar where the casting code has a reference to the assembly where Foo.Bar is defined.

codekaizen
"You can't call it Action<Foo.Bar> in your calling code" - yeah I realize that. Re: contravariance - Sorry I didn't specify .NET 3.5. I'll fix the tags.
dss539
+4  A: 

If you use

Type barType = Type.GetType("Foo.Bar, whateverassembly");
Type actionType = typeof(Action<>).MakeGenericType(barType);

actionType will now represent Action<Foo.Bar>. However, to use it, you'll need to contintue to use reflection, so you'll need to find a MethodInfo that fits the signature void(Foo.Bar), and call Delegate.CreateDelegate to create a delegate. And you'll need Delegate.DynamicInvoke to execute it.

Delegate call = Delegate.CreateDelegate(actionType, ...);
...
call.DynamicInvoke(someBar);

Something tells me that's not what you're thinking of...

Ruben
What would I put in the `...` in `Delegate.CreateDelegate(actionType, ...);`? I think your solution is what I require, because I will be passing this delegate to a constructor in the source assembly anyways.
dss539
Thanks, I resolved my issues. Your help is much appreciated.
dss539