Wednesday, June 17, 2009 8:58:18 PM
So I have this semi-fancy Google Android Dev Phone 1. Lately I've been devoting part of my spare time to learning about programming for Android (the OS of the phone). Google (probably because they didn't ask for my opinion and/or input) decided to use Java as the lingua franca for Android programming. If you ask me - and I know you will - they should have used C# and Mono (I might be a bit biased here). Luckily, years ago I had done Java programming, so I wasn't that intimidated by the use of Java on Android.
The first big question that every developer faces is which IDE? There are a few Java IDE's out there, but if you ask me the only ones worth considering are Eclipse and IntelliJ. The documentation for Android points you to using Eclipse. Eclipse is a good IDE. However, back in the day when I was getting paid for Java development, my employer got us all copies of IntelliJ, from JetBrains. I liked it. I like it enough that if I landed a contract tomorrow that involved Java, I'd buy me a copy of IntelliJ.
So, all that being said, I figured I'd give IntelliJ a spin as I travelled down the stack-trace of Android programming. Here are my observations, in general:
- There is an Android plug-in for IntelliJ. Now, you might believe that development on the Android plug is dead. Not true. The plug-in is undergoing active development - it just seems to be kind of slow
- I found the installation of the Android plug-in for IntelliJ far easier than for Eclipse. Just download the most current release, and then unzip to your plugins folder in your IntelliJ installation. With Eclipse, it is simple, but not when the documentation is wrong.
- The IntelliJ plug-in is simple, and seems to get the job done. It's a bit to simple at this time, if you ask me. The ADT for Eclipse provides a far richer dev-centric experience for Android coding. For example there are designers to help you with laying out your form, a lot more control over starting up the Android emulator, and better tooling for hooking up the debugger to either the emulator or an app running on the physical phone.
- Being a Resharper junkie, I found that IntelliJ was more natural for me to use.
- I didn't run into to many problems when I was trying to use/convert Eclipse project with IntelliJ. This is good, because the vast majority (all?) projects I've seen are all Eclipse based.
So, my conclusion at the end of the day, is that I'm going to stick with Eclipse for my Android development. There just seems to be less friction at the moment if you're using Eclipse. In a couple of months maybe I revisit IntelliJ and see what's new with it and Android development. However, at this time, I'd like to really concentrate on learning the Android SDK, and it seems simplest to me right now with Eclipse.
Thursday, June 04, 2009 9:53:24 PM
A while ago I picked up a Microsoft Notebook Mouse 5000. Finally decided to use it on my laptop. I figured that having a bluetooth mouse would mean that I wouldn't have a USB receiver hanging off my laptop all the time. Plus, I thought it would be nice to use Blue Proximity.
Now, the hiccup came when setting up the new mouse on Ubuntu 9.04 64-bit. It seems that you have to do a little bit extra to get the mouse working. I found the solution on the Ubuntu forums. For my one selfish purposes, I will repeat the instructions here:
1) install the bluez-compat package with terminal
sudo apt-get install bluez-compat
2)Pair the mouse with the bluetooth manager. The manager will say that the pairing is "successfull"
Although the mouse won't worked... this step has to be done...
3) In the terminal, type :
sudo hidd --search
You should see something like
Searching ...
Connecting to device 00:XX:XX:XX:XX:XX (your mouse MAC)
Done. Your mouse should be working now.
Saturday, May 23, 2009 7:26:20 PM
For those who have a subscription to CoDe Magazine (and you should) and are interested in getting their feet wet with Mono, you might want to check out the May/June issue.
Wednesday, May 20, 2009 9:50:07 PM
Yes, I'm still alive and kicking. With the weather here trying to warm up, I've been distracted from my usual routine of IT-geek-nerd-technology stuff, hence the long silence. As well, I do find myself largely unmotivated by the whole IT-software development thing in general lately. Probably the weather.
I've been keeping myself pretty busy learning about Android development. Quick summary:
- I will say that I'm like my ADP1, and I'm happy that Roger's will be carrying the G1 and the G2 in just a couple of weeks. I'm thinking very soon phones will kind of disappear, and turn into some sort of Star Trek-ish tricorder/communicator/fashion accessory in short order.
- I'm playing catch up with Java. It's been about 5 years since I last worked with Java so I'm playing catch up to the changes in the JDK world.
- I was using IntelliJ for my IDE, as I really liked using in back in the day when I did Java development. However, the Android plug-in for IntelliJ just didn't seem to smooth over the rough spots enough, especially when you're trying to learn the Android SDK. So, after about two weeks of that, I switched to Eclipse. The ADT plugin for Eclipse makes Android development reduces more of the friction. However, I do believe that IntelliJ is the superior IDE. I'm hoping to put together a more detailed blog post soon, where soon is some time period that I will define as "between now and in the next ten years".
The other side project that is distracting me is I'm trying to build a Mono 2.4 virtual machine for running Mono web apps, ASP.NET MVC in particular. That is really going slow, largely because Android is occupying most of time (it's more shiny and new). If you know of any decent VMware appliances specifically tailored to this, it would be great if you could let me know as this would save me some steps along the way.
Friday, April 24, 2009 2:48:11 PM
Over the Easter long weekend, I experience my own resurrection of sorts. On Thursday just before Easter I noticed that my NAS, a Thecus N3200 Pro with three Seagate Barracuda 7200.11 drives in a RAID5 array, was beeping and displaying a "RAID degraded" message. I didn't worry about it to much, as it was late on Thursday, and I figured I was safe/okay with three drives in a RAID5 array.
So, the next morning I check things out. Turns out all was not well in Whoville. While check the RAID config, I saw that two of the three drives had "warnings" associated with them. This was Not Good. Two out of three failing HDD in a RAID5 array is A Bad Thing. A bit of Googling and conversing with the vendor who sold me the NAS (note- I've got no problems with them, Hard Data has always been great for me for the past six or seven years) and it seems that there is a firmware upgrade for my particular trio of NAS drives. Luckily, I managed to get all my critical stuff off the NAS, so I'm not to worried about data loss.
So, I pull the drives, apply the firmware update, and try to rebuild. The NAS will not let me create a RAID5 array. So, I pull the drives one by one, and then proceed to check them out in a computer. Turns out that the two drives that had the warnings were okay, but the third drive, that was "warning-less" is toast. What is wrong with it I'm not sure, but the BIOS on the computer won't recognize the drive after boot up. Had to RMA the drive back to Seagate.
So, now I sit, alone in my room, without my NAS.
Wednesday, April 01, 2009 7:25:39 AM
Well, I just got an e-mail notifying me that I've been awarded the Microsoft MVP Award for 2009. It pleases me, largely as I get to use the secret roads and facilities that Microsoft acquired when they bought out the Stonecutters a while back. One big change is that my speciality was change from C# to Mono. Who'd have guess that?
Thursday, March 26, 2009 8:42:52 PM
Figured I was due to spend some time setting up a Linux VM and learning how to program my Android Dev Phone 1. Eclipse is what is recommended, so I thought I'd give that a try first. So, with the help of Suse Studio, I quick built myself a VM with Java 1.6 (Aside: I love Suse Studio, I can provision a VM in minutes). I figured it would be pretty straight forward. The docs on the Android Developer site for installing ADT plug-in seem pretty straight forward and simple, and I remember Eclipse having a very rich ecosystem of plug-ins that were easy to install (something I wish Visual Studio had - hint, hint Microsoft).
However, I ran into some hiccups with the provided documentation.
The first annoying one was item #4 in the list for Eclipse 3.4. You're directed to enter the location https://dl-ssl.google.com/android/eclipse/ for the location of the ADT plug in. This did not work for me. The location I had to use was https://dl-ssl.google.com/android/eclipse/site.xml. There is a chance https might not work for you, then use http://dl-ssl.google.com/android/eclipse/site.xml.
After overcoming that hurdle, I tried to do the Hello World sample. This did not work out so well - Eclipse crashed. Turns out that the default packages for Eclipse provided by OpenSUSE doesn't have the Web Standard Tools, which is a requirement for using ADT. So, I went back and uninstalled Eclipse, and download the tarball from the Eclipse website. Then I installed and setup the ADT plug.
Saturday, March 14, 2009 9:54:13 PM
After a bit of tinkering, I managed to provision my ADP1 setup without a SIM card. A bit of google, and here is what I did
- Download the Android SDK. In my case, I unzipped it to C:\android-sdk-windows-1.1_r1.
- Connection the phone via the USB cable to my computer. When the phone asks for a device.
- You'll get the new hardware dialog, when prompted for the drivers, you'll need to specify the location. The Android SDK has the drivers, in my case they were at C:\android-sdk-windows-1.1_r1\usb_driver\x86.
- Once you have the drivers installed cd to c:\android-sdk-windows-1.1_r1\tools.
- Type adb devices. This should list all the Android devices that you have connected. If you don't see any devices listed, then you have a problem.
- Type adb shell. This will direct your commands to your ADP1
- Now while at the adb shell, su to root, then :
- cd /data/data/com.android/providers.settings/databases/
- sqlite3 settings.db
- INSERT INTO system (name, value) VALUES ('device_provisioned', 1);
- .quit
- Reboot the phone
- adb shell
- am start -a android.intent.action.MAIN -n com.android.settings/.Settings
Once all that is done, you should be enable to use your ADP1 as if you had a SIM card in it (we'll except for the phoning part).
Useful link: FAQ: Unlocking/Activating a G1 or ADP1 Without A Sim Card.
Saturday, March 14, 2009 7:27:43 PM
After an uneventful flight from YEG to PSP, I'm settled in with my family. After spending some time with beer at the pool, I'm sitting down with my Android Dev Phone 1 that I ordered last week (ship to PSP).
First impressions: it seems like a nice phone, and I like the fact it has a keyboard. I don't have a SIM card to help with provisioning the phone, so all I get is this message saying "No SIM in phone" and "Emergency call".A quick search on Google tells me that how to get around this and use WiFi. So, that's my task for tonight.
Tomorrow we're heading to the farmer's market at the College of the Desert where I hope to refresh my collection of quality shirts.
Friday, March 13, 2009 7:35:47 PM
I'm off to sunny Palm Springs, California tomorrow to enjoy some time in the sun with my family, and to pick up my Android Dev Phone 1 (screw the US$200 that Brightstar wants for import and brokerage fees).
While I'm down there, I figure it will be a good time to do some serious geeking out. I hope to get a good look at MEF, CodeContracts, Mono 2.4 RC2 & ASP.NET MVC, Android Development, and hopefully level up my Death Knight in World of Warcraft. As well, while I'm down there, I'll be giving an introductory talk on ASP.NET MVC to the Inland Empire .NET User Group on March 17, 2009.
Or, maybe I'll just hangout by the pool, drink, and tweet pictures of me in my bathing suit.
Really, about the only bad thing is that I won't be able to go to the Winnipeg Code Camp this weekend. Maybe next year.
Monday, March 09, 2009 4:40:05 PM
So, it looks like EnergizeIT will be coming to Edmonton at the end of April, April 28th - 30th to be specific. Sounds like it has a range of content for both IT Pros and Developer. Forgive me while I quote the website for details:
"EnergizeIT 2009 is a national series of events to support you in learning what's possible. From sharing innovative solutions, and connecting with peers and local experts you will learn how technology can help you navigate the path for your organization and gain direction to take advantage of the Microsoft platform from the cloud to client."
It also seems like there will be a Windows 7 installfest for those who want to check out Windows 7.

Saturday, February 28, 2009 6:06:26 PM
This session started out with Glenn Block asking what Microsoft can do to support DDD in the .NET framework. It kind of turned into a discussion of what is DDD. Turns out that I was a bit (alot?) misinformed about some concepts of DDD. Here are the notes I made. I have pictures too - those will follow later when I download them from my camera.
Question: Should .NET do anything special to support DDD?
- None of the letters in DDD stand for 'drinking' or 'drunk'. This was pointed out to me by Don, who scoured Seattle for a decent bottle of single malt scotch. The duty free in Edmonton has a not good selection of single malt, IMHO.
- Good persistence mechanism.
- Supporting decorators (Udi admits that this one is a bit of a rabbit hole). You kind of lose the reference when you wrap something with a decorator.
- Allow entities to reference decorators. i.e if you reference the decorator you get the inner type wrapped by the decorator.
- Hydration/dehydration.
- Something like Qi4j (http://www.qi4j.org)
- Entities vs. Value Types. What could .NET do to support ValueTypes
- Immutability. First class citizen like a class or struct, i.e
public valuetype MyValueType { .} or
public immutable class MyValueType { .}
Udi: Most people are abusing "aggregate root". Most people treat aggregate roots as a structural concept. They are not. They are a logical concept or dynamic. They are targeted to a use case, not to the structure of your code. Ask yourself: Has my domain model structured itself and exposed itself in such a way that a single method call on a class will do something?
- If you have done that, then you have an aggregate root.
- It's okay if that method ends up calling other methods
- You only deal with one aggregate root at a time. You can pass in an aggregate root as a parameter. Aggregate roots can reference other other aggregate roots. Ie.
- new Order().CreateFor(myCustomer) or
- var order = myCustomer.CreateOrder()
- Note that one syntax is more natural than the other.
- The big differentiator is the context.
Example:
- Repository.Get<IOrderThatnCanBeCancelled>(id).Cancel()
- IOrderThatCanBeCancelled could still be implemented by the Order class. The Order class could implement many interfaces that describe such actions.
Friday, February 27, 2009 9:15:57 PM
Well, tomorrow I leave a oh-dark-early for Seattle WA. First stop, Redmond for a bit of ALT.NET, and the back to downtown Seattle for the MVP Summit.
View Larger Map
Friday, February 20, 2009 7:06:24 PM
If you using a unit testing framework such as NUnit, you're no doubt familiar with the [Ignore] attribute. (Note: I haven't used MbUnit in a while, but I'm pretty sure that all this applies there as well.) For those who aren't, when you adorn your [Test] with this attribute, then your test runner should pay no heed to this particular [Test]. Instead of going green or red, your test turns up as yellow in your test runner. At first blush, this seems handy - rather than deleting a failing or broken test you can have it [Ignore]d, much like your typical computer geek at a high school dance before the punch get's spiked. Now you can deal with the wayward test on your own time with the pesky failure cluttering up your CI build (you do have a CI build box set up, right?).
Please bear with me while I submit to you: This isn't a good idea. This is a bad idea. An ugly idea. The kind of bad, ugly idea than even Belcham-esque quantities of scotch couldn't make pretty. Why? Well, the whole point to having a unit test is to test something. If your test is failing, that means something is broken. You should be addressing the cause of the failure and dealing with the problem now. Covering up the failure with some attribute kind of defeats the purpose of having the unit test in the first place. I mean, really, if you had open, festering lesions on your skin would you just cover them up with a band-aid and pretend nothing was wrong? Odds are you'd go to a doctor and get that checked out.
Alternately, perhaps the test isn't valid anymore: your application has changed/evolved and the code that you were testing isn't around anymore. Then, get rid of the test! Delete it from your test fixtures, and don't look back.
Granted the world we live in is not black and while. Sometimes we're working on things, and we only want tests to run when it is explicitly asked to run. To handle this scenario, NUnit provides the [Explicit] attribute. This is a kinder, more gentle kind of ignore. This instructs NUnit to only run the test when it is told to run the test. If you add a comment to the attribute, then it helps those going through the build log understand why the test is being run. However it is still possible to run the test if desired.
[Explicit("This test takes a really really really long time to run so we don't want to run it in this test suite every time")]
[Test]
public void My_very_important_test()
{
// Test valuable things here
}
I know some people are going to protest my advice. So I will offer up this one last piece. If you are going to [Ignore] a [Test] then please take advantage of the fact that you can add a comment to the Ignore which will show up when NUnit ignores the test:
[Ignore("This test is ignored as I wish to incur the wrath of Cthulhu (or his proxy)")]
[Test]
public void My_very_important_test()
{
// Test valuable things here.
}
Now when your CI server runs your unit tests, you will have a nice friendly message that will inform others as to why the test is not running.
Thursday, February 05, 2009 8:02:41 PM
Tonight I kicked my kids outside for a couple of hours. I started playing around with AutoMapper, and then realized I chased my kids away without putting on their coats and shoes. So, I called them back in, clothed them, and then got back to checking out AutoMapper. What is AutoMapper?
Last month, Jimmy Bogard announced AutoMapper. AutoMapper is basically a utility that allows you to map from object to object. Where does this come in handy? Well, a lot of the time in DDD, you find that you find yourself using DTO's and such for views or reporting or what have you. A lot of times that means you need to move data from your model objects to the DTO/view-model objects. Usually this isn't a hard task, it's just a lot of typing to create custom mapper. AutoMapper tries to save you from some of this drudgery.
Jimmy already covers all of what I'm about to say in his blog, but this makes it easier for me to reference later on. I've only scratched the surface with AutoMapper, but this will hopefully whet your appetite and you'll check things out for yourself.
So, in my case, I'm working on a little cross platform WinForms app that I call RangeLog. I'm just using it to keep track of my trips to the range: I'd like to know when I went to the range, which firearm I took, and how many rounds I fired, and perhaps some comments. Very simple: it's a form with a grid, and a user control for editing/adding a new trip. The user control has an interface like this:
public interface IRangeTripView
{
DateTime DateOfTrip { get; }
int RoundsFired { get; }
string Firearm { get; }
string Comments { get; }
}
I want to take the values from the user control, and use them to populate a domain object:
public class SimpleRangeTrip
{
public SimpleRangeTrip()
{
ID = Guid.NewGuid();
}
public Guid ID { get; set; }
public DateTime DateOfTrip { get; set; }
public string Comments { get; set; }
public int RoundsFired { get; set; }
public string Firearm { get; set; }
}
Now this is a pretty trivial mapper to code by hand. So, how would one do this with AutoMapper?
First add a reference to the AutoMapper.dll to your project (sorry to belabour the obvious). Then, you configure AutoMapper. In my case, it looks something like this:
1: Mapper.CreateMap<IRangeTripView, SimpleRangeTrip>()
2: .ForMember(x => x.ID, opt => opt.Ignore());
3:
4: Mapper.AssertConfigurationIsValid();
In line #1, we tell AutoMapper that something like this: "Using an instance of IRangeTripView as the source, figure out how to copy the data in it's properties to our target, which will be an instance of SimpleRangeTrip". Automapper is pretty clever - it will automagically try to match properties on the source object to the target object by name. Notice however, that SimpleRangeTrip as one extra property - ID. In line #2 we tell AutoMapper how to handle this issue. In line #2, we tell AutoMapper to ignore SimpleRangeMap.ID when mapping from an IRangeTripView.
Finally, in line #4, we as AutoMapper to confirm that our mappings are valid, that is, all the properties on the source are mapped to corresponding properties on the target. It matches the properties by name, so if you happen to have a misspelled property somewhere or forget to map a property, AutoMapper would throw an AutoMapperConfigurationException.
With configuration out of the way, using AutoMapper is pretty simple:
1: var control = (IRangeTripView) _panel1.Controls.Find("NewRangeTripView", true)[0];
2: var newTrip = Mapper.Map<IRangeTripView, SimpleRangeTrip>(control);
In line #1 we get a reference to our user control. In line #2, AutoMapper takes our user control and returns a new SimpleRangeTrip object using the values from the user control.
Nice, neat, and simple.
The AutoMapper homepage is on CodePlex : http://www.codeplex.com/AutoMapper. There is a mailing list at: http://groups.google.com/group/automapper-users. You can get the source code from: http://code.google.com/p/automapperhome/. AutoMapper is licensed under the Apache 2.0 License.