Use an interface from an external assembly that

2019-06-09 00:33发布

问题:

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.

回答1:

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



回答2:

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



回答3:

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


回答4:

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).