A couple of days ago, I saw the CoClassAttribute being used in a way I haven't imagined before.
[ComImport, CoClass(typeof(Foo)), Guid("787C1303-AE31-47a2-8E89-07C7257B1C43")]
interface IFoo {
void Bar();
}
class Foo : IFoo {
public void Bar() {
Console.WriteLine("Oh retado!");
}
}
being used as:
class CoClassDemo {
public static void Show() {
var a = new IFoo();
a.Bar();
}
}
That should have not surprised me since COM Interop does exactly that since the early days of the .NET Framework. I simply haven’t paid that much attention when digging through COM Interop code in .NET Reflector.
method public hidebysig static void Show() cil managed
{
.maxstack 1
.locals init (
[0] class ConsoleApplication1.IFoo a)
L_0000: nop
L_0001: newobj instance void ConsoleApplication1.Foo::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: callvirt instance void ConsoleApplication1.IFoo::Bar()
L_000d: nop
L_000e: ret
}
What happened is that out of the context of COM Interop, I immediately I envisioned this being used as a poor man’s compile time dependency injection.
All there is to do is get rid of the conventional "I" prefix on the interface's name (as does COM Interop).
Then it would be a matter of changing the CoClass attribute to swap an implementation for another, mocking, etc.
Two drawbacks I see upfront are having to recompile (which pretty much limits testing scenarios to development time) and eventual problems surrounding circular dependencies when interfaces and implementations are deployed to different assemblies.
Has anybody played with this technique? Any other drawbacks? Other uses?