Sharing dynamic Objects Between Assemblies in C#
I had a method in one assembly within my project namespace
that accepted a dynamic
as a parameter in the method. Something like this:
using System;
namespace MyAssembly.Data {
public class MyDataClass {
public IResult Parse(dynamic input) {
// do stuff…
var data = (int)input.data;
return new ClassThatImplementsIResult(data);
}
}
}
I then attempted to test this method, by passing in a dynamic
created by the test:
using System;
using MyAssembly.Data;
namespace MyAssembly.Tests {
[TestClass()]
public class MyDataClassTest {
[TestMethod()]
public void Parse_Should_Parse() {
var instance = new MyDataClass();
var result = instance.Parse(new { data: 1 });
Assert.Equals(result.ID, 1);
}
}
}
But when I ran the test I got this exception:
‘object’ does not contain a definition for ‘data’
This is because of the way dynamics are generated under the hood. They cannot be shared between assemblies because they obey the normal rules of access control, and the types generated by the compiler for the dynamics are marked as internal
. To get this to work, I had to add the following line to the AssemblyInfo.cs
file of my Test assembly (basically think of what other assemblies you want the current assembly to share internals with):
[assembly: InternalsVisibleTo("MyAssembly.Data")]
And after that everything worked peachy! For other gotchas related to dynamic
objects in C#, check out Gotchas in dynamic typing from C# In Depth.