# Sunday, 24 July 2011

I’ve been using the MvvmLight Toolkit on a project now for several weeks. At first, the ViewModelLocator pattern the toolkit uses didn’t bother me. But after you wonder why your view can’t be located and then debug everything only to discover that you forgot to create the ViewModel in the ViewModelLocator.

I first thought about switching the ViewModelLocator to inherit from DynamicObject and using MEF to discover the VIewModel’s. A quick search lead me to discover that I’m not the only one to have that same thought Smile

The one thing I didn’t like about using Dynamic and MEF for discovering the ViewModel was the design time experience took a big hit. Locating the ViewModel was now much more expensive at design time.

I started started doing more thinking, and wondered if I could use T4 to generate the ViewModelLocator for me. After more thought, I knew I had to be able to use T4 to generate the ViewModelLocator, heck T4MVC uses it to generate a bunch of helper classes.

Because I’m big on using IoC in my apps, I’ve also added the ability to get the ViewModel from an IoC container if the application isn’t in design mode.

There are two files that are required to make this approach work. ViewModelLocator.tt, and ViewModelLocator.settings.t4. The settings file exists so you can configure the what’s and how’s. If you use the default setup for MvvmLight, the only thing you will have to change is the IoC stuff.

To use the T4 ViewModelLocator, delete your existing ViewModelLocator.cs class in your ViewModel folder, and drop the two T4 files into your ViewModel folder. Once that happens, you will see a new icon show up in the solution explorer called “Transform All Templates.” Click that icon to have your ViewModelLocator automatically generated for you, compile and run Smile

image

Download the T4 templates!

Next time, I’ll write a post about using MEF, DynamicObject and other code to dynamically locator your ViewModels to create a composable application (Wait, didn’t I just say there were performance issues? Yes, but sometimes you have to take the hit).

Please post your thoughts on all this, I would be really interested in hearing other perspectives!

.NET | MVVM | MvvmLight | WPF
Sunday, 24 July 2011 18:59:41 (Alaskan Daylight Time, UTC-08:00)
# Sunday, 07 November 2010

At the Fall 2010 DevConnections keynote, Scott Guthrie demo’d NuGet (formally Nupack). After seeing how easy NuGet makes it to install project references and resolve dependencies, I had to try it!

After installing CTP1 of NuGet and installing a bunch of packages, I found out I needed the latest version (the 10-26-2010 build) in order to install some of the packages I wanted. Well, between CTP1 and the 10-26-2010 build, the NuSpec file format has changed slightly, making packages created with CTP1 and the 10-26-2010 build incompatible.

I decided to pop open a .nupkg (.nupkg the file extension of a NuGet package) package file using 7-Zip (a .nupkg file is really just a .zip file). Inside I saw a .nuspec file.

Opening up the .nuspec file reveals its an xml file. After comparing a CTP1 and a 10-26-2010 build version of a .nuspec file I discovered the only difference is an xml namespace reference.

CTP 1 version of a .nuspec file:

<package>
    <metadata>
        ...

10-26-2010 build version of a .nuspec file:

<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">

It took a few minutes to update all my .nupkg files to the new format and now everything works again!

.NET | HowTo | NuGet
Sunday, 07 November 2010 11:08:09 (Alaskan Standard Time, UTC-09:00)
# Monday, 05 July 2010

For the past week or so, I've been developing a couple of sample apps in Mono with Cocoa on my Mac. In that time, I've struggled quite a bit, and learned quite a bit. One of the biggest things I've learned is things are much harder when you try and mix-in paradimes for which things were not designed.

Take for example NSTableView. Because Objective-C is duck typed, you set Delegate property of your table to this (self in Objective-C) and implement the selectionDidChange method and you will get notified when a row is selected.

Because C# is not duck typed, you have to write a whole lot of ceremony code to get notified when a row is selected. And figuring out that ceremony was a huge battle. I wouldn't have won the war without the help of John Moshakis. Another thing thats not supported is Registering a generic type, or setting a generic .NET type the property of a Cocoa widget.

That means the ceremony code has to be duplicated every time, for every different type of object. I actually tried to make a generic version of my Databinding to an NSTableView blog post, but I was thwarted by an "Invalid IL exception." Hopefully this is just a defect, and not a limitation when dealing with Cocoa.

I would file a defect on this issue with the mono project, but Novell requires you to create an account to add a defect to their bug tracker. I can understand why they want you to do this, but its not a very good way to encourage participation from the community. But I guess it is a particularly good way to discourage drive-by defect reports.

.NET | Mac OS X | Mono | MonoMac
Monday, 05 July 2010 01:28:36 (Alaskan Daylight Time, UTC-08:00)
# Saturday, 03 July 2010

I’ve followed MonoDevelop for a long time. In that time, I’ve seen it go from a barely usable product, to now a fairly capable IDE. Out of the box, it look and acts much like Visual Studio. I do like that that a dedicated unit testing tab is present as a constant reminder that, “Hey, you know you should probably write those unit tests you’ve always talked about writing.”

One thing I was somewhat surprised to not see, at least on the Mac edition of MonoDevelop is a built-in scheme for the VS keybindings. On the down side, I have been able to crash MonoDevelop when I didn’t have some setup code in the right place and I ended up with a null ref trying to talk to some Cocoa widgets.

More to come as I spend more time with MonoDevelop.

.NET | Mono | MonoMac
Saturday, 03 July 2010 08:00:00 (Alaskan Daylight Time, UTC-08:00)
# Friday, 02 July 2010

When Miguel De Icaza first announced MonoMac back in April I was pretty excited! Its been my goal for the past two years to write a half-decent, native looking, Mac OSX application with .NET. I’ve looked at the various Cocoa binding strategies for Mono and always found them lacking. Some like CocoaSharp haven’t been updated in ages, and the WinForms stuff on Mac looked plain fugly. Like Windows 95 fugly.

I found Michael Hutchinson’s quick-start post on writing a simple .NET app using MonoMac. Because I had previous experience using Interface Builder, I was able to muddle my way through building his simple app. But at the end, I wanted something more. “Hello World” is great to show you the most basic syntax of a language, and maybe how to use the compiler, but it honestly does nothing for me.

So, I set out to write real, although somewhat contrived image viewing application. Having an extensive background writing WinForms, ASP.NET and some WPF apps, the hardest part for me was trying to figure out the Cocoa equivalent to things like PictureBox, and FolderBrowserDialog. But Google as always was my friend.

I’m not going to dive into how to write the app tonight, but I will post a screen shot, and the ImageViewer source!
image

Nits

Yes Cocoa is based on an MVC architecture, and yes I should have put some of the code into a business class, but I didn’t.

.NET | C# | Mac OS X | Mono | MonoMac
Friday, 02 July 2010 07:22:00 (Alaskan Daylight Time, UTC-08:00)
# Tuesday, 29 June 2010

A while back, I was tasked with solving a defect in our system. The defect was “Changes to an image can be reverted only one time.”

As I started to look into the code, I saw something like this:

  1. private Image _originalImage;
  2. private Image _image;
  3.  
  4. public void Show(Image image) {
  5. _image = image;
  6. _originalImage = (Image) image.Clone();
  7. }
  8.  
  9. private void Revert() {
  10. _image = _originalImage;
  11. }
 

Looking at the code, I suspected I knew what was wrong, but I wanted to confirm it. So I ran the app, made modifications to the image, clicked revert, made modifications to the image again, set a break point and clicked revert again. Once Visual Studio broke, I popped over to the immediate window and typed this:


&_image
Which returned: 0x1234abd0
&_originalImage
Which also returned: 0x1234abd0

Now I knew what the issue was, the original image was getting clobbered due to a missed .Clone() on line 10. A simple _image = (Image)_originalImage.Clone(); fixed the issue.

.NET | C#
Tuesday, 29 June 2010 06:45:00 (Alaskan Daylight Time, UTC-08:00)
# Friday, 03 April 2009

Background

For a project I'm doing, I have a task model for the various pieces. In the beginning, I was manually creating a List<ITask>. As I kept adding tasks to run, I started thinking about hacking some code together to rifle through my assembly and pull back all the classes which implement ITask.

Then I remember hearing about Managed Extensibility Framework (MEF). I did some searching, found the MEF home page, and even read the MEF overview. But none of that told me what I really wanted to know, what's the fastest way to get started using MEF as a component loader?

I did some more searching and found the dnrTV episode "Glenn Block on MEF, the Managed Extensibility Framework" and after 20-30 minutes they finally got down to how to create a plugin for your app.

But what I really wanted, and I bet a lot of others, is a quick start guide for creating a plugin.

Solution

Download the latest version of MEF, as of this writing its Preview 4. Grab the System.ComponentModel.Composition.dll from the bin folder and stash it somewhere. Make a reference to said dll in your project.

On your plugin class, add Export attribute:

[Export(typeof(IPlugin))]
public class Foo : IPlugin { ... }

In your plugin consumer, create a property to hold your plugins, and add the Import attribute:

[Import(typeof(IPlugin))]
internal IList<IPlugin> _myPlugins { get; set; }

Now, tell MEF where to get the plugins at (line 2), and where you want MEF to fulfill any plugins (line 5):

private void LoadPlugins() { var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); var batch = new CompositionBatch(); batch.AddPart(this); container.Compose(batch); }

 

I put my call to the LoadPlugins method in the constructor.

Now, spin through your plugins and do the work:

Console.WriteLine("Found {0} plugins", _myPlugins.Count);
foreach (var plugin in _myPlugins) {
    Console.WriteLine(plugin.Name);
}

 

Download the complete source to this (really, only about 10 extra lines to glue things together) and have fun!

kick it on DotNetKicks.com
.NET | C# | HowTo | MEF
Friday, 03 April 2009 20:37:33 (Alaskan Standard Time, UTC-09:00)
# Sunday, 15 March 2009

A long time, and many many moons ago I took wrote some code to interface our build server with a network power switch we had laying around the office. We used this to turn on and off lava lamps to indicate the status of the build. Some might ask why we didn't use the X10 support that is already in CCNET, and the answer mostly is cost, and the fact that X10 wouldn't work in our environment.

That was 2.5 years ago. Since then, our team has become more distributed. We have one guy working in Ann Arbor, MI, and occasionally have others telecommuting. So not everyone can see the status of the lamps. Also in the 2.5 years since that code was written, a little thing called Twitter has become very popular. I did some research, and found Tom Fannings nAnt Twitter task and briefly considered using it.

But in the end, I just couldn't resist adding my own developer gold plating and thought it would be neat if we could also issue commands to the build server via tweets. So with that feature in mind, I had to write it myself.

To start out with, I used Yedda's C# Twitter library. The Yedda library is a pleasure to work with, it makes sending a tweet as simple as

new Twitter().UpdateAsXML(_username, password, messsage);

One thing the Yedda library didn't have, was the ability to query for your Twitter replies. A quick look through the source, and the Twitter API docs and I realized this would be trivial. The details of how I did it aren't important to this post, but if your curious, you can look at lines 567 - 627 of the Yedda source included with this post.

I'm not going to dive to much into how the whole project works, but here is a high level. The software runs as a Windows Service, leverages the CCTrayLib assembly for Cruise Control.NET to do all the heavy lifting. It polls the Cruise Control.NET server every 5 seconds, and fires events when things happen. The two events we want are the Polled and BuildOccurred events.

These events allow us to intern kick off our own events based on the state of the build. Based on the state, we grab the appropriate actions to run as defined in the BuildActions.xml file. This maps a build state to a set of actions. In the case of a "Building" action, we send a Twitter, with a message template of "{PROJECT} is building", and turn ports 1 on, and 2 off on our ePower switch. Easy enough.

But how do we take in commands? I pondered this for a minute than realized it would be trivial to leverage the Twitter replies API for this. But what about security, we can't have just anyone sending commands to our build server. This is where the Twitter friends API comes in handy. In order to issue commands to our build server, the account our build server uses has to have you as a friend, not just a follower.

The first action I implemented was the force build command. The idea for the grammar came from a joke reply @orand sent our Twitter bot. After that, I thought it might be nice to be able to get the list of projects, get a projects status, and ask for help. So that leaves us with a total of 4 commands.

A small bunny trail

When I first wrote the command parser, it looked something like this:

if (msg.StartsWith("force build "))
    ProcessForceBuildCommand(msg, user);
else if (msg.StartsWith("get projects"))
    ProcessProjectListsCommand(msg, user);
...

I thought about it for a while, and thought there had to be an easier way. We are using .NET 3.5 after all, with all its lamba, LINQ and new and improved delegate goodness. I did some research and came upon the Action<T> (and Func<T>) delegate type. And came up with this implementation for registering commands

var commands = new Dictionary<string, Action<string, string>>
    {
        {"force build ", ProcessForceBuildCommand},
        {"get projects", ProcessProjectListsCommand},
        {"get project status ", ProcessProjectStatusCommand},
        {"help", ProcessHelpCommand}
    };

Once we have all the commands registered, we can use some lambda and LINQ magic to act upon the commands issued

var key = _commands.Keys.Where(msg.StartsWith).First();
if (!string.IsNullOrEmpty(key))
    _commands[key].Invoke(msg, user);
else
    SendTweet(string.Format("@{0} I'm sorry, I don't understand you. Maybe you should ask for help", user));

Get to the point, I want to see the source code

The code overall is fairly well structured (if I do say so myself), although there is one area where I did violate the separation of concerns rule, the TwitterManager class knows more about Cruise Control.NET than it should. But, given that this is a very simple internal project, and not for public consumption, I'm mostly OK with that :)

I've included the source to our entire build monitor, I hope you find it useful.  We are using a very old version (1.1) of Cruise Control.NET in our environment. If your using a more recent version, you will probably need to swap out the Cruise Control CCTrayLib and Remote assemblies for something more recent, and invert some of the commented out code in the SetupCruiseControl method of BuildServerMonitor.cs

If you have any questions, or find/fix any bugs, please feel free to leave a comment, or send me a tweet, my username on Twitter is akcoder.

Download the Afhcan.BuildMonitor

.NET | C# | HowTo
Sunday, 15 March 2009 19:59:22 (Alaskan Standard Time, UTC-09:00)
# Friday, 20 February 2009

One of our applications has a Windows service in it. To make debugging and running this service easy,we have a winform in the service which can be activated by passing a command line switch. Simple enough. Our service does all its logging with log4net. I wanted to be able to put the output of the logging on our development form, but how?

After looking at various things, I realized what I needed to do was create a log4net appender, and add the appender to the log4net logger and at regular intervals, grab the contents of the logger.

Solution

I created the below appender which uses a StringBuilder as the backing store. It takes in one bool param in the contructor which allows you to specify if you want the log to be built up in reverse.  This is useful if you want to display the most recent event at the top.

public class StringBuilderAppender : log4net.Appender.AppenderSkeleton
{
    private System.Text.StringBuilder _builder = new System.Text.StringBuilder();
    private readonly bool _invert;

    public StringBuilderAppender(bool invert) { _invert = invert; }

    public string Text { get { return _builder.ToString(); } }

    protected override void Append(log4net.Core.LoggingEvent loggingEvent)
    {
        var msg = loggingEvent.RenderedMessage;
        
        if (_invert)
            _builder = new System.Text.StringBuilder().AppendLine(msg).Append(_builder);
        else
            _builder.AppendLine(msg);
    }
}

Now we need to add our new appender to the logger. I found this helper method someone wrote.

public static void AddAppender(string loggerName, IAppender appender)
{
    log4net.ILog log = log4net.LogManager.GetLogger(loggerName);
    log4net.Repository.Hierarchy.Logger l = (log4net.Repository.Hierarchy.Logger)log.Logger;

    l.AddAppender(appender);
}

Finally, lets put it all together:

StringBuilderAppender appender = new StringBuilderAppender(true);
AddAppender("MyLogger", appender);

while(true) {
    System.Threading.Thread.Sleep(5000);
    someControl.Text = appender.Text;
}
.NET | HowTo | Logging
Friday, 20 February 2009 22:18:15 (Alaskan Standard Time, UTC-09:00)
# Tuesday, 10 February 2009

At our organization, we have to globalize our software. Making sure you've gotten all the strings globalized can be a real pain. You have to create a new language resource that looks nothing like your native language, then set the Thread.CurrentThread.CurrentUICulture to the culture of the new language resource you created.  Such a pain.

While pondering that this afternoon, I came upon something better. The .NET CultureManger looks for the most specific resource file, then works its way back to the least specific. For example, given the following resource files:

  • i18n
  • i18n.en
  • i18n.en-US

If your current culture was en-GB, the CultureManger would use the resource file for i18n.en, since there is no i18n.en-GB. But, if your current culture was da-DK, it would use i18n.

In our software, we have i18n, and i18n.da-DK resource files, plus i18n.fr-FR which is a special, internal resource file. What's so special about the fr-FR resource file you ask? The fr-FR resource file is really the i18n resource file which as been transformed to replace all the localized text with dashes.

Why did we do this? Because with all the English text replaced with dashes, it makes it very easy to see which text in the application hasn't been globalized. The down side to this, is we have to change the CurrentUICulture (and CurrentCulture) to fr-FR in order to test this.

Solution

The solution is actually quite simple, rename the fr-FR resource file to i18n.en-US (or what ever the ISO code for your culture is).  Now when your testing, the CultureManager will pick the most specific resource file, and use that. But, don't forget to remove en-US folder from the final build folder before you deploy your application, lest users get your debug language resource.

kick it on DotNetKicks.com
Tuesday, 10 February 2009 14:11:48 (Alaskan Standard Time, UTC-09:00)
# Friday, 09 May 2008

The Problem

For the last few days I've been trying to figure out how to do this SQL in linq:

   1: select from customers where substring(customers.Name, 1, 1) IN ('a', 'b', 'c', 'd');
The problem is the list (a, b, c, d) is variable, on one page I need all the results where foo.Name starts with a or b, on another it could be b, c, d, e and f.  This is trivial to do in SQL, you just break out a little dynamic sql and your done.  But being a noob to LINQ, I'm not so sure how to go about doing this.

I had a lot of failed queries, and failed code, before giving up and just looping through the letters for that particular page and manually building up what I wanted.

But that's kind of a hack. OK, its not kind of a hack, its a big hack.

The Solution

This LINQ goodness (using the Customers db in LINQPad) will pull back all the customers who's names begin with a t, d, or j (note the .ToList() on line 4, I'll discuss it next).

   1: string[] letters = { "t", "d", "j" }; 
   2:  
   3: var customers = (from c in Customers
   4:     select c).ToList(); 
   5:  
   6: var results = from c in customers
   7:     join letter in letters on c.Name.First().ToString().ToUpper() equals letter.ToUpper()
   8:     select c; 
   9:  
  10: customers.Dump("Customers");
  11: results.Dump("Filtered by first letter");

And LINQPad renders this for us:

image

Limitations

LINQ to SQL doesn't support querying a SQL database with if one of your sources is an in-memory store, except if you use the Contains operator.  So, to work around that, you have to pull back ALL the results from the db, and then convert it to a List before you use it in the above query.

I'm my opinion, this is kind of a painful limitation, but for my particular purpose, I'm willing to live with it because my particular database will only ever have around 100 or so rows, so pulling everything back in memory isn't such a big deal...

P.S. if you are reading this in a feed reader, let me know how it renders, I've updated my code snippet plugin to try and fix the previous rendering problems.

.NET | C# | LINQ
Friday, 09 May 2008 01:13:08 (Alaskan Daylight Time, UTC-08:00)
# Sunday, 25 November 2007

Background Information

Aspect Oriented Programming has been on my list of things to read up on for almost a year now.  It likely would have stayed on my list of things to do well into the future if it hadn't been for a recent .NET Rocks episode.  I can't recall if it was the Pablo Castro on Astoria, or the Tim Sneath and Ian Ellison show, but one of them off-hand mentioned PostSharp.  As I usually do when links are thrown about on the show, I scribbled it on my hand for later review. Update DNR just released a show with Gael Fraiteur of PostSharp fame!

Once I got to the PostSharp site, I found their sample video on creating a trace AOP attribute.  They had me hooked.  I wasn't so much interested in doing a logging or trace attribute, but was more interested in doing a few validation attributes.  More specifically a NotNullAttribute.

The Problem

What got me interested in doing the NotNullAttribute was thinking back to how many times in our code base we would have something like this:

1 public void AddUser(Organization org, User user) 2 { 3 if (org == null) 4 throw new ArgumentNullException("org"); 5 if (user == null) 6 throw new ArgumentNullException("user"); 7 8 org.AddUser(user); 9 _ordDal.Save(org); 10 }

Granted this is a somewhat short method, but we have methods which take 6 parameters, and only 2 actual lines of code.  That's 12 lines of code taken up for argument checking, and 2 lines of code.  That would put our crap to code ratio at 6/1.

The Solution

Wouldn't it be much nicer if you could do something like this:

1 public void AddUser([NotNull] Organization org, [NotNull] User user) 2 { 3 org.AddUser(user); 4 _ordDal.Save(org); 5 }

 

PostSharp is almost there to let you write code just like that.  Currently, there is no support for an OnParameterAspectBoundaryAttribute in PostSharp, so we have to do things just slightly differently:

[NotNullHelper] public void AddUser([NotNull] Organization org, [NotNull] User user) { org.AddUser(user); _ordDal.Save(org); }

We have to have a helper class were all the actual code lives.

How PostSharp Works

PostSharp works by weaving all your AOP attributes with your source code after the compiler compiles your code.  This article by Gael Fraiteur describes in more detail how the PostSharp process works.  After the code is post-compiled by PostSharp, you end up with something very ugly that looks like this:

public void AddUser([NotNull] Organization org, [NotNull] User user) { MethodExecutionEventArgs ~laosEventArgs~2; try { object[] ~arguments~1 = new object[] { org, user }; ~laosEventArgs~2 = new MethodExecutionEventArgs(methodof(OrgManager.AddUser, OrgManager), this, ~arguments~1); ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnEntry(~laosEventArgs~2); if (~laosEventArgs~2.FlowBehavior != FlowBehavior.Return) { org.AddUser(user); _orgDal.Save(org); ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnSuccess(~laosEventArgs~2); } } catch (Exception ~exception~0) { ~laosEventArgs~2.Exception = ~exception~0; ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnException(~laosEventArgs~2); switch (~laosEventArgs~2.FlowBehavior) { case FlowBehavior.Continue: case FlowBehavior.Return: return; } throw; } finally { ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnExit(~laosEventArgs~2); } }

I don't know about you, but I would have one HELL of a time trying to debug this, thankfully PostSharp touches up the PDB files, so when your debugging, you only see and debug the source code you've written, both your attribute, and your business logic.

The Drawbacks

PostSharp modifies your code! Well, not directly, but it is still modifying your code (as seen above), but thankfully it touches up the PDB files so all the mess under the hood is hidden from you.

Conclusion

This is but one of the many things you can do with AOP and PostSharp.  Next up, I plan to write some validation attributes.  Look for those in the next few weeks.  In the mean time, download the source code for the NotNullAttribute.

I'm sorry if this post looks terrible in your feed reader, I still haven't been able to figure out why the code looks terrible.  If anyone has any suggestions, let me know.  I'm using DasBlogCE as my blog engine.

kick it on DotNetKicks.com
.NET | AOP | C# | PostSharp
Sunday, 25 November 2007 20:37:23 (Alaskan Standard Time, UTC-09:00)
# Thursday, 13 September 2007

Usually I post solutions I've discovered or created to problems I've encountered.  Now, I've run into a problem with the XmlSerializer and I need your help solving it.  Scroll to the bottom for an update.

The Problem

I have a class called Foobar.  Foobar inherits from List<string>, and contains one member Title.  When I use the XmlSerializer to serialize and deserialize Foobar, all the items in the List are make it through safely, but the member Title does not.

The Code

using System; using System.Collections.Generic; using System.IO; using System.Xml.Serialization; internal class Program { private static void Main() { Foobar f = new Foobar(); f.Add("1"); f.Add("2"); f.Title = "Title"; MemoryStream mem = new MemoryStream(); XmlSerializer xs = new XmlSerializer(typeof(Foobar)); xs.Serialize(mem, f); mem.Seek(0, 0); mem.Seek(0, 0); Foobar deser = (Foobar)xs.Deserialize(mem); Console.WriteLine(deser); } } [Serializable] public class Foobar : List<string> { public string Title; }

The Solution

One way I came up with to solve this problem is make Foobar not inherit from List<string>, and make a member called Items that is a List<string>, but that's kind of hokey.  I've searched Google and can't find a solution.  So I'm appealing to my dear readers for a better solution.

Update

Looks like I was being way to specific in my Google search, searching on "XmlSerializer List" gives us this http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&SiteID=1 as the first item.  In the post,

Elena Kharitidi says "XmlSerializer does not serialize any members if a collection. Only collection items get serialized. This is by design, basically a decision was made to handle collections as arrays not as classes with multiple properties, so collections should look like arrays on the wire, therefore they do not have any members other then collection items, and can be “flattened” by adding the [XmlElement] to the member of the ICollection type."

Long and short, I need to use the hokey solution I came up with (or something like it), or write my own serializer.

Thursday, 13 September 2007 07:22:29 (Alaskan Daylight Time, UTC-08:00)
# Sunday, 26 August 2007

I downloaded the very excellent Resource Refactoring Tool (http://www.codeplex.com/ResourceRefactoring) the other day.  It works great in code files, but I found that it didn't work at all for ASPX/HTML pages.  Seeing this as a challenge, I decided to hack something up in VBA to automatically extract the selected text, create a resx name for the text, add it to the resource file, and insert the ASP.NET literal control.

How to use it

This is split up into two different macro modules, one named Utilities, and the other named what ever you want.  Then add them to your Visual Studio tool bar so you have something convenient you can click on (Right click the tool bar, click Customize, click Commands, then Macros under categories, find what you named the macro and then drag it up to your tool bar.  You can either drag it to an existing tool strip, or create your own.  Finally right click on the item while still in customize mode and add an image).

 

Caller:

Imports System Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics Public Module MoreMacros Public Sub AspTextLiteral() Dim resx as ProjectItem = DTE.ActiveWindow.Object.GetItem("solution\project\folder\ResourceFile.resx") Utilities.AspTextLiteral(resx) End Sub Public Sub InQuoteLiteral() DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate() Dim resx as ProjectItem = DTE.ActiveWindow.Object.GetItem("solution\project\folder\ResourceFile.resx") Utilities.InQuoteLiteral(resx) End Sub End Module

Utilities:

Imports System Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics Imports System.Xml Public Module Utilities Public Sub AspTextLiteral(ByRef resourceFile As ProjectItem) Const literalFormat = "<asp:Literal runat=""server"" Text=""<%$ Resources:{0},{1}%>"" />" Const inQuotesFormat = "<%$ Resources:{0},{1}%>" LiteralReplacer(resourceFile, literalFormat, 4) End Sub Public Sub InQuoteLiteral(ByRef resourceFile As ProjectItem) Const inQuotesFormat = "<%$ Resources:{0},{1}%>" LiteralReplacer(resourceFile, inQuotesFormat, 3) End Sub Private Sub LiteralReplacer(ByRef resourceFile As ProjectItem, ByVal template As String, ByVal delete As Int16) Dim ts As TextSelection = DTE.ActiveDocument.Selection Dim name As String = StripNonAllowedChars(ts.Text).Trim.ToLower Dim value As String = ts.Text Dim path As String = resourceFile.Properties.Item("LocalPath").Value Dim resName As String = System.IO.Path.GetFileNameWithoutExtension(resourceFile.Name) name = AddResourceEntry(path, name, value) ts.Text = String.Format(template, resName, name) DTE.ActiveDocument.Selection.Delete(delete) End Sub 'Returns the value of the name used Public Function AddResourceEntry(ByRef resourceFilePath As String, ByVal name As String, ByVal value As String) As String Dim doc As XmlDocument = New XmlDocument doc.Load(resourceFilePath) 'See if it exists first Dim root As XmlElement = doc.DocumentElement Dim e As XmlElement = root.SelectSingleNode(String.Format("data[@name=""{0}""]", name)) If e Is Nothing Then name = CreateUniqueName(root, name) Dim elem As XmlElement = CreateResourceFileElement(doc, name, value) root.AppendChild(elem) Else If e.SelectSingleNode("value").InnerText.ToLower = value.ToLower Then Return name Else name = CreateUniqueName(root, name) Dim elem As XmlElement = CreateResourceFileElement(doc, name, value) root.AppendChild(elem) End If End If doc.Save(resourceFilePath) Return name End Function Private Function CreateUniqueName(ByRef root As XmlElement, ByVal name As String) As String If IsNumeric(name.Substring(0, 1)) Then name = "n" & name End If 'Name doesn't exist, use it If Not CheckNameExists(root, name) Then Return name End If Dim result As String 'Build a unique name For I As Int16 = 1 To 100 result = name & I If Not CheckNameExists(root, result) Then Return result End If Next Return name & Guid.NewGuid.ToString End Function Private Function CheckNameExists(ByRef root As XmlElement, ByVal name As String) As Boolean Dim e As XmlElement = root.SelectSingleNode(String.Format("data[@name=""{0}""]", name)) Return Not (e Is Nothing) End Function Private Function CreateResourceFileElement(ByRef doc As XmlDocument, ByVal name As String, ByVal value As String) As XmlElement Dim result As XmlElement = doc.CreateElement("data") SetAttribute(result, "name", name) SetAttribute(result, "xml:space", "preserve") Dim valueElem As XmlElement = doc.CreateElement("value") valueElem.InnerText = value result.AppendChild(valueElem) Return result End Function Private Function SetAttribute(ByRef element As XmlElement, ByVal attr As String, ByVal value As String) As XmlElement If element.Attributes.GetNamedItem(attr) Is Nothing Then Dim attrib As XmlAttribute = element.OwnerDocument.CreateAttribute(attr) attrib.Value = value element.Attributes.Append(attrib) Else element.Attributes.Item(attr).Value = value End If Return element End Function Private Function StripNonAllowedChars(ByVal text As String) As String Const non_allowed = """';:,<.>/?\|`~!@#$%^&*()-=+[{]} " For I As Integer = 0 To non_allowed.Length - 1 text = text.Replace(non_allowed(I).ToString, "") Next Return text End Function End Module

 

del.icio.us Tags: , , ,
Sunday, 26 August 2007 20:56:04 (Alaskan Daylight Time, UTC-08:00)
# Tuesday, 23 January 2007

I've started work on the search piece of our application.  Searching (no pun intended) for some inspiration on how users might want to search within our application, I brought up the current WinForms version, and then the ASP.NET version.

I realized that we need to make searching easier in WinForms client, currently when searching for a patient in our WinForms client, you are presented with a separate text box for first name, last name, SSN, date of birth, and health record number.  Our ASP.NET client presents just one text box to search all of those fields.

Tying the Domain Model to the Data Access Layer

So I started thinking about all the pieces in our domain model that we might want to allow the user to search.  Then I realized that to allow searching across all the fields in an entity would tie the data access layer (DAL) to  the domain model ala something like this:

public IList<Patient> Search(string text) { ICriteria criteria = session.CreateCriteria(typeof(Patient)); Disjunction or = Expression.Disjunction(); text = string.Format("%{0}%", text); or.Add(Expression.Like("FirstName", text)); or.Add(Expression.Like("MiddleName", text)); or.Add(Expression.Like("LastName", text)); crit.Add(or); return criteria.List<Patient>(); }

Variations of this code would have to be repeated for every data access class in our DAL.  You could create a string list of the properties on the entity to search and pass them to a method that would build your criteria; but at the end of the day, your still tying your domain model to your data access layer.

Custom Attributes

I started doing some thinking about how unit testing frameworks such as  work and realized I could use .NET custom attributes and some reflection to solve the problem.

I came up with an attribute called Search, currently it takes in one boolean parameter called Enabled.

1 using System; 2 using System.Reflection; 3 4 [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 5 public class SearchAttribute : System.Attribute 6 { 7 public bool Enabled; 8 9 /// <summary></summary> 10 /// </summary> 11 /// <param name="Enabled">if true, property will be included in object-level searches</param> 12 public SearchAttribute(bool Enabled) 13 { 14 this.Enabled = Enabled; 15 } 16 }

I could have written it as:

1 using System; 2 using System.Reflection; 3 4 [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 5 public class SearchAttribute : System.Attribute { }

But I wanted the flexability of adding named parameters in the future.  Who knows, maybe this is a lame reason, and I should just refactor the code if I want to add parameters to it in the future.

Adding the Attribute to Your Domain Model

The interesting thing about a custom attribute, is if it ends in Attribute (i.e. SearchAttribute), its name gets changed to Search by the C# compiler(?), although you could still use SearchAttribute as the name when you add it to your properties.  If you look at the IL, its still called SearchAttribute:

.custom instance void MyNamespace.SearchAttribute::.ctor(bool) = ( bool(true) )

But if you change the attribute name to SearchAttrib, or SearchAttributes, then you have to use the full name when decorating the properties in your class.  This really isn't germane to the topic at hand, I just thought it was neat! :)

Example:

1 public class Patient 2 { 3 [Search(true)] 4 public string FirstName 5 { 6 get { return _firstName; } 7 set { _firstName = value; } 8 } 9 ... 10 }

Pulling it All Together

The custom attribute is great and all, but it doesn't inherently buy us anything.  We need to add a little bit more to make all this work.  This is a simplified version of what I ended up putting in my DAL base class:

1 private IList<Patient> Search(string text) 2 { 3 Type type = typeof(Patient); 4 ICriteria criteria = _session.CreateCriteria(type); 5 6 Disjunction or = Expression.Disjunction(); 7 foreach (PropertyInfo propInfo in type.GetProperties()) 8 { 9 //SearchableAttribute is AllowMultiple = false, so we only need the first item 10 Attribute[] attribs = Attribute.GetCustomAttributes(propInfo, typeof(SearchAttribute)); 11 if (attribs.Length == 0) 12 continue; 13 14 if (((SearchAttribute)attribs[0]).Enabled) 15 or.Add(Expression.InsensitiveLike(propInfo.Name, string.Format("%{0}%", text))); 16 } 17 criteria.Add(or); 18 return criteria.List<T>(); 19 } 20

Again, this is a simplified version of what's in our DAL base class, the actual signature looks more like this: private IList<T> Search<T>(string text) so that I don't have to write a version of this for each class in our domain model I want to enable searching for.

Everything above should be pretty self-explanatory unless you aren't familiar with the NHibernate Criteria API; in which case the Expression.Disjunction bit on line 6 is how you do an OR (a OR b OR c)when searching.  You can also do Expression.Conjunction if you want AND searching (a AND b AND c).

The original version of this code had a second foreach loop which spun through all the attributes on each property looking for the SearchAttribute.  I thought to myself that their had to be a better way and did a little bit of poking around, and discovered much to my delight that the static method Attribute.GetCustomAttributes allows you to specify what kind of attribute you are searching for!

Limitations

In the code above, you'll get an Exception if you try to search against non-text columns in your database so you will need to that into account when putting the Search attribute in your Domain Model; or add some more smarts to the Search method to take into account different data types.

Comments

If you've read down this far, then I'd love to get a comment from you.  Is there anything you think I could do a better job of explaining, am I an awesome guy?  Or do I suck, either way, I'd like to know, so please leave me a comment!

If you like my article, please kick it at .NET Kicks (I have no idea why the kick counter says I have zero kicks btw)!

.NET | C# | NHibernate | ORM | Searching
Tuesday, 23 January 2007 11:02:42 (Alaskan Standard Time, UTC-09:00)
# Thursday, 18 January 2007

We are in the midst of doing a total rewrite of our Software, and one of the things that has come up is date and time.  How do we do it, how do we store it, and how do we ensure that we can compare DateTime from one timezone to DateTime in another timezone.  After a lot of research, we settled on using UTC (or UCT depending on your preference).  FxCop will take care of ensuring we use UTC (for the most part).

That solves the problem, or so we thought.  Turns out, when you create a DateTime object either through the constructor, or through DateTime.Parse, its Kind defaults to DateTimeKind.Unspecified.  We need a way to ensure that all DateTime objects are always set to UTC.

What are our options?

Because we are using NHibernate, we have a few options.  The three NHibernate specific ones that immediately come to mind are using an Interceptor, a custom UserType with a SQL datetime column, and a custom UserType with a SQL varchar column; and the non-NHibernate specific one is creating our own DateTime container.  What are the pros and cons of each of these?

NHibernate Interceptor

Pro: very cross-cutting, can touch every object as it comes in and goes out to the database; if there are other data types we need to monkey with, we already have a framework in place.

Con: Very cross-cutting, can be expensive because it's touching every property on every entity as the entities are loaded and persisted

UserType with SQL datetime column

Pro: Only touching the DateTime objects that we want it to

Con: The type has to be specified for every DateTime object in every mapping file; no meta-data along with the date to stamp in the timezone it was created in

UserType with SQL varchar column

Pro: Only touching the DateTime objects that we want it to; can store the timezone and offset along with the date in the db

Con: Same as above UserType; abusing SQL data types; datetimes created at the same (relative) time in two different timezones won't be sorted correctly

Custom DateTime container

Pro: We can do anything we want

Con: Yuck! - I could write a whole paragraph on why this is yucky, but I'll leave that to your imagination

 

After some thought, I decided on the Interceptor!  Here is the class I came up with (you can also download the complete UtcDateTimeInterceptor class):

1 class UtcDateTimeInterceptor : IInterceptor 2 { 3 public bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types) 4 { 5 ConvertDatabaseDateTimeToUtc(state, types); 6 return true; 7 } 8 9 public bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types) 10 { 11 ConvertLocalDateToUtc(state, types); 12 return true; 13 } 14 15 public bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, 16 IType[] types) 17 { 18 ConvertLocalDateToUtc(currentState, types); 19 return true; 20 } 21 22 private void ConvertLocalDateToUtc(object[] state, IType[] types) 23 { 24 int index = 0; 25 foreach (IType type in types) 26 { 27 if ((type.ReturnedClass == typeof(DateTime)) && state[index] != null && (((DateTime)state[index]).Kind == DateTimeKind.Utc)) 28 { 29 state[index] = ((DateTime)state[index]).ToUniversalTime(); 30 } 31 32 ++index; 33 } 34 } 35 36 private void ConvertDatabaseDateTimeToUtc(object[] state, IType[] types) 37 { 38 int index = 0; 39 foreach (IType type in types) 40 { 41 if ((type.ReturnedClass == typeof(DateTime)) && state[index] != null && (((DateTime)state[index]).Kind == DateTimeKind.Unspecified)) 42 { 43 //Create a new date and assume the value stored in the database is Utc 44 DateTime cur = (DateTime)state[index]; 45 DateTime result = DateTime.SpecifyKind(cur, DateTimeKind.Local); 46 state[index] = result; 47 } 48 49 ++index; 50 } 51 } 52 }

Loading The Entities

For the sake of brevity, I'm going to exclude the bits of the Interceptor interface that aren't relevant to my posting.  With that said, the OnLoad event (line 3) gets fired every time an entity is loaded from the database.  We can count on the fact that all dates are stored as UTC in the database because of stuff we'll do later, so we need to convert the DateTime that NHibernate generates (which has a DateTimeKind of Unspecified) to a UTC date (line 36 - 48).  The types array holds the CLR data type of each property in the entity, and each type in the array contains both the internal NHibernate type, and the CLR type. But we don't really care about how NHibernate maps the data types internally, so we are only interested in type.ReturnedClass.

The first thing we need to do is see if the ReturnedClass is of type DateTime (line 41), if its a DateTime, then we need to see if its null, and finally double check that the Kind on the DateTime object coming back from the database is Unspecified.  This last check is a sanity check, in case this behavior changes in the future.

After all these checks are passed, we need to create a new DateTime object from the old one, and set its Kind to Utc (lines 44 and 45).  Thankfully, DateTime has the built-in method SpecifyKind which will take care of building a DateTime of the specified kind for us. And finally replace the existing DateTime object with our new one (line 46).  Shampoo, rinse, repeat for all the DateTime values in the entity.

Persisting The Entities

Now we can move on to the save and update NHibernate events (line 9, and 15 respectively).  In these, we want to make sure the values being persisted to the datastore are UTC, and that no Local times have slipped through the cracks.  If one were so inclined, they could throw an error instead of converting the DateTime to UTC...

The basic code for converting Local DateTime's to Utc (line 22- 34) is much the same as above, but with a few exceptions.  When we do all our checks (line 27), this time we make sure the DateTimeKind is Local before we perform a conversion operation on it.  It is pointless to check if the Kind is Unspecified, because there is no conversion operation we can really perform on it.  On line 29, we can use the built in DateTime method ToUniversalTime() to convert a LocalTime to UTC.

Finishing Up

How do we wire this all up?  When you open a session on your session factory, you can pass in an Interceptor, this is where you would pass in the UtcDateTimeInterceptor.  eg:

ISession openSession = ourSessionFactory.OpenSession(new UtcDateTimeInterceptor());

I want to give credit where credit is due, I got the actual idea of using an Interceptor from  where he grappled with DateTime, null, messages and web services.  If anyone using NHibernate doesn't read , I would highly encourage you to.  He is a very, very sharp fellow; and prolific blogger.

.NET | C# | NHibernate | ORM
Thursday, 18 January 2007 15:36:52 (Alaskan Standard Time, UTC-09:00)
# Saturday, 30 December 2006

Often times when you're developing an application, there is a one-to-one mapping between your domain model (object model) and your database schema.  Doing it this way often times makes it easier to wrap your head around everything going on in your app.

 

But this isn’t always the right way to do things.  For example, take the highlighted columns in the UserCredential table:


 

In the UserCredential class, do you really want to have HashedPassword, HashType, and PasswordSalt properties?  Probably not...  So, how can we still do our mapping with NHibernate and avoid creating a clunky UserCredential class?  Enter NHibernates CompositeUserTypes!

 

First, let’s create our domain objects:

Notice that the UserCredential class contains a property called Password, which maps to the class Password.

 

Now, let’s create our CompositeUserType, in our case, we’ll call it PasswordCompositeUserType, and this class will implement the NHibernate.IUserType interface:

public class PasswordCompositeUserType : IUserType { public new bool Equals(object x, object y) { if (x == y) return true; if (x == null || y == null) return false; return x.Equals(y); } public object DeepCopy(object value) { if (value == null) return null; else return ((Password)value).Copy(); } public int GetHashCode(object x) { return x.GetHashCode(); } public bool IsMutable { get { return false; } } public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner) { if (rs.IsDBNull(rs.GetOrdinal(names[0])) || rs.GetOrdinal(names[0]) == string.Empty) return null; string hashedPassword = (string)rs[names[0]]; long salt = (long)rs[names[1]]; HashType hashType = (HashType)Enum.Parse(typeof(HashType), (string)rs[names[2]]); Password result = new Password(); result.HashedPassword = hashedPassword; result.Salt = salt; result.HashType = (HashType)Enum.Parse(typeof(HashType), hashType); return result; } public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index) { if (value == null) { ((IDataParameter)cmd.Parameters[index]).Value = null; ((IDataParameter)cmd.Parameters[index + 1]).Value = null; ((IDataParameter)cmd.Parameters[index + 2]).Value = null; } else { Password pass = (Password)value; ((IDataParameter)cmd.Parameters[index]).Value = pass.HashedPassword; ((IDataParameter)cmd.Parameters[index + 1]).Value = pass.Salt; ((IDataParameter)cmd.Parameters[index + 2]).Value = pass.HashType; } } public Type ReturnedType { get { return typeof(Password); } } public global::NHibernate.SqlTypes.SqlType[] SqlTypes { get { global::NHibernate.SqlTypes.SqlType[] types = new global::NHibernate.SqlTypes.SqlType[3]; types[0] = new global::NHibernate.SqlTypes.SqlType(DbType.String); types[1] = new global::NHibernate.SqlTypes.SqlType(DbType.Int64); types[2] = new global::NHibernate.SqlTypes.SqlType(DbType.String); return types; } } }

Looks complicated, but it’s not.  Let’s break it down method by method.

public new bool Equals(object x, object y) – Returns whether object x and y are equal.  Why does it matter?  In our case, it really doesn’t (that I’m aware of); but NHibernate uses this to figure out the relationship between objects in your domain model.

public object DeepCopy(object value) – Creates a deep copy, I’m not sure why NHibernate needs this.  Note, in my implimentation of Password, I created a Copy method.  You could also create a new Password object, set the properties of that new object, and return that as well.  Something like this:

Password p = (Password)value;

Password result = new Password();

result.HashedPassword = p.HashedPassword;

result.HashType = p.HashType;

result.Salt = p.Salt;

return result;

 

I don’t know about you, but I prefer to encapsulate all this into the object itself :).

public int GetHashCode(object x) - Returns the hashcode for the object.

public bool IsMutable – Is this object mutable?  In our case, it doesn’t matter so we return false.

public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner) – This is where a lot of the magic happens :) First thing to do is check if the value from the database is null or empty, if it is, then we can return null and be done.  Second step, grab all the values from the data reader.

This is one of the things I don’t like about NHibernate, you have to get the values out by ordinal value.  Not only by the ordinal value, by in the same order they are mapped in the NHibernate mapping file (more on this later).  And finally, build and return a Password object.

public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index) – This is the other half of the magic :) This code is fairly straight forward so I won’t bother to explain it.

public Type ReturnedType – Tells NHibernate what type of object will be returned by this CompositeUserType.

public global::NHibernate.SqlTypes.SqlType[] SqlTypes – Tells NHibernate what data types of each column is.  Again, the the columns are in ordinal order.  Why “the global::” you might ask?  Well, we have a class called NHibernate in our DataAccessLayer, so the global:: bit tells the C# compiler to backup and look in the global NHibernate namespace.  If you don’t have this issue, you can get rid of the global:: part.

 

Now, onto the Hibernate mapping file:

<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> <class name="MyNamespace.DomainModel.UserCredential, MyNamespace.DomainModel" table="UserCredential" lazy="false"> <id name="Id" column="ID" type="Guid"> <generator class="guid.comb"/> </id> ... <property name="Password" type="MyNamespace.DataAccess.PasswordCompositeUserType, MyNamespace.DataAccess" > <column name="HashedPassword"/> <column name="Salt"/> <column name="HashType"/> </property> <property name="IsActive" /> </class> </hibernate-mapping>

Notice that the column order in the mapping file for our CompositeUserType in our mapping file is in the exact same order as in our PasswordCompositeUserType class.

 

I know this post was very long, but hopefully you found it useful and can adapt it to meet your specific needs!  Next up, using a NHibernate UserType to map the .NET IPAddress class to/from your database.


Questions, comments, please feel free to leave a comment.  This is my first article and I'd like as much feedback as possible!

Saturday, 30 December 2006 23:58:24 (Alaskan Standard Time, UTC-09:00)