.Net Development27 Dec 2010 07:13 am

I moved from Visual Basic to C# when I migrated to .Net back on ’04. I have never regretted this. C# is so much nicer a language in my opinion. One of the things I especially like about C# is its conciseness. I hate typing.

The one and only thing I missed from VB was the WITH statement. It drove me nuts that in C# for all its brevity, if I needed to do half a dozen things with Object.Child.Grandchild.GreatGrandchild, I had to write that whole thing out or put GreatGrandchild in a local variable like so:

Object.Child.Grandchild.GreatGrandchild.Property1 = 1;
Object.Child.Grandchild.GreatGrandchild.Property2 = 2;
Object.Child.Grandchild.GreatGrandchild.Property3 = 3;
Object.Child.Grandchild.GreatGrandchild.Property4 = 4;

The advent of object initializers in C# 3.0 alleviated the primary use case for the With statement. But object initializers don’t do much for the above case or any situation where you have a pre-existing instance.

I recently realized though that I can get 99% of the way there with a combination of two other C# 3.0 features, extension methods and lambda expressions. Putting the two together, I came up with the following method:

public static void With<T>(this T obj, Action<T> action)
{
    action(obj);
}

Which lets me rewrite the example code like this:

Object.Child.Grandchild.GreatGrandchild.With(x =>
    {
        x.Property1 = 1;
        x.Property2 = 2;
        x.Property3 = 3;
        x.Property4 = 4;
    });

Its not perfect and I can see that depending on your stylistic preferences this might drive you nuts, but I think its some very clean code.

Author’s Update:

I recently discovered that Anay Kamat posted a different solution on his blog a way back in ’09. His approach uses reflection and results in a different usage syntax. I recommend you take a look and use whichever approach you like best.

.Net Development20 Sep 2010 06:35 am

I have always had a love/hate relationship with ResXFileCodeGenerator and the StronglyTypedResourceBuilder and the code it generated. Simplified access to string resources and the elimination of string literals in user code is a great thing, but what if I need slightly different generated code? Generated code that you can’t modify is very often a two edged sword.

The only alternative that I have seen offered is to write your own Visual Studio plug in to replace ResXFileCodeGenerator as Dmytro Kryvko has done in his CodeProject article.

I have not had good luck with writing my own VS Pug-ins. All those methods that return object and you have to know what to cast them to, the undocumented property bags, etc. It is just not the kind of framework I like to work with. Moreover, an installed plug-in is harder to use on a distributed team, and what if you want different customizations for different projects?

Stealing shamelessly from the T4MVC template by David Ebbo, my solution to all of this is T4resx.tt. What it does is find all the .resx files in a project and generate output nearly identical to what the Microsoft tools generates. I say nearly identical because, I have of course tweaked it to my liking.

Specific changes I have made:

  • I have neglected to include the attributes marking the code and auto-generated and non-user code. (Since the generated code can now become as complex as you like, its good to be able to step into it.)
  • The accessor members are public vs. internal to make them easy to reference from MVC Views.
  • I have added support for named tokens in the resource strings.
  • I have added support for returning HtmlString wrapped strings.
  • Defined constants for each resource name (for use as attribute parameters such as are needed to work with the validation attributes in the System.ComponentModel.DataAnnotations namespace). These constants are defined in the “Names” inner class within each resource accessor class.

I will talk more about some of these changes below. Many of them are very similar to what Dmytro did in his plug-in. The real advantage to the T4 approach though is that, being a text template, the code is highly accessible to the developer and easily modified to support generating the code that you want. Moreover, each project gets its own template (or you can share one among all projects in a solution if you like). Your are not locked into the same generated code for each project. Lastly, the template is part of the project source code tree so distributing it and keeping it up to date across a team becomes a simple function of source control.

Token Replacement Coolness

The biggest change to the generated code is the ability to do things like this: Create a resource string named OrderSuccessMessage with a value of “Thank you for your order. Your order confirmation number is {OrderNumber}. You will receive an e-mail shortly with this informaiton.” ResXFileCodeGenerator will create a property like so:

public static string OrderSuccessMessage { get { return ... ; } }

The T4resx template will generate the following method:

public static string OrderSuccessMessage(string OrderNumber)  
{ 
    return ... ; 
}

If the string has no tokens in it, the template will generate a property instead of a method. This is because the DataAnnotation validation attributes when used with resource accessor types use reflection to call the member and they expects the member to be a property. This means you cannot embed tokens in resources that are intended to be used by the DataAnnotations framework. But that is okay. How would the framework know what values to provide in the first place?

Support for HTML strings

If a resource string value is prefixed with the token “HTML:”, it is presumed to contain formatted HTML. In this case, you presumably don’t want the MVC framework to encode it. To fix that problem, if the HTML: tag is found, the template strips it off but returns the string wrapped in an HtmlString so that MVC will not HTML encode it. This is very handy for putting bulk page content into a resource and then emitting it as follows:

<%@ Import Namespace="Localized=MyWebSite.Resources.Views.Home.Index" %>
<div id="mainContent">
    <%: Localized.PageConent %>
</div>

Note that the “Localized” alias for the resource accessor class is not part of the template (yet) but is my convention for making things more readable and reduce typing.

Some Caveats

Of course one disadvantage of T4 templates is that, unlike a VS plug in, they are not language independant. My template generates C# code. It wouldn’t take too much to come up with a VB version but if you needed to maintain VB and C# versions, this could be a headache.

Also, because the template emits classes that are named identically to the ones that ResXFileCodeGenerator creates, it is necessary, after creating each resource file in your project, to go into its properties and remove the reference to ResXFileCodeGenerator by clearing the “Custom Tool” property. Otherwise, the two tools will generated competing class declarations and your build will fail.

I find that getting rid of ResXFileCodeGenerator, because it eliminates the plus signs and child .designer.cs files in the solution explorer has the added aethetic advantage of making the solution tree all that much cleaner.

As with most T4 templates, the generated code now becomes a child file of the template itself. So if you want to find the generated code, look for the T4Resx.cs file as a child of the T4Resx.cs file, wherever you put that.

Lastly, this is my first attempt at writing a T4 template. I am very open to critique. Please leave comments.

Future Plans

Eventually, if people like the “Localized” alias convention, I may set the template up to insert these import statements (or using statements as appropriate) in each class for which there is a matching .resx class.

I would also like to add support for tags of the format {AmountDue=decimal:C} where decimal is the type of the input argument into the method and “C” is the string format to use when converting it to text. I am not settled on the best syntax for these tags though.

Another feature I would like to add is the comparison of the default .resx file and localized versions (.de.resx, etc.) to ensure that any tokens specified in the default version are specified in the localized ones. Right now if a token is missing in the localized version, the value passed to the accessor method is simply ignored. Conversely, if the localized resource file contains tokens not in the default file, they are not processed and remain in the returned string.

I thoroughly tested the code generated against all the scenarios outlined by Alexander Adamyan in his thorough article ASP.NET MVC 2 Localization complete guide to make sure I have all the bases covered. Following on his example of subclassing the DisplayName attribute, I am considering subclassing all the DataAnnotation validation attributes to use a by-convention approach to finding the appropriate resource strings. This doesn’t have so much to do with the T4 template itself but it strikes me as a good next step in reducing the redundant code needed to perform localization.

Download the Template

Download the template here: T4resx.zip

.Net Development11 Jun 2010 05:34 pm

I spent a few hours yesterday piecing together the needed code to create a single instance (non-re-entrant) WPF desktop application. There are lots of examples out there of how to do this.  All the ones I could find fall short however, in that, if they detect that a prior instance is open, the just display a message box telling the user that another instance is already running. I wanted something more user friendly, namely to bring the running instance to the foreground. In my experience, this is the expected behavior for non-reentrant applications.

I discovered that the reason all the examples take the easy way out is that it can’t be done in .Net directly. To bring another window to the foreground, you have to make native Win32 API calls. Ugh!

I finally found this worth-while article on how to do what I wanted in WinForms, and combining that with the information found in this StackOverflow post, I updated the solution for Windows Presentation Foundation and encapsulated it all in a the following handy class.

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Interop;
 
namespace SIPC.SLS.ClaimsProcessing.ProcessorWpfApp.Application
{
    internal class SingleInstanceEnforcementUtility : IDisposable
    {
        private Mutex _mutex;
        private Window _mainApplicationWindow;
        private bool _isDisposed;
 
        #region Win32 API Interop
        private const int HWND_BROADCAST = 0xffff;
        private const string UNIQUE_MUTEX_NAME = "{490D60C5-A51C-4c10-ADDE-47B4EECF9EE0}";
        private static readonly int WM_MOVE_TO_TOP = RegisterWindowMessage("WM_MOVE_TO_TOP" + UNIQUE_MUTEX_NAME);
 
        [DllImport("user32")]
        private static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
        [DllImport("user32")]
        private static extern int RegisterWindowMessage(string message);
        #endregion
 
        public void EnforceSingleApplicationInstance()
        {
            bool isOwned;
            _mutex = new Mutex(true, UNIQUE_MUTEX_NAME, out isOwned);
 
            if (isOwned) return;
 
            //Broadcast to all open windows the custom move to top command
            //(Will be ignored by any window that does not recongize it);
            PostMessage((IntPtr)HWND_BROADCAST,
                        WM_MOVE_TO_TOP,
                        IntPtr.Zero,
                        IntPtr.Zero);
 
            Environment.Exit(0);
        }
 
        public void RegisterMainApplicationWindow(Window window)
        {
            //Hook into window message processing loop to watch for our custom message
            _mainApplicationWindow = window;
            var source = PresentationSource.FromVisual(window) as HwndSource;
            if (source != null) source.AddHook(HandleWindowsMessage);
        }
 
        private IntPtr HandleWindowsMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_MOVE_TO_TOP)
                MoveWindowToTopOfDesktop();
 
            return IntPtr.Zero;
        }
 
        private void MoveWindowToTopOfDesktop()
        {
            if (_mainApplicationWindow.WindowState == WindowState.Minimized)
            {
                _mainApplicationWindow.WindowState = WindowState.Normal;
            }
 
            // get our current "TopMost" value
            var top = _mainApplicationWindow.Topmost;
            // make our form jump to the top of everything
            _mainApplicationWindow.Topmost = true;
            // set it back to whatever it was
            _mainApplicationWindow.Topmost = top;
        }
 
        public void Dispose()
        {
            if(_isDisposed) return;
            _isDisposed = true;
 
            if(_mutex != null) _mutex.ReleaseMutex();
        }
    }
}

With this class in place, you can a create a non-reentrant WPF application like so:

[System.STAThreadAttribute()]
static void Main()
{
	using(var sieu = new SingleInstanceEnforcementUtility())
	{
		sieu.EnforceSingleApplicationInstance();
 
		var app = new MyApplication();
		app.InitializeComponent();
 
		sieu.RegisterMainApplicationWindow(app.MainWindow);
 
		app.Run();
	}
}

You will probably also want to change the UNIQUE_MUTEX_NAME, just in case you application ever gets installed on the same machine as mine! 🙂

Happy coding!
–Ken

« Previous PageNext Page »