Some thoughts on expanding SuccincT to provide richer interface contracts and auto-generated data classes

! Warning: this post hasn't been updated in over three years and so may contain out of date information.

SuccincT iconRecently I created a very simple framework, SuccincT. At it’s core is the ISuccess<T> interface. As I explained in a previous post though, by itself that interface isn’t much use. C# lacks the ability to define constraints on an implementation of ISuccess<T>, save through comments. The idea behind it was that an implementation should throw an exception if its Value is read when Success is false, but there is no way to guarantee that an implementation will exhibit this behaviour. This bugs me.

Unrelated to SuccincT, I’m a fan of defining data objects via interfaces, rather than concrete types. By “data object”, I mean any object that encapsulates a set of values. These might be used to avoid multiple parameters to a method or constructor, or to return a complex data set from a method. Data objects need not be immutable or serializable; they just need to be simple to use without causing problems when it comes to testing. As I like to encapsulate data, I like the setters of data objects to be internal, which does cause problems with testing. Thus why I like to use interfaces: the test class can define its own implementation, rather than having to fight against encapsulation. However, for every interface I create, I have to create at least one class too. This adds needless code to projects, which also bugs me.

These two things – wanting interfaces to define a more detailed contract and wanting to avoid having to write data object classes that can be 100% inferred from the interface – set me thinking: could I create some way of extending interfaces and avoiding writing data object classes?

My first idea was to keep things as simple as possible. For the interface IXYZ:

I’d simply make a call like:

This would result in xyz containing a reference to an instance of an implementation of IXYZ. That implementation would be generated and compiled at runtime, so it wouldn’t be necessary to write any code for it.

This idea could then be extended to allow interfaces to define more detailed contracts. Taking the following from SuccincT:

the current implementation is:

What I want to be able to do is replace it with something like:

and then have a ISuccess<int> implementation returned via one of these two calls:

Both success and failure would be set to instances of an implementation of ISuccess<int>, which would be created at runtime. There would be no need for the code in class Success<T> above to exist other than at run-time.

This initial idea is simple to implement, but it does have some disadvantages. Firstly, generating a new type at runtime is costly. This idea wouldn’t scale well and generating 100’s of such classes might add minutes to an application’s start up time. Secondly, Succinct.CreateInstance<T>() cannot know in advance the number and type of the parameters that will be passed to it. So its signature would have to be something like Succinct.CreateInstance<T>(params object[] paramList) and no type checking can be done at compile-time. Finally, a means of reliably ensuring the order of the parameters will match the order the items are defined in the interface would be needed.

One possible way to expand on the basic idea would be to create some sort of utility that scans a project’s interfaces and, if it finds a [Succinctable] one, it generates the derived class for it. This would have the advantage that the class would exist as source code and so instances can be created directly using strong typing. The Roslyn project ought to provide the means of parsing the interfaces and compiling the generated code. This shouldn’t be too difficult to implement therefore.

There are problems with this idea though, mainly that it wouldn’t work well with Visual Studio. The latter has an annoying feature in that files must explicitly be added to a project for them to be compiled. Generating the files as a pre-build step would mean they wouldn’t be compiled to the assembly automatically, intellisense wouldn’t work etc. It might work well in Mono build environments though.

My final idea is by the grandest. It involves creating an add-on for Visual Studio that works like the Razor Generator for ASP.NET MVC. When a [Succinctable] interface file is saved, the add-on would be triggered. It would then auto-generate the derived class file and add it to the project. This would be by far the most advantageous solution for Visual Studio users. I know nothing about writing Visual Studio add-ons, but I suspect it’ll be a tough thing to write. SO this won’t be happening any time soon.

In conclusion I think the initial basic idea has enough merit to warrant creating it. The other ideas might follow depending on how well it all goes. If you have any thoughts on all of this though, please do say. I’m open to suggestions…

2 thoughts on “Some thoughts on expanding SuccincT to provide richer interface contracts and auto-generated data classes

  1. Just stumbled across this today while researching ORM frameworks for C#. There’s a couple of other things you may want to try for generating the classes if the main issue is getting the files into the build process.

    One thing you could do is edit the project template. In VS 2008 and later this is an MSBuild file for C# projects. It’s a pain to edit because you have to unload the project first (and make sure it doesn’t mess with your references), but it’s a cheap simple way to edit the project build. For starters, you can add your file to the Compile item list. Also, you can ease the pain by making your own project or item templates.

    Another thing you can try is T4. T4 templates get evaluated at build time, and I think this may also allow people using your framework to extend the process by editing the templates.

Comments are closed.