Entries
RSS 2.0

Comments
RSS 2.0

Playing Nice With Service Locators

When I introduce dependency injection to developers, I often receive the complaint that it’s not significantly better than the service locator pattern. The main disadvantage of a service locator is that you’re required to couple all of the services in your application to the service locator in order for them to resolve their dependencies. By using a DI framework instead, you can keep your services very loosely-coupled.

However, there are some advantages of the service locator pattern. In particular, it’s much easier to implement hybrid activation — when some of the values in a constructor are provided by the consuming code, and some are provided by the framework. Hybrid activation is common in situations where you don’t need (or want) your DI framework to control the instantiation behavior of the type, but you still want to be able to resolve dependencies that are required for the instance.

In Ninject, hybrid activation is possible through the use of context parameters, which allow you to provide values for specific constructor arguments when you request the instance. However, context parameters can only be used for active requests — that is, calls to the kernel’s Get() method. If you often call Get() on the kernel, you’re using it as a service locator anyway.

The reality is, there’s nothing inherently wrong with using a service locator — when used in the right way, it can greatly simplify your code. I don’t think that service locator and dependency injection are mutually exclusive; in fact, I’ve found that it can actually be very effective when used in conjunction with a dependency injection framework like Ninject.

For example, let’s say you have an EventWatcher service that listens for a named event on an IMessageBroker, reads event information from the message, and triggers a specified callback. The implementation of such a service might look like this:


public class EventWatcher<T> {
  public EventWatcher(string eventName, Action<T> callback, IMessageBroker messageBroker) {
    //...
  }
}

You can’t easily activate a service like this using the Ninject kernel (at least without using context parameters), since the first two constructor arguments have to be supplied from the consuming code, and only the third is actually a dependency that should be activated via the kernel.

However, let’s introduce a simple service locator, which just delegates activation requests to a Ninject kernel:


public static class ServiceLocator {
  private static IKernel _kernel;
  public static void Initialize(IKernel kernel) {
    _kernel = kernel;
  }
  public static T Get<T>() {
    return _kernel.Get<T>();
  }
  public static object Get(Type type) {
    return _kernel.Get(type);
  }
}

Then, when we initially create our kernel, we just have to pass it to the Initialize() method of the ServiceLocator:


public static class Program {
  public static void Main() {
    using (var kernel = new StandardKernel(...)) {
      ServiceLocator.Initialize(kernel);
      //...
    }
  }
}

Using the service locator, we can alter our implementation of EventWatcher to make it easy to pass in the event name and callback method arguments, while still leaving it flexible enough to swap out the implementation of IMessageBroker. This is particularly useful for testability, since you can easily swap in a mock implementation of IMessageBroker in your tests.


public class EventWatcher<T> {
  public EventWatcher(string eventName, Action<T> callback)
    : this(eventName, callback, ServiceLocator.Get<IMessageBroker>())
  { }
  [Inject]
  public EventWatcher(string eventName, Action<T> callback, IMessageBroker messageBroker) {
    //...
  }
}

As you can see, if the more limited constructor is called, the EventWatcher asks the ServiceLocator to resolve the instance that should be used. Notice also that I’ve still kept the [Inject] attribute on the second constructor, in case you want to activate the type using the kernel and context variables.

While this is a useful technique in limited use, it’s important to be careful how much you rely on it. Remember that every time you use a service locator instead of dependency injection, you’re coupling your type to the service locator — and since it’s a static method call, it’s coupled just about as tightly as you can get. Again, though, taken in small doses, this technique can actually simplify your code and make it much more flexible.

Ninject Featured in InfoQ

Rob Bazinet, an editor for InfoQ, was kind enough to interview me about Ninject for the 1.0 release! Check out the article if you’d like to read more about the ideas behind Ninject and what went into its creation.

Ninject 1.0 Goes Gold

It’s always great to watch an idea mature from its first conception. About 18 months ago I began work on the first version of Ninject, which was then called Titan. It’s gone through a lot of iterations and all sorts of changes along the way, but today I’m happy to announce that Ninject 1.0 has officially gone gold and is available for download.

I’ve put in a lot of effort over the past couple of months to make Ninject multi-platform. One of the original goals of the Ninject project was to create a light enough framework that dependency injection was viable anywhere you could run a CLR. I’m proud to say that 1.0 supports the following platforms:

  • .NET Framework 2.0, 3.0 and 3.5
  • .NET Compact Framework 2.0 and 3.5 (Ninject.Core and Ninject.Conditions)
  • Silverlight 2.0 beta 2 (Ninject.Core, Ninject.Conditions, and all shipping extensions)

The same codebase is used for all supported platforms, with certain features turned off when the platform doesn’t support them. Unless I’m mistaken, Ninject is the first dependency injection framework to officially support the .NET Compact Framework or Silverlight, and this is no small feat. Kudos to Mike Eaton for kicking me in the right direction by encouraging me to provide Silverlight support. :)

It’s rare that open source software reaches a full version 1.0, instead preferring to remain beta-0.999 or release candidate 63. I’m not sure why that is; maybe open source developers are just too aware of the deficiencies of their software and are afraid to claim that the product production-ready. I’ve personally used Ninject in production systems for over a year now, and by now I’m very confident that it’s ready for prime time.

I’ve also taken the opportunity to re-launch the Ninject website. At the Cleveland Day of .NET, Brian Prince mentioned that he was frustrated that many open source project websites don’t contain any information about what the product is or does. I’ve tried to fix that with the new design, introducing some value propositions that I think explain how Ninject can help you write sleek, well-designed software that can stand the test of time.

So, what are some of the features of Ninject 1.0?

  • Constructor, property, method, and field injection
  • Instantiation behaviors (singleton, one-per-thread, one-per-request)
  • Fluent interface for declaring type bindings
  • Contextual bindings, where the selection of which type to instantiate can be delayed until activation
  • Support for instance scope and deterministic disposal
  • Fully pluggable, modular design: each kernel component can be easily replaced to alter the framework’s behavior
  • Lightweight interceptor support (aspect-oriented programming)
  • Integrations with other popular frameworks

I’d like to thank all of the companies and individuals that have contributed to the project, whether it’s been bug reports, patches, or software licenses. Please take some time to look at the products of the companies listed on the sponsors page.

I’d also like to dedicate this release to my wife Nicole, who has been understanding enough to put up with me hammering away at a keyboard for hours on end late at night. (She also helped me put together the cool products available in the Ninject store!) I love you sweetie. :)

Anyhow, grab the software, check out the manual, join in on the discussion, and by all means, buy some swag! :)

Bait-and-Switch and Software Licenses

Jack Slocum and the rest of the Ext JS team recently released version 2.1 of their fantastic toolkit. If you’re not familiar with Ext, it’s a user interface library that lets you write rich Internet applications (RIAs) using JavaScript. It’s more than jQuery or Prototype, in that it gives you full-fledged components like dialogs, grids, and trees in addition to the typical animation and language-enhancement features of the other JS libraries. If you develop RIAs and you haven’t tried Ext, I highly recommend you check it out.

That being said, the Ext team slipped in a little surprise with their latest release. Up until version 2.1, Ext was released under a dual-license model, with one option being an LGPL-compatible license and the other a commercial license. From this point forward, they’ve changed the options to GPL (as in, full copyleft) or a commercial license. This means that in order to upgrade to the latest version, all products which had previously relied on Ext will now have to start distributing the source — of not only Ext, but also their own products — in order to remain within license.

As you might imagine, this caused quite a stir within Ext’s already-quite-large user base. First, let me say that I am absolutely a believer in open-source software. Open-source means you can use the code in your own projects, commercial or otherwise. You can read the code and learn from it. You can contribute patches and ideas, furthering the project’s development. However, there is a tremendous difference between what I would call open-source licenses (Apache, BSD, MIT, et al.) and copyleft licenses like the GPL.

(Note: some people will disagree and say that GPL is still open-source, but I’m not trying to debate semantics. This post will refer to the two types of licenses separately.)

Ninject, for example, is open-source (Apache 2.0, actually), and I fully encourage anyone and everyone to use it in as many commercial products as they like. If you make a billion dollars through a product that uses Ninject, I’d appreciate it if you bought me a beer, or maybe my own private jet on 24-hour standby, but otherwise I would be nothing but happy for you. :)

The GPL is fine for things like operating systems and applications, which are essentially standalone. These products aren’t going to be re-used in other products. However, libraries, frameworks, and any sort of middleware should never, ever, ever be released under a copyleft license like the GPL. Copyleft is viral, in that the second it touches any part of your code, you must open its source. Ostensibly, that is perfectly reasonable, but the difference between closed-source and open-source is a business decision, and a very significant one. Your business model determines whether you can or should run your project as open- or closed-source.

Ask yourself: are you really going to build your business model around the license of a library like Ext? My guess is that most people would just find another way, and that discourages adoption of the library. It’s true that if people are making money off of Ext, it’s reasonable they pay the creators, but changing the license of the library after there are a lot of products that already use it is downright unfair. The Ext team is playing dirty, and people have every right to be upset.

There’s nothing wrong with wanting to be compensated for your work, particularly when you create something as widely useful as Ext. However, waiting until version 2.1 to change the license model for your software (not to mention changing it on a point release rather than a full dot-oh) strikes me as a little bit dishonest. Unless we give them the benefit of the doubt, it sure seems like they leveraged the openness of LGPL to get control of market share and build their user base, and then pulled a major bait-and-switch once they locked users in.

Bear in mind, also, that Ext was originally called yui-ext, and was built on top of YUI, the Yahoo! UI Library, a BSD-licensed toolkit. Basically, the Ext team stood on the shoulders of open-source, putting on airs as though they were participating, and then when the time was right they slammed the door shut.

Worse yet, the Ext community has contributed back a large number customized components and enhancements to the library. The Ext team hasn’t explicitly rolled these enhancements into the core, but they have undoubtedly learned from them and enhanced the code library as a result. I’ve also seen several cases where people submit code change suggestions (essentially patches) on the forum, which end up being rolled into the core. It’s not fair to have it both ways — accepting outside ideas means you have a responsibility not to screw the people that contribute those ideas.

At best, this is a terrible blunder on the part of the Ext team, and at worst, it’s a blatant misuse of open-source licenses. This is not what the GPL and the LGPL were created for. Also, it’s cases like this that add to the FUD surrounding open-source. After seeing things like this, I don’t blame businesses being afraid of adopting open-source in their products, for fear of the rug being pulled out from under them. And that’s not fair to real open-source libraries.

Of course, all this nonsense begs the question: how do you GPL a web application, anyway? In a typical website based on Ext, there’s client-side code written in JavaScript, which uses Ext for the user interface, and then there’s server-side code written in any of a myriad of languages which doesn’t come near Ext. Does using Ext on the front-end mean you have to open-source your entire product?

There’s all sorts of gray area there, which Jack desperately tries to explain. His reasoning? If your server-side code generates markup, then yes, you need to open-source it. What if the JSON/XML that I send back to the UI influences the layout? Do I need to open that source also? Now I need to employ a whole legal team to try to decipher whether or not I’m GPL-compliant.

Jack tries to defend the decision thusly:

In the end, we want Ext JS to be open source friendly and still have a good business model in place to grow. The old Ext License was not open source friendly and pretty much killed all options for use in open source projects. That wasn’t our goal so we had to address it.

To be perfectly blunt, that’s a crock of shit. The only reason the old Ext License wasn’t open-source friendly is because it wasn’t really the LGPL and therefore not OSI-approved. Why didn’t they use the LGPL, you ask? They were worried that someone would fork the project. Tell me again that they weren’t planning this all along.

Oh, and by the way, they’re not opening up the project’s Subversion repository. You can download official releases, but you can’t have direct access to the latest builds — unless you buy a commercial license. That’s technically fair, but doesn’t exactly jive with the concept of open-source.

On one hand, I feel for Jack, who has been a target of personal attacks because of this license change. He attempts to defend himself on his blog. However, it’s easy to see why people are upset, and I can’t believe he didn’t see it coming. I understand that you need to protect your intellectual property, but you need to recognize that open-source is a give-and-take (quid pro quo, as the Ext site says) — you give users free access to the library, and in exchange you get community support and good ideas. Changing from LGPL to GPL doesn’t protect the library from being misused by “major companies”, either. Sorry Jack, but they’re still banking on the fact that you don’t have the money to sue them.

To be fair, it does look like they’re considering a FLOSS exception like MySQL has, so non-copyleft open-source projects can continue to use the library. Why even change, then? You’re going to end up with essentially the same outcome as a result.

Using the GPL in this way arguably causes a chilling effect not unlike closing the source completely. By requiring users to release their source, you are shutting out a potential segment of users. It’s very easy to see that if Ext had been licensed under the GPL since inception, it would not have nearly the mind-share it does today.

Since I use Ext in my “day job” in for-profit products, we were happy to buy a commercial license. However, now that it’s licensed under the GPL, its much more difficult for me to consider using it in side work or hobby projects.

Announcing Ninject Contrib!

A few days ago, I accepted the first patch for Ninject, an NLog integration extension by Ivan Porto Carrero. Ivan subsequently created a couple other extensions for Ninject, and rather than put them directly into the main project, we decided to launch Ninject Contrib to collect contributions from the community.

If you’ve got any ideas for Ninject extensions, or if you come up with any examples that you’d like to share with the rest of Ninject users, feel free to post your idea in the Ninject developers group and I’ll set you up with commit access.

Major thanks to Ivan for his contributions, and his excellent ongoing series of Ninject-related articles!

This Is Why We Can’t Have Nice Things, People

Rob Conery (a Microsoft employee) has been working on a series of screencasts (part one, part two) illustrating the construction of a web commerce application using TDD. His intent is to learn the process, and by doing so, help others to do the same. These screencasts have caused some major backlash on the intertubes, where people have attacked him for not fully understanding TDD, and therefore presenting his allegedly poor ideas as Microsoft best-practices. The debate culminated in a conference call between Rob, Aaron Jensen, Ben Scheirman, and Scott Bellware.

First off, let me say that Microsoft must have killed Scott Bellware’s puppy or something. All you have to do is say the word “Microsoft” to raise his blood pressure to unhealthy levels. He’s clearly very intelligent, and has good things to say, but every time he tries to make a point, it gets drowned in piss and vinegar.

Note to Scott: not everything has to be Israel vs. Palestine. We want to hear what you have to say, but lay off the holier-than-thou stuff and you won’t come off sounding like a pompous ass. People don’t respect those that don’t respect others. The more you alienate people, the less you’ll be taken seriously — and the less effective you will be at getting your message across.

Anyhow, a comment by David Nelson on Rob’s post describing the conference call sums up why this whole situation is ridiculous:

When you open up with “My name is Rob Conery and I work for Microsoft”, you are declaring yourself to be an expert at whatever you are talking about.

Are you kidding me? I really hope that this is an aberration and the majority of the .NET community doesn’t feel this way. If someone works for Microsoft, I tend to think they have their finger on the pulse of what’s going on in the company (or at least in DevDiv) — but Microsoft is a huge corporation, so even that is suspect. Just because someone works for Microsoft doesn’t mean they’re an expert at anything, or should even be listened to in the first place. Now, I tend to think Rob is a pretty sharp guy, but that’s more due to his contributions to the community than the fact that he works for Microsoft.

Software developers are smart people. Since when did we forget how to think for ourselves?

This, in a nutshell, is what’s wrong with the .NET community, and why Microsoft largely remains a “walled garden”. If a Microsoft employee can’t communicate their perspective to the community at large without it being taken as the One True Way, they will simply stop talking, and the trumpet of Sales and Marketing will drown out the voice of the technologists. This is not the fault of Microsoft employees, or the company itself. If people truly do take the word of Microsoft employees as fact, the problem is systemic, and each developer that thinks this way shares in the blame.

This is also at least part of the reason why Microsoft has traditionally been hesitant to associate their name with open-source software. This results in an offshoot of the Not Invented Here syndrome, Not Invented at Microsoft — which leads to unnecessary projects like MSTest, ASP.NET MVC, and Unity. Don’t get me wrong, there’s nothing inherently wrong with Microsoft creating these projects, but they are all “me-toos” created after similar open-source efforts (NUnit, MonoRail, and Windsor, respectively) have had success. Now, I understand that a lot of developers have difficulty convincing the “powers-that-be” in their companies that open-source is a viable alternative to commercial software. A lot of companies are wary that if they build their products on open-source, if they need commercial support, it won’t be there.

However, what if, instead of hiring leaders of the .NET community to create official, Microsoft Brand(tm) alternatives to existing open-source software, Microsoft certified and funded open-source projects directly? For example, NHibernate and the Castle Project are two of the most well-respected open-source efforts in the .NET community. Their software provides fantastic value to a huge number of companies.

What if Microsoft awarded these projects a grant, so they can provide commercial support, and then told its customers that these are quality software products, and are safe to use in their infrastructure? Microsoft would save money, improve the legitimacy of .NET as a development platform, and give the developers that donated their time to the community a chance to make their hobby into their day job.

As long as the average .NET developer believes that what someone says is solid gold just because their paycheck says Microsoft on it, this will never happen.

Microsoft Supports Open-Source Software

Okay, I was skeptical too, but it’s true. They proved it to me.

In one of the comments on this post on Rob Conery’s blog, I saw Sam Ramji, the Director of Platform Technology Strategy at Microsoft, mention that they were interested in sponsoring .NET open-source efforts by donating MSDN licenses. I had just recently released the first beta of Ninject (then called Titan), so I sent Sam an email asking whether Microsoft would be willing to sponsor the project. Sam replied (in a matter of hours, no less) letting me know that they’d be happy to donate a MSDN license to the project, and connected me with Garrett Serack, Microsoft’s Open Source Community Lead to get the details worked out.

A little while later, I received a congratulatory email welcoming me to the MSDN Program. The Ninject project was now the proud new owner of a MSDN Premium subscription, and a MSDN Visual Studio Team Suite license. I never paid Microsoft a cent, or jumped through bureaucratic hoops, or anything. I was using a copy of Visual Studio 2005 Standard Edition that I’d gotten at a launch conference in November of 2005, and I was concerned that my open source efforts wouldn’t be able to keep up once .NET 3.5 and Orcas comes out next January. The MSDN license ensures that I won’t be hindered by financial constraints. (Which is great, since Ninject’s budget is holding steady at $0. :)

I mentioned this to a coworker, and he laughed, saying that Microsoft probably just wanted to see if my source code infringed on any of their patents. I corrected him immediately, and if anyone tries to tell me that Microsoft doesn’t care about open source software in the future, I will be sure to mention their support for Ninject. Microsoft is the world’s largest software company, and with an issue as sensitive as intellectual property and open source, there are bound to be multiple factions within the same company. People who are more in tune with the business of software than the technical underpinnings (like Steve Ballmer) are much more likely to spurn open source, seeing it as synonymous with Linux and therefore a threat to the Windows platform. I’m certain that at least a large subsection of developers within Microsoft believe in open-source software and would choose to contribute to OSS efforts if possible.

Microsoft is changing. The Microsoft Permissive License is a legitimate open source license, basically just BSD plus an extra clause describing patent disputes. New developer efforts like the DLR (and associated languages, IronPython and IronRuby) are being released under the MPL. Microsoft is even accepting community code contributions for IronRuby. How much more open source can you get than that?

Now, does this mean Microsoft will embrace OSS as a business model? No. They’re not releasing the source for Windows or Office anytime soon. However, at least in parts of the company, there’s a growing effort to support and cultivate open source efforts, rather than stomping them out or usurping them. What I really would like to see from Microsoft is company contribution back to existing open source efforts, particularly for developer tools. For example, rather than introduce their own unit testing system, they should just contribute support to nUnit or MBUnit. Until then, this is a good start.

IronRuby and a Paradigm Shift at Microsoft

John Lam just announced that Microsoft will be accepting source code contributions for the IronRuby project! They’ve already impressed me by releasing the DLR, IronPython, and IronRuby under their Microsoft Permissive License, which is essentially just BSD with extra patent protections so no one sues them for a bajillion dollars. I have to admit, I didn’t think I’d see the day they’d accept community contributions to a project. More and more, it seems that Microsoft is starting to embrace open source. I don’t think they’re going to GPL the Windows source anytime soon, but opening the source of developer projects is a big step.

I can’t wait for the DLR… I’m hoping they can make IronPython and IronRuby first-class citizens in Visual Studio as well. I’m also interested in seeing what sort of fun DSL support the DLR can provide…

Open Source, and Passionate Developers

Last night, I came across this article talking about the difference between an employee who is passionate about the company and an employee who is passionate about their work. Rarely does a blog entry come along that matches up so exactly with my own ideas.

The best nugget of wisdom comes in the form of the “four-question test” that identifies if an employee is passionate about their work:

  • keeps up with trade/professional journals
  • knows who the key people in the industry are
  • would spend his own money, if necessary, for better tools
  • if they were NOT doing this as their job, they would still do something related to it as a hobby

When applied to software developers in particular, I would add “participates in open-source software efforts” to the list as well. This relates closely with the 4th question (concerning hobbies), but goes deeper — it suggests that not only does the individual enjoy what they do, but they want to use their talents for “the greater good”. This also goes back to another test of a “passionate worker” in the original article:

Does not care about upward mobility in the company. Cares about doing fabulous work and possibly the recognition of his peers in the industry. May stive (sic) for professional recognition.

This is the main reason why I chafe so much under the the non-compete agreements and intellectual property constraints that permeate the software industry. All developers should have the right to “own” the software that they develop, as long as it’s done entirely on their own time with their own resources, and doesn’t represent a conflict of interest with their “day job”. Not only should developers be allowed to release their own personal creations as open source, but they should be permitted to sell them.

Before you tag me as some sort of commie, understand that I do think a company that employs software developers has every right to protect their intellectual property. Unfortunately, too many companies do so simply by saying their developers own nothing. Before I took my current job, I interviewed at a “big-name” consulting firm. Their contract agreement said something along the lines of:

The Employee hereby acknowledges that all Inventions are the property of (company), except those explicitly listed in Appendix A.

Translation:

You’re screwed. If you ever have a unique idea that ends up gaining any decent amount of buzz or generating any decent amount of money, you better damn well better be able to prove that you didn’t think it up before, during, or up to 12 months after your tenure with our company. Otherwise, we’ll sue the shit out of you and take not just your ideas, but your house, your car, and probably your dog.

Needless to say, I wasn’t interested in the job. (Particularly when they offered me a flat salary with no overtime and suggested that the average work week was 70-80 hours. Bear in mind, they would be billing my time to their client on an hourly basis.)

In my opinion, developers should legally own their work, as long as the following conditions are met:

  • Absolutely no code would be re-used from company projects.
  • Within reason, no concepts that were developed specifically for in-house projects would be re-implemented.
  • All of the work on the project occurs on the developer’s own time, outside of the office, and would not be developed using any company hardware or software.
  • The software would not be directly related to the company’s industry, and would not compete with any offerings of the company.

Developers who care about software write the best software. If they want to spend hours of their own time improving their skills, why get in their way?

MetaCode Released on CodePlex

Happy birthday to me! :)

Today’s my 24th birthday. To celebrate, I released a project on CodePlex which has been one of the things I’ve been obsessing over in the past few weeks. It’s a library called MetaCode. From the project description:

The MetaCode library provides a means to generate dynamic types at runtime without directly emitting CIL opcodes. The library exposes a flexible “meta-programming” model that represents code artifacts via objects, similar to the types found in System.CodeDom. Internally, MetaCode uses the types in the System.Reflection.Emit namespace to build the concrete implementations of types.

The desire to create the MetaCode library started when I got tired of working with CIL directly while developing Cricket, and the integration framework I’m working on at Merge. Here’s a simple example of how to use the library.

A common pattern when working with dynamic types is to create a concrete implementation of a contract, which is implemented as a .NET interface. Let’s say you have this (very useful) interface:

public interface ILoopy
{
  int Loop(int start, int max, int step);
}

The Loop() method is supposed to move through a simple loop structure given the provided parameters, and return the final value of the index. If you were to implement this contract using a while loop in C#, it might look something like this:

public class WhileLoopy : ILoopy
{
  public int Loop(int start, int max, int step)
  {
    int index = start;
    while (index <= max) { index += step; }
    return index;
  }
}

However, you could also do the same thing with a for loop, like this:

public class ForLoopy : ILoopy
{
  public int Loop(int start, int max, int step)
  {
    int index = start;
    for (int ii = start; ii <= max; ii += step) { index = ii; }
    return index;
  }
}

Let’s say that for some bizarre reason, you wanted to delay the decision on which loop method to use until runtime. Admittedly, this is an overly simple example. Ignore the lack of practicality of this case and bear with me. If you want to see some more practical uses, grab a copy of the source and take a look at the Assemblers project. It shows two methods of proxy generation, one that uses composition, and one that uses exterior interceptors.

Anyhow, back to this example. To start working with MetaCode, you have to use the objects defined in the TypeModel hierarchy. All dynamic types must exist inside a MetaAssembly. Then, we can create a MetaType that implements our ILoopy interface inside of it:

MetaAssembly assembly = new MetaAssembly("Enkari.MetaCodeExample.Dynamic");
MetaType type = assembly.DefineType("TestType", new Type[] { typeof(ILoopy) });

Readers familiar with the System.Reflection.Emit namespace may be wondering, what about modules? There is actually a MetaModule class as well that actually contains the defined MetaTypes. However, since the majority of assemblies only contain a single module, the MetaAssembly type provides shortcuts to create types directly in a “default module” inside it.

Okay, so now we have the beginnings of a concrete implementation of ILoopy. However, to actually implement the type, you have to provide an implementation of the different members that the contract defines. There are two ways to define a method on a MetaType: definition and overriding. As the name suggests, overriding means to override a method defined by a base type or interface. (It’s somewhat akin to the override keyword in C#, but is used to implement interface types in addition to overriding methods marked virtual on base types.) In this case, we want to override the Loop() method defined by our contract:

MetaMethod method = type.OverrideMethod(typeof(ILoopy), "Loop");

So far, none of this is that impressive. Most of the functionality that we’ve covered so far matches that provided in the System.Reflection.Emit namespace. If we were using SRE, we would now start emitting CIL opcodes using the method’s ILGenerator.

Instead, with MetaCode, we can use a code builder, which gives us a way to piece together code artifacts represented by the objects defined in the CodeModel namespace to create the method body. Right now, the only code builder that’s defined is the ImperativeCodeBuilder, which presents an imperative programming interface to creating the method body:

ImperativeCodeBuilder cb = new ImperativeCodeBuilder(method);

Now we can actually build the method. Let’s start by declaring a local variable to store the count, and initialize it to the value of the first argument (the starting value of the loop):

VariableReference countRef = cb.Declare("count", typeof(int), method.Arguments[0]);

Then, we can define the loop itself. I’ll define this implementation using a while loop. We can refer to our defined “meta variable” using the VariableReference that was returned from the Declare() method call, and begin the while loop:

cb.While(countRef < method.Arguments[1]);

This creates code inside the MetaMethod that does just what it reads like: the while loop will continue while the count variable is less than the value of the second argument of the method. Although it seems strange, you can define statements using the standard comparison operators. Behind the scenes, the operators are overloaded to create MetaOperation objects that do the actual comparisons. (For example, the < operator is overloaded to join two MetaExpressions in a LessThanOperation.)

Anyhow, at this point, any statements we define from now until we call EndWhile() will be defined inside the while loop’s body. Let’s create the increment statement:

cb.Assign(countRef, countRef + method.Arguments[2]);

This increments the count variable by the value provided by the third argument of the method. Now, we can end the while loop:

cb.EndWhile();

Now we’re back out of the while block’s body. We’re almost done implementing our simple method. All that’s left is to return the value of the count variable:

cb.Return(countRef);

At this point, we’ve defined a valid concrete implementation of our ILoopy interface. It’s still only meta code, though, meaning it’s only defined as an object graph. Before we can execute it, it has to be “realized”. Objects can only be realized once, and after they’re realized, you can’t edit them. The easiest way to realize the types is by calling one of two methods available on MetaType: CreateType(), which realizes the MetaType and returns a System.Type, or CreateInstance(), which realizes the MetaType and then calls Activator.CreateInstance() to create an object of the newly-created type.

In this case, we’re only interested in a single instance of the MetaType, so we’ll call CreateInstance(). The method actually returns a System.Object, but we can cast it to our contract type:

ILoopy loopy = type.CreateInstance() as ILoopy;

You can then interact with the object as if you wrote it in your favorite .NET language. The following call will run through our loop and output “20″ to the console:

Console.WriteLine(loopy.Loop(1, 20, 1));

So there you have it. An important thing to remember is that once realized, the code you build with MetaCode is defined as CIL, so executing it is just as efficient as running any other method. Also, the realization process doesn’t require triggering the compiler, so it’s much faster than using the types in the System.CodeDom namespace.

If you’re interested in learning more, you can download the example project described here.

Also, please check out the CodePlex project, or get a copy of the code from the Subversion repository. If you have questions or comments, feel free to post on the CodePlex forums.