Click here to Skip to main content
Click here to Skip to main content
Go to top

Mixin in C# 3

, 19 Sep 2005
Rate this:
Please Sign up or sign in to vote.
How to add mixin to a class in C# 3

Introduction

Note: It's probably pretty early to start talking about patterns for C# 3, but the thought popped in my mind and wouldn't go away.

Mixin: In computer science, a mixin is a group of functions which can be mixed into a class and become methods. They allow certain classes to take on certain functionality, in an object-oriented programming including in languages that do not support multiple inheritance, just as if the class were a cooking dish and a mixin was a specific ingredient.

Ruby on Rails recently got a act_as_taggable mixin, which basically allows you to just slap a single line of code on a class and get tagging support. I'm going to show the C# 3 interface for a similar implementation. I don't care about the implementation, so we'll just assume that this is a given. I want to be able to tag any database object with as few lines of code as possible and just have it work like magic, the ideal is Ruby's single line of code. I'm going to show the ideal, the interface & client code and then talk about how this is possible.

The Code

Let's see what we would like to write:

//Creating taggable mixin 
public mixin Taggable<T>
{
 public void TagWith(params string tags) { .. } 

public static T TaggedWith(params string tags, FindWith with) { .. }
}
public enum FindWith 
{
 AnyOfTheTags,
 AllTheTags
}
//Adding tagging to a class
public class Photo : Taggable
{
...
}

//client code: 
// create photo and adding tags 
Photo photo = ... ;
photo = Photo.TaggedWith("flower","sun","yellow", "mayhem");
//Loading with tags
Photo photo = Photo.TaggedWith("flower", FindWith.AnyOfTheTags);

This is what we would like to have, but right now and in the future we are not likely to get it. We can get something very close. Here is what we would need to write:

//creating taggable mixin
namespace Tagging
{
 public static class Taggable
 {
  public static void TagWith(this ITaggable<T> tagged, params string tags) { .. }

  public static IList<T> TaggedWith<T>(params string tags, FindWith with) 
            where T : ITaggable<T> { .. } 

 public interface Mixin<T>   where T : ActiveRecordBase, Mixin<T>   { }
 }
 
 public enum FindWith 
 {
  AnyOfTheTags,
  AllTheTags
 } 
}
//Adding tagging to a class
public class Photo : ActiveRecordBase, Taggable.Mixin<Photo> 
{
...
}
//client code
using Tagging;//create photo and adding tags 
Photo photo = ... ;
photo.TagWith("sun","rain","colors");
//load photo with tags
IList<Photo> photoWithFlowers = 
    Taggable.TaggedWith<Photo>("chaos",  FindWith.AnyOfTheTags); 

So, what do we have here? We have a static class with extension methods that refer to the Taggable.Mixin<T> interface. The Taggable.Mixin<T> interface requires that the implementing class will inherit from ActiveRecordBase and implement ITaggable*, this is so the Taggable class will have a way to work with the database, (that is an implementation detail, it can certainly be done in other ways).

Then we have the Taggable class, which has an extension method to add tags to an object, and a static method (not an extension one), which takes a Taggable.Mixin type and returns a list of the tagged instances of it. Check out the bolded lines, those are what you've to do in order to get the taggable support for an object. Add a declaration to Taggable.Mixin, and your object is set. Then in the client code, just import the Tagging namespace, and you can use it as if it was part of the object.

I think that this is a really nice way to add functionality to objects in a non intrusive way. The client code can actually choose whatever it wants to be exposed to the tagging support or not, and all the class has to do is to declare its intention to accept the mixin.

As I said, it's pretty premature to start thinking about patterns for C# 3 (C# 2 is not yet released, after all), but I'm willing to bet quite a sum that this will be the way to create mixins is the .NET Framework. This is just one of the cool things that you can do with the things that C# 3 will give you. I expect a lot more goodies along the way. The new features are useful for so much more beyond LINQ.

One thing to be considered, it's pretty early to say anything, but I can certainly see libraries such as the Boost providing tremendous value for developers in the C# 3 world.

Implementing Taggable.Mixin

Since Taggable.Mixin is an empty interface, the constraints here are just a way to say that any Taggable.Mixin must inherit from ActiveRecordBase. It's a nice way to declare things, since now we can say: ITaggable<Photo> is ActiveRecordBase, and it's always true.

For mixin today you can use Castle.DynamicProxy.

History

  • 19th September, 2005: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

No Biography provided

Comments and Discussions

 
GeneralA nice practical use of Extention Methods Pinmemberegozi134-Aug-06 8:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140916.1 | Last Updated 19 Sep 2005
Article Copyright 2005 by Ayende @ Rahien
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid