views:

687

answers:

4

I'd like to implement an interface that resides in an external assembly. However that particular interface has been marked as "internal". Is there a way I can still implement this interface for my own classes?

I know how to call private/internal methods using reflection in C#, so I guess reflection should be used in this case too. However, I don't know how. And yes, I do know it usually isn't wise to use internal/private stuff, but in this case I see no other solution.

Update: I'm not able to edit / change the external assembly in any way. It should be left untouched.

+3  A: 

You can't do that, unless you can change the assembly containing the interface to add an InternalsVisibleToAttribute, targeting your own assembly.

Jb Evain
I don't want to edit / change the external assembly in any way. I've updated the question.
LeonZandman
So you're pretty much toasted :)
Jb Evain
Some tricky solutions would involve patching the original assembly with Cecil for instance, and if the assembly is signed, deactivate its strong name check, but that's not a path I would recommend :)
Jb Evain
I don't want to go that way either. Weird though, that one can call private / internal methods without any problem, but cannot implement those internal interfaces.
LeonZandman
+2  A: 

Use the InternalsVisibleToAttribute in the external assembly to point to the assembly that you want to expose internal types to.

http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

Dustin Campbell
A: 

I you have the source of the external assembly then you can compile it with an InternalsVisibleTo attribute pointing at your assembly. This is not a perfect solution and I often use it for unit testing rather than production code but it may be something worth looking at.

Basically all you would need to do is add the following to the AssemblyInfo.cs code-file in your project:

[assembly: InternalsVisibleTo("YourAssembly")]

If YourAssembly is strongly-named then you have to put the fully qualified name of the assembly including the entire public key (not just the token).

Andrew Hare
+1  A: 

Just to get some background, presumably you want to pass the interface implementation to something else in this assembly, which is also internal, because otherwise they wouldn't have been able to compile this other assembly (it being an error to refer to an internal type in a public method's parameters).

I think you'll have to use Reflection.Emit to build a type that implements the interface, having obtained the interface's Type object by reflection. Not exactly a straightforward task, and the result will be fragile because you're digging around in the internals of someone else's assembly.

Other options:

  • Disassemble the other assembly, using Reflector and that cool addin that builds a whole project from the assembly.
  • Talk to the owner of the other assembly and explain your needs to them
Daniel Earwicker
Yeah, I was already looking into Reflection.Emit. Interesting stuff :-)
LeonZandman
You can't use reflection.emit to implement a private interface, you'll get a TypeLoadException.
Jb Evain
D'oh. This is undoubtedly a good thing though.
Daniel Earwicker