Entries from May 2008 ↓
May 25th, 2008 — .Net, Boo, Visual Studio
Quick update on the Boo plugin I mentioned previously. Jeff Olson announced the BooLangStudio project a couple of days after I announced mine, and we’ve decided to join forces. I’ve begun merging our codebases, and we’re looking to get a release out in the not too distant future.
Our combined code-bases have now got syntax highlighting, intellisense, single file and project support. Not bad going.
We’ve now got a nice little team going as well, which is a big improvement from what was the one man band of my self. One of the contributors, Torkel Ödegaard, has written a nice overview of our progress and processes as-well.
May 18th, 2008 — .Net, Boo, Hobby Projects, Visual Studio
What do we want? A Boo plug-in for Visual Studio. When do we want it? Sooner, rather than later.
The initial aim of this plug-in is to provide a “good enough” experience when using Boo files within other projects. I’m not currently focussing on doing full-scale development with Boo; so the target is DSLs and Binsor. There won’t be any assemblies created, or anything else that would affect your project. The only difference between how you work now would be that you could write Boo using Visual Studio, with syntax highlighting and intellisense.
That’s for the initial version anyway.
I’ve found that creating a plugin for Visual Studio isn’t that difficult, in-fact that’s an understatement, it’s stupidly easy. Most of the plugin architecture is successfully created using the project wizard, so there’s very little I needed to do from that point of view. The tricky part is getting Boo and Visual Studio to communicate.
I started by spending some time looking at the IronPython Studio implementation, the Boo implementation, abstract syntax trees, antlr, and after getting my head around what I needed to do, I set out on my adventure.
So what’s the result? A very basic (and flakey) implementation of both syntax highlighting and intellisense.

The highlighter isn’t perfect yet. It suffers from slowdown when you’re writing an unclosed string, and it can’t handle multi-line statements yet (think comment blocks).

The intellisense is pretty basic, it allows namespace navigation, and type methods, but there isn’t much in the way of constraints (you can see instance methods against types, for example).
There’s a lot of work to be done, but it’s fun and interesting.
Targets
In the near future I’d like to get the following done:
- Make intellisense work with everything in the local scope
- Make intellisense parse import statements
- Make syntax-highlighting correctly handle multi-line blocks
- Make syntax-highlighting highlight types (like C# does)
Then at some point tackle these:
- Get Resharper involved
- Refactoring support
Hopefully I’ll progress on these and report back in a future post.
Code
The code is poor, it’s a mess and probably all wrong; however, you can get it in the usual place. However, I haven’t provided a direct download because it isn’t really in a state to be distributed yet.
The source is accessible from Subversion at: http://jagregory.googlecode.com/svn/trunk/BooPlugin/ (using user jagregory-read-only)
May 18th, 2008 — .Net, Code, Work
The current system I’m working with has a setup whereby the model (data access objects) are being used by the web-services for delivery; this means that the consumers of the web-services are directly tied to our inner implementation of our data access code. On-top of that, it’s old full of bad conventions, and is in need of refactoring.
This is my account of how I freed the model from the web-service.
public class vehicle_info
{
public int vehicle_id;
public string vehicle_name;
public string vehicle_manufacturer;
public DateTime vehicle_manufactured_date;
public int vehicle_number_produced;
}
That’s the existing model. You can see that these have some nasty naming conventions that I just can’t live with anymore.
A large problem with pushing your model out to the web-service consumers is that I can’t refactor the classes without breaking their implementations; if I rename a field in my model, the consumers will have to update their code to deal with it. This is an issue because not all the consumers are able to update their code. So we’re stuck with how the classes were built years ago, with awful naming conventions, and no ability to change.
What’s the ideal setup then? It’s my opinion that we should be using specialised DTOs (Data Transfer Objects) for this purpose, they’ll exist solely to be the transport mechanism for the web-service. With DTOs you’re separating what your service pushes out from what you use internally, which allows you to refactor your internal design without any problems with integration.
public class VehicleWebServiceDto
{
public int vehicle_id;
public string vehicle_name;
public string vehicle_manufacturer;
public DateTime vehicle_manufactured_date;
public int vehicle_number_produced;
}
There’s an issue with using DTOs in an existing web-service environment, it’s unlikely your DTOs will be named the same as your original objects (if they do, you’re fine). We can’t just swap it out with a DTO, because the signatures won’t match in the WSDL.
When we change the web-service to return those DTOs instead of the original classes, we end up with this mismatch in the output:
<vehicle_info>
<vehicle_id>int</vehicle_id>
<vehicle_name>string</vehicle_name>
...
<VehicleWebServiceDto>
<vehicle_id>int</vehicle_id>
<vehicle_name>string</vehicle_name>
...
How can we get around this? Make the signatures match.
You can control the way objects are serialized by the web-service through the serialization attributes; namely the XmlRoot and SoapType attributes are the ones you’re looking for, these allow you to override what name is output in the xml for your class. Slap on those attributes, one for the standard HTTP usage and the other for SOAP, and give them your old class name; then as far as the consumers of the webservice can see, you’re giving them the same old classes. Now you have a separate DTO from your domain layer, but without breaking the schema.
These are the updated DTO objects:
[XmlRoot("vehicle_info"), SoapType("vehicle_info")]
public class VehicleWebServiceDto
{
public int vehicle_id;
public string vehicle_name;
public string vehicle_manufacturer;
public DateTime vehicle_manufactured_date;
public int vehicle_number_produced;
}
Which now produce this xml:
<vehicle_info>
<vehicle_id>int</vehicle_id>
<vehicle_name>string</vehicle_name>
...
We are now free to refactor our code as much as we like, without affecting the output of the web-service.
public class Vehicle
{
public int ID { get; set; }
public string Name { get; set; }
public ManufacturingDetails ManufacturingDetails { get; set; }
}
public class ManufacturingDetails
{
public Manufacturer Manufacturer { get; set; }
public DateTime ManufacturedDate { get; set; }
public int NumberProduced { get; set; }
}
public class Manufacturer
{
public int ID { get; set; }
public string Name { get; set; }
}
Magic.
May 12th, 2008 — .Net, Hobby Projects, Opinion
Making a Visual Studio 2008 plugin isn’t as hard as it sounds.
Making one that works is a bit more difficult.
Syntax highlighting is fairly straight forward, just run a tokenizer over the text and colour code each token appropriately. It’s the code sense that is causing me to go slightly mad. To determine what methods need to be listed when the intellisesne pops up, you need to parse the code that’s in the document, then resolve any classes and references in there to build up a collection of methods to display. It gets more tricky when the document isn’t valid, because you can’t compile it. That’s where I am now, I need to figure out some way of partially compiling the document, or maybe using an AST walker.
May 6th, 2008 — .Net, Code, Hobby Projects
I just posted about how if you’re looking for a solution to a problem that hasn’t already been solved, then you’re probably doing something wrong. Well this is my case of it.
I quite dislike mapping DTOs to entities, it’s a pain, but mostly tedious and tiresome rather than difficult. I decided to try to ease things by creating a library that would resolve entity instances to their DTO counterparts.
My requirements were few but I was determined not to violate any of them.
- Refactoring friendly. No strings for property names, changing names should give compiler errors.
- Must simplify code.
- Must improve maintainability.
First attempt: Explicit mapping
var mapper = new DtoMapper<Customer, CustomerDto>();
mapper.Pair(mapper.Entity.Name, mapper.Dto.CustomerName);
mapper.Pair(mapper.Entity.Address, mapper.Dto.CustomerAddress);
// ... elsewhere ...
CustomerDto dto = mapper.Transform(customer);
With a clever bit of DynamicProxy usage, this implementation successfully mapped properties on an entity to a DTO. I believed it was reasonably clear, but having to use mapper.Entity was a bit obtuse. Dealing with properties on instances without an instance is tricky, especially if you want to avoid using strings.
The explicit mapping is very refactoring friendly. I could rename a property without breaking the mapping, so requirement 1 was satisfied.
var dto = new CustomerDto();
dto.CustomerName = customer.Name;
dto.CustomerAddress = customer.Address;
return dto;
As the above code demonstrates, this implementation isn’t actually any simpler than just doing simple assignments, it’s in-fact more complicated because of the overhead of understanding what the mapper is. This simple assignment method is also refactoring friendly.
So with requirement 2 failed, and requirement 3 no different to doing it manually, it was time to move on.
Second attempt: Implicit mapping
var mapper = new DtoMapper();
mapper.CreateImplicitMap<Customer, CustomerDto>();
// ... elsewhere ...
CustomerDto dto = mapper.Transform(customer);
This is my favorite implementation, it’s clean and smart; however, it’s also useless.
It did the same as the first example, but implicitly mapped any properties that have the same name together. This is fine, but it would ignore anything that don’t have the same names. I could’ve implemented some logic for guessing names, but that would just be asking for trouble.
Tragically this implementation wasn’t that refactoring friendly; you can rename properties, but it would silently stop mapping them unless you renamed it’s partner too. That’s pretty dangerous stuff. Requirement 1 failed.
It does produce less code than the first implementation, and the simple assignment method, so 2 and 3 are covered.
Third attempt: Attributes
public class CustomerDto
{
[DtoPartner(typeof(Customer), "Name")]
public string CustomerName { get; set; }
[DtoPartner(typeof(Customer), "Address")]
public string CustomerAddress { get; set; }
}
I could live with this implementation, it’s not as clean as the implicit method, but it is still quite clear.
Unfortunately, it fails in the refactoring test. You can’t rename a property on Customer without it breaking the mapping, because the property names are strings. Requirement 1 failed.
You could smooth over this with an inspection unit test, which checks the strings against their types to see if the property exists, but that smells, it’s not a very good library if you have to verify it even works. I could’ve also created a static class to represent the Customer instance properties, but that’s more noise (you’d need 3 classes, instead of just 2); a pre-build step (ala SubSonic) came to mind, but that’s entering into the realm of diminished returns.
Conclusion?
Sometimes the obvious way is the best way. Old fashioned may be old, but that doesn’t make it wrong. Sometimes a cigar is just a cigar.
May 6th, 2008 — .Net, Alt.Net, Opinion
If you have a really good idea, and nobody has done it before, chances are there’s a reason for that. It could be that it was technically impossible last time looked at it, but more than likely it’s because you’re trying to solve something that is only present because you’re doing something wrong.
Consider alternatives always before embarking on writing something yourself. In an ever maturing software ecosystem, and the constant catch-up .Net plays with Java, if a solution to your problem was really needed, somebody should have attempted it before.
That’s not to say don’t innovate, but don’t recreate either, and certainly don’t provide solutions to non-existent problems.