Twin Cities Developer Guild

The twin cities developers guild has recently formed as a way to help bring together and organize other special interest groups.

Magenic is currently sponsoring an XNA User Group as well as a Languages User Group and now the Developers Guild is being formed. I’m happy to say that these groups are open for everyone and will encompass any relevant topic. Check out the respecitve websites and come to the meetings when you can!

NBusiness 3 Updates

I’ve been working on NBusiness a little bit over the weekend. I’ve decided to create a Curried API using extension methods for the CodeDom to speed along template creation. Here is an example of what I have so far.

CodeMethodReferenceExpression onPropertyChanged =
 new CodeMethodReferenceExpression(null, “OnPropertyChanged”);
 
CodeMemberProperty memberProperty = new CodeMemberProperty();
memberProperty.Name = field.Name.ToPascalCase();
memberProperty.Type = new CodeTypeReference(field.Type);
 
memberProperty.Get()
.Return(memberField.Reference());
memberProperty.Set()
.If(             
    memberField.Reference().NotEqualTo(memberProperty.SetValue()))
.Then(
   memberField.Reference().Assign(
      memberProperty.SetValue()),
      onPropertyChanged.Invoke(memberProperty.Name));
Trust me, as ugly as the above seems it’s still a million times better than doing it all the way it was originally written. Hopefully this will mature and get better over time as well. Here is an example of the code it produces.
private int Aid {
 get {
   return _aid;
}
 set {
   if ((_aid != value)) {
      _aid = value;
      OnPropertyChanged(“Aid”);
    }
}
}
Secondly I have been polishing and simplifying the model framework that comes with NBusiness. I have been working to create an abstract DataAccess API that can easily produce any type of query. Here is an example of how you might insert a new model with the next version of NBusiness.
MockModel model = new MockModel();
model.Name = “testinsert”;
model.Save();
This is as normal and will end up calling into MockModel’s “InsertModel” method which may be implemented like so
protected override void InsertModel(IQuery query)
{
query.Insert().Into(
    MockModel.Database.Table,
    MockModel.Database.Name).Values(“@Name”);
query.Go();
query.Parameter(“@Id”).Direction = ParameterValueDirection.Output;
query.Parameter(“@Name”).Value = Name;
query.Load += loader =>
{
   Id = (int)query.Parameter(“@Id”).Value;
};
}
The DataBase.Table and DataBase.Name members are code generated, static ITable and IColumn fields based on your E# model definition. The query object will be passed up to parent objects and down to child objects and will be passed into an abstract provider which will use it to generate SQL and call your database. The IQuery object actually comes from your IDatabaseProvider and may abstract it to work with different databases. My theory at this point is that you could actually parse the query object anyway you like in the IDatabaseProvider and with a little manual work you could even get it working across a webservice.
Here is my MockDatabaseProvider for my unit tests. The provider interface is much simpler with this new technique.
class MockDatabaseProvider : IDatabaseProvider
{
#region IDatabaseProvider Members
 
 public IQuery Query()
{
    return new SqlQuery();
}
 
 public ITable Table(string name)
{
   return new SqlTable(name);
}
 
 public void Execute(IQuery query)
{
   MethodCall.Calls.Add(new MethodCall(
      “Execute”,
      new { Name = “query”, Value = query }));
 
   SqlQuery sqlQuery = query as SqlQuery;
           
    // Simulate setting the identity parameter after an insert
    IParameterValue id = sqlQuery.Parameters.FirstOrDefault(
      v => v.Name == “@Id”);
   
    if (id!=null && id.Direction == ParameterValueDirection.Output)
    {
      id.Value = 100;
    }
 
    sqlQuery.OnLoad(new MockLoader());
}
 
#endregion
}

Twin Cities Languages User Group

A new user group has formed in the Twin Cities with a special focus on programming languages.

http://www.twincitieslanguagesusergroup.com

The first session will be held by Charles Nutter, who works for Sun Microsystems developing JRuby. He works right here in the Twin Cities and I’ve met him personally at the Lang.NET symposium this past January and found him to be very knowledgable and exciting to talk to.

Getting a chance to talk with someone who is actively working on a professional programming language should be quite interesting. If you have any interest at all in programming languages you should definitely go to the link above and find out the logistics.

Creating Attribute Macros in Boo

 

Here is a simple example of writing an Attribute Macro in boo. I have created a macro that you can use to ensure that parameters are not null and raise a ArgumentNullException if they are. The interesting thing to note about this is that if you were to do this in C# you would need to use a factory method to inject these methods as aspects at runtime. With Boo macros you are actually changing the code at build time, which has both positive runtime performance implications and positive architectural changes since you do not need a factory method.
Here is an example of how you might use such an attribute:
namespace MacroExample
 
import System
import Macros
 
class Example:
       [Ensure(example)]
       def DoSomething(example as string):
              print example.ToUpper()
             
e = Example()
e.DoSomething(“testing!”)
e.DoSomething(null)
 
print “Press any key to continue . . . “
Console.ReadKey(true)
 
I have declared a class called Example with a single method DoSomething. On that method we have attached an Attribute called Ensure. If you were using standard Aspect Oriented Programming techniques you would need some custom code to inspect this attribute at runtime and build a dynamic type and method to wrap the logic of the ensure attribute.
In Boo, since my EnsureAttribute inherits from AbstractMacroAttribute the logic of the Attribute will actually be run at build time, not runtime. Note the parameter in the constructor, the ‘example’. There are no quotes around this because it is not a string. It actually comes into the constructor as a ReferenceExpression which I can use to match to the methods parameters.
Here is the ensure Attribute code:
namespace Macros
 
import System
import Boo.Lang.Compiler.Ast
 
[AttributeUsage(AttributeTargets.Method)]
class EnsureAttribute(Boo.Lang.Compiler.AbstractAstAttribute):
      
       private _parameter as ReferenceExpression
       public Parameter as ReferenceExpression:
              get:
                     return _parameter
                    
       def constructor(parameter as ReferenceExpression):
              _parameter = parameter
      
       override def Apply(node as Node):
      
        target = cast(Boo.Lang.Compiler.Ast.Method, node)
       
        parameter as ParameterDeclaration
        for p in target.Parameters:
              if p.Name == _parameter.Name:
                     parameter = p
                     break
       
        code = [|
              if $(parameter) is null:
                     raise ArgumentNullException($(parameter.Name))
        |]
       
        target.Body.Insert(0, code)
 
 
One of the most amazing parts about constructing macros in Boo is the built in code templating features. If you notice towards the bottom of the example where we are assigning to the variable ‘code’ there is a special block wrapped in [| … |]. This is a special type of operator that tells Boo that whatever is inside of this block is to be parsed and returned as an AST (abstract syntax tree) node. This is a helper for replacing reliance upon manually constructing Boo CodeDom objects. You can see on the following line that this compiled code is being inserted into the body of the method this attribute has been applied to.
It is important to note that while we are affecting the body of the method that method knows about the class it is attached to and that class knows about all other classes in the assembly and so on. This is the difference in power between Boo macros and C++ macros.

Calling Member Methods on null References

I just learned about an interesting way to use extensions methods. It turns out that even though extension methods appear to be used like member methods they still are, actually, not. Here is an example:

 

class Program

{

    static void Main(string[] args)

    {

        string value = null;

 

        Console.WriteLine(“IsNullOrEmpty: “ + value.IsNullOrEmpty());

        Console.ReadKey();

    }

}

 

public static class Extensions

{

    public static bool IsNullOrEmpty(this string value)

    {

        return string.IsNullOrEmpty(value);

    }

}

Which outputs:

IsNullOrEmpty: True