.NET Announcements C# CodeCop

Know this: CodeCop v3.1 let’s you create types at runtime without dynamic compilation

One of the most difficult challenges for anyone that strives to create a breakthrough product or service is keeping up with its steady pace towards innovation. That is certainly one of my main concerns every time I add new bits to CodeCop or to any other software I build.

I’ve been experimenting a lot with dynamic compilation even before CodeCop was born. It’s predecessor a framework I built called ShapeFX (now extinct but with a light version on GitHub ) was all based around experimenting stuff with Roslyn , the Mono C# compiler and CodeDom.

This post is certainly not about the aforementioned technologies but to tell you that one of the things that bugged me the most when using them, was the fact we had to feed the compilers with “stringified” versions of classes.

If you wanted a fluent, more code based way to do things, or you had to write a wrapper yourself and prepare to live on the string parsing hell for quite some time, or you had to go down to the metal and work directly with Reflection Emit, which if you’re not proficient at CIL it’s even an hotter hell than the previous one.

Also Mono and Reflection Emit were the only two choices you had to avoid having dynamic assemblies lying around all over your appdomain every time you compiled something, as they allowed the use of Collectible Assemblies (at the time the Roslyn team had removed the Scripting API from public which used that same approach but now it’s back again as pre-release).

Anyways and without further due if you can dive directly into the source of all things why not drink directly from it without having to go through all these technologies that at the end of the day are just different river channels flowing into that same sea?

The CLR Metadata (Unmanaged) API

Well it exists for ages but not everyone knows that. The CLR Metadata (Unmanaged) API is what feeds the CLR with information used to describe runtime types and internal implementation and layout information used to JIT-compile IL, load classes, execute code and interoperability. In other words, this is the metadata Holy Grail used by compilers, profilers and other RAD tools out there.

It has a caveat though, it’s unmanaged, ouch!

CodeCop v3.1 to the rescue

Ok so I went in and created a managed wrapper for this. So what, it’s a public API for God’s sake, you might ask? Nothing new there and anyone can do that, for sure. Where’s that innovation factor I spoke about?

Well that innovation factor is that with the help of the CodeCop interception technology I made it work at runtime with your current application modules, just like profilers internally do but without all that profiling overhead.

In essence these new CodeCop bits allow you to create a new type at runtime and specify things like inheritance, interfaces, constructor, fields, properties, methods and attributes, in a managed and fluent way, almost resembling F#’s object expressions.

Cut the chase, show me the goods!

Check out this example that shows how to create a new Serializable and Disposable type that has an int field a property and a void method as members.

    public class SomeParentClass
    {
        public void SomeParentMethod()
        {
            Console.WriteLine("SomeParentMethod Logic...");
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            // Tell CodeCop to use the Fluent API 
            Cop.AsFluent();

            // Create a new type
            var newType = Cop
                            .Let("NewType")
                            .With()
                            .Parent<SomeParentClass>()
                            .Attribute<SerializableAttribute>()
                            .Implementing<IDisposable>("Dispose",
                             new Action(() =>
                             {
                                 Console.WriteLine("Dispose Logic...");
                             }))
                            .Constructor(
                             new Action(() =>
                             {
                                 Console.WriteLine("Constructor logic...");
                             }))
                            .Field<int>("SomeField")
                            .Property("SomeProperty",
                             new Func<int>(() =>
                             {
                                 Console.WriteLine("Getter logic...");
                                 return 1;
                             }),
                             new Action<int>((x) =>
                             {
                                 Console.WriteLine("Setter logic...");
                             }))
                            .Method("SomeMethod",
                             new Action(() =>
                             {
                                 Console.WriteLine("SomeMethod logic...");
                             }))
                            .Create();

            // Print the type to the console to see that resides on mscorlib
            Console.WriteLine("Type Name: {0} Assembly: {1}", newType.FullName, newType.Assembly.FullName);
           
            // Check to see if it is Serializable
            Console.WriteLine("{0} is Serializable? {1}", newType.Name, newType.IsSerializable);
            
            // Instantiate it
            dynamic instance = Activator.CreateInstance(newType);

            // Cast it to parent class
            SomeParentClass parent = instance;

            // Call a method on parent class
            parent.SomeParentMethod();

            // Call its members
            instance.SomeField = 10;

            instance.SomeProperty = 1;
            var propValue = instance.SomeProperty;

            instance.SomeMethod();

            // Dispose it via its IDisposable implementation
            (instance as IDisposable).Dispose();
        }
    }

Freakin’ awesome, right? Now here’s the output result:
screen3

Where do these types go?

As I said there is no dynamic compilation involved in this process so there are no dynamic assemblies hosting these types. Instead and for this first pilot they are magically attached right into the mscorlib assembly by the CodeCop runtime, but it’s my plan in a near future to let you attach it to any assembly you like.

How is this possible? Well that’s part of our secret sauce, so you have to trust us on this one. 🙂

Limitations?

For now, you can’t specify member or type visibility (all is public), you can’t also declare generic member fields, you have to use the object type and perform a cast. Parent types must be public, and last if you are returning or using types that reside outside the mscorlib assembly, the containing assembly must be signed.

It’s a simple price to pay for such an amazing power don’t you agree?

Are there any licensing restrictions?

The same rules for method interception apply. Free version lets you declare 25 methods total (sum of all methods of the types you create), Developer 150 and Ultimate unlimited.

Just before wishing you a Merry Christmas

This year has been crazy for me, I was a parent again, all the work and social fuss around CodeCop and now it’s culminating with my permanent move to the United States in the beginning of 2016.

So as this will probably be the last CodeCop release I’ll do in Portuguese soil and in 2015, I want to personally address a big THANK YOU to all our users who have been supporting us since the August debut, helping us reach 4.048 total CodeCop packages downloaded as of this date. This is the fuel I need to keep going (but if you can please support it by licensing the product as well).

Hope you liked what v3.1 brings and if you’re a CodeCop fan, please take it as my personal gift to you, Merry Christmas!

See y’all soon.

Free Email Updates
Get the latest content first.
100% Privacy. No spam.

Liked it? Please Share.

Leave a Reply

Your email address will not be published. Required fields are marked *