New Silverlight Theme - JetPack

Update: This blog has been moved to http://brandonzeider.me/2010/microsoft-net/new-silverlight-theme-jetpack/.

The Silverlight team at Microsoft, in conjunction with Pixel Lab, has released a new theme call JetPack. This theme joins the three existing themes: Cosmopolitan, Accent Color and Windows 7.

JetPack Theme Screenshot

JetPack Theme

Links

Demo of the JetPack theme

Download JetPack Theme - Includes resource dictionaries and Visual Studio project templates

Tim Heuer's blog post detailing the release of JetPack

John Papa and Tsitsi Gora on an episode of Silverlight TV detailing how to customize the Silverlight themes.

 

Bookmark and Share dotnetshoutout
Tags: ,
Categories: Microsoft .NET | Silverlight

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (1) Post RSSRSS comment feed

Silverlight 4 Themes

Update: this blog has been moved to http://brandonzeider.me/2010/microsoft-net/silverlight-4-themes/

The Microsoft Silverlight team has put together three Silverlight 4 themes that they are making publicly available. If you're starting a new Silverlight business application, or want to add a consistent look and feel to your existing business application, take a look at these themes. I have found them to be a good starting point, and easily customizable.

As of 8/2010, there are three themes (with more on the way): Accent Color, Windows 7, and Cosmopolitan. You can install the Visual Studio templates, or download the XAML files and include them within your existing project.

Accent Color Theme

Accent Color Theme

This theme focuses on clean styling with a splash of color. Green not your thing? That's ok, the accent color can be easily customized.

Accent Color Demo

Windows 7 Theme

Windows 7 Theme

This theme gives a little more native look and feel to your users (assuming they are using Windows 7).

Window 7 Demo

Cosmopolitan

Cosmopolitan Theme

Inspired by the Metro UX of Windows Phone 7 and Microsoft Zune, this theme has a clean, modern style.

Cosmopolitan Demo

Download

Download Themes

 

Bookmark and Share dotnetshoutout
Tags: ,
Categories: Silverlight

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (2) Post RSSRSS comment feed

WCF Service Call Encapsulation and Abstraction

Update: this blog has been moved to http://brandonzeider.me/2010/microsoft-net/wcf-service-call-encapsulation-and-abstraction/

If you've worked with Windows Communication Foundation (WCF) very long, you know that it's an extremely powerful and flexible platform. Having the ability to consume WCF services in Silverlight makes using Silverlight for your business application much easier. However this does come with a few challenges.

WCF Service Calls Are Asynchronous

All calls to WCF services from Silverlight are asynchronous. This means that to call a service, you must instantiate the generated service client, handle the completed event for the service method you wish to call, call the service method using the generated asynchrouns method, then close the connection using the generated CloseAsync method (which is calling the OnBeginClose method of the ClientBase class).

WCF Service Clients Must Be Explicitly Closed

As mentioned above, after calling a WCF service, you must remember to call the CloseAsync method, otherwise the connection remains open. Even though the generated service client derives from ClientBase, which implements IDisposable, it is not safe to wrap the service client in a using statement and have the IDisposable.Dispose method kill the connection, you must call it explicitly.

Solution

Because of these challenges, and especially if the service is called in more than one class within your Silverlight application (for example more than one viewmodel), you've probably looked for or created a way to encapsulate these service calls and abstract the details of how the service is consumed from the rest of the application. With the aid of generics, we can create a base class that encapsulates the creation of a WCF service client, handling the result of the WCF service call, and closing the connection with IDisposable.

For this example we'll create a simple MathService that allows you to call Add, Subtract, Multiply and Divide. Here's the interface:

using System.ServiceModel;

namespace WcfServiceExample.Web.WCF
{
	[ServiceContract]
	public interface IMathService
	{
		[OperationContract]
		decimal Add(params decimal[] args);

		[OperationContract]
		decimal Multiply(params decimal[] args);

		[OperationContract]
		decimal Subtract(decimal minuend, decimal subtrahend);

		[OperationContract]
		decimal Divide(decimal numerator, decimal denominator);
	}
}

Once our WCF service is working, we can consume this service within our Silverlight application. Within our Silverlight development framework (or wherever you choose), create a base class for all service clients:

using System;
using System.ServiceModel;

namespace Framework.WCF
{
	public abstract class ServiceBase<TClient, TChannel> : ClientBase<TChannel>, IDisposable
		where TClient : ClientBase<TChannel>, new()
		where TChannel : class
	{
		#region Fields
		private readonly TClient _wcfServiceClient = null;
		#endregion Fields

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="ServiceBase<TClient, TChannel>"/> class.
		/// </summary>
		protected ServiceBase()
		{
			_wcfServiceClient = Activator.CreateInstance<TClient>();
		}

		#endregion Constructors

		#region Properties

		/// <summary>
		/// Gets the WCF service client.
		/// </summary>
		/// <value>The WCF service client.</value>
		protected TClient WcfServiceClient { get { return _wcfServiceClient; } }

		#endregion Properties

		#region Methods

		/// <summary>
		/// Handles the result of the WCF service call.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="action">The action.</param>
		/// <param name="result">The result.</param>
		public void HandleResult<T>(Action<T> action, T result)
		{
			if (action != null)
			{
				action(result);
			}
		}

		/// <summary>
		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
		/// </summary>
		public void Dispose()
		{
			if (_wcfServiceClient != null && _wcfServiceClient.State == CommunicationState.Opened)
			{
				try { _wcfServiceClient.InnerChannel.BeginClose(null, null); }
				catch
				{
					_wcfServiceClient.Abort();
					throw;
				}
			}
		}

		#endregion Methods
	}
}

Notice that we are defining the channel and interface with the aid of generics, and closing our connection through the use of IDisposable. Next we can create a concrete class deriving from this base class, passing in the generated service client and interface that we want to abstract.

using System;
using System.Collections.ObjectModel;
using Framework.WCF;

namespace WcfServiceExample.Services
{
	public sealed class MathService : ServiceBase<WebServices.MathService.MathServiceClient, WebServices.MathService.IMathService>
	{
		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="MathService"/> class.
		/// </summary>
		public MathService()
		{
			base.WcfServiceClient.SubtractCompleted += new EventHandler<WebServices.MathService.SubtractCompletedEventArgs>(WcfServiceClient_SubtractCompleted);
		}

		#endregion Constructors

		#region Methods

		/// <summary>
		/// Encapsulates the call to MathServiceClient.Subtract
		/// </summary>
		/// <param name="callback">The callback.</param>
		/// <param name="minuend">The minuend.</param>
		/// <param name="subtrahend">The subtrahend.</param>
		public void Subtract(Action<decimal> callback, decimal minuend, decimal subtrahend)
		{
			WcfServiceClient.SubtractAsync(minuend, subtrahend, callback);
		}

		/// <summary>
		/// Handles the SubtractCompleted event of the WcfServiceClient control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="WebServices.MathService.SubtractCompletedEventArgs"/> instance containing the event data.</param>
		private void WcfServiceClient_SubtractCompleted(object sender, WebServices.MathService.SubtractCompletedEventArgs e)
		{
			base.HandleResult<decimal>(e.UserState as Action<decimal>, e.Result);
		}

		#endregion Methods
	}
}

Now that we have abstracted MathService, it's ready to be used. Here's where our "hard work" pays off. Instead of calling our WCF service the traditional way:

MathServiceClient mathServiceClient = new MathServiceClient();
mathServiceClient.SubtractCompleted += new System.EventHandler<SubtractCompletedEventArgs>(mathServiceClient_SubtractCompleted);
mathServiceClient.SubtractAsync(SubtractXValue, SubtractYValue);
mathServiceClient.CloseAsync();

We can call it this way:

using (MathService service = new MathService())
{
	service.Subtract(HandleSubtractResult, SubtractXValue, SubtractYValue);
}

This is much cleaner, and our viewmodels do not need to know how the service is created, called, closed, etc. The big win in my book, however, is the ability to use IDisposable to close the service channel connection.

Download

WcfServiceExample.zip (534.83 kb)

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.

Bookmark and Share dotnetshoutout
Tags: , , , , ,
Categories: Design Patterns | Microsoft .NET | Silverlight | Windows Communication Foundation

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (2) Post RSSRSS comment feed