| More
.NET
 


Using Extension Methods to Improve & Simplify Type Conversion in .Net

As the .NET platform has evolved, languages like C# and VB.NET have introduced more and more features to improve the compile-time type safety of the code we write. Features like generics, custom conversion operators, and now co- and contra-variance make it easier than ever before to write code that the compiler can examine for type errors. With each new release, more and more of these features also find their way into the .NET framework classes.

Even in .Net 4, every now and then you run across a situation where type conversion rears it's ugly head and we have to revert to writing code that requires runtime casts. One such situation is when you write code that uses the ADO.NET classes and interfaces - particularly DataTable and IDataReader. Matters can get even worse when we don't know (or don't correctly anticipate) the type of value returned in a given call. If we don't tread carefully here, we can easily encounter runtime errors. Look at the following innocuous bit of code:

var connection = new OracleConnection("Data Source=DEV;");
IDbCommand cmd = new OracleCommand("SELECT 1.85 AS AGE FROM DUAL", connection);
connection.Open();

double age = (double) cmd.ExecuteScalar();

While this looks like it should work, if we actually run it we get:

System.InvalidCastException: Specified cast is not valid.

Clearly, that's not what we want. What's happening here is that Oracle returns a decimal here rather than a double. ExecuteScalar() returns object, and it's illegal to try to unbox a value of one type into a variable of a different type, even if a conversion exists between the two types. While this is a common point of confusion in C#, there is a straight-forward solution - perform the cast in two steps:

double age = (double)(decimal) cmd.ExecuteScalar();

An alternative approach is to use the Convert class:

double age = Convert.ToDouble( cmd.ExecuteScalar() );

Convert will do all of the necessary runtime checks to figure out what type we're dealing with, and will return an appropriately-typed result. Convert.ToDouble() will even work if the value passed in is a string:

IDbCommand cmd = new OracleCommand("SELECT '1.85' AS AGE FROM DUAL", connection);
double age = Convert.ToDouble( cmd.ExecuteScalar() );

Convert is nice, but it does have it's limitations. Among them are:

  1. It can't convert to or from nullable types (int?, double?, DateTime?)
  2. It can't convert DBNull values, which are often encountered in ADO.NET
  3. It doesn't handle conversions to or from enum types
  4. It offers no ability to supply a default value when dealing with nulls
  5. It isn't much less verbose than the straight-forward casting syntax

We can do better than this. In fact, we're going to create a set of extension methods that will make it simpler, easier, and cleaner to perform runtime conversion of types, and we're going to address the limitations above along the way.

Show me the code! All right, down to business. The following listing shows the complete source for our conversion utility class. The class is marked as static to allow it to define a number of extension methods.

public static class ConvertExtesions
{
// converts the source object variable value to the desired result type
public static TR ChangeType<TR>( this object value ) { return (TR)ChangeType(value, typeof(TR)); }

// converts the source value, and if null returns the specified default value public static TR ChangeType<TR>( this object value, TR whenNull ) { return (value == null || value is DBNull)
? whenNull
: (TR)ChangeType(value, typeof(TR)); } public static object ChangeType( this object value, Type convertToType ) { if ( convertToType == null )
{
throw new ArgumentNullException("convertToType");
}

// return null if the value is null or DBNull
if( value == null || value is DBNull )
{
return null;
} // non-nullable types, which are not supported by Convert.ChangeType(), // unwrap the types to determine the underlying time if (convertToType.IsGenericType &&
convertToType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{ convertToType = Nullable.GetUnderlyingType(convertToType);
} // deal with conversion to enum types when input is a string if (convertToType.IsEnum && value is string) { return Enum.Parse(convertToType, value as string); }

// deal with conversion to enum types when input is a integral primitive
if (value != null && convertToType.IsEnum && value.GetType().IsPrimitive && !(value is bool) && !(value is char) && !(value is float) && !(value is double) ) { return Enum.ToObject(convertToType, value); }
// use Convert.ChangeType() to do all other conversions
return Convert.ChangeType(value, convertToType, CultureInfo.InvariantCulture); } }

We're going to break down and examine the code in a moment. But first, let's see how this makes our earlier example better. The same code from before can now be written as:

double age = cmd.ExecuteScalar().ChangeType<double>();

We can even substitute null values with defaults gracefully:

double age = cmd.ExecuteScalar().ChangeType( 0.0d ); // return 0.0 when null

Nullable types are no obstacle either:

double? age = cmd.ExecuteScalar().ChangeType<double?>();

Don't know the type at compile time? Not a problem:

object age = cmd.ExecuteScalar().ChangeType( Type.GetType("System.Double") );

Strings and integral values can now also be converted to enums:

enum CompareResult
{
    LessThan,
    EqualTo,
    GreaterThan,
}

IDbCommand cmd = new OracleCommand("SELECT 'EqualTo' AS CR FROM DUAL", connection);


CompareResult age = cmd.ExecuteScalar().ChangeType<CompareResult>();

So, how did we make this all possible? Let's take a look at the implementation of the CompareExtensions class. The first two overloads of ChangeType<> are:

public static TR ChangeType<TR>( this object value );
public static TR ChangeType<TR>( this object value, TR whenNull );

In all overloads, TR is the type of the result that will be returned. The first overload accepts any object will attempt to convert it to the type TR. Because the type parameter only appears in the output position it cannot be inferred for us - which requires that we supply it:

int valueAsInt = "12345".ChangeType<int>();

The second overload accepts a default value parameter to return if the conversion fails. By making the type of the default value parameter TR we also allow the compiler to infer the type of the return value from the default, which means we can omit the explicit type argument list:

object value = null;
int result = value.ChangeType(-1); // TR is inferred here...

Neither the first or second overloads do much work, the second performs a bit of null checking as a shortcut - but otherwise, both simply delegate to the third overload. That's where all the real work happens.

The third overload of ChangeType() looks like:

public static object ChangeType( this object value, Type convertToType )

You probably notice that this overload is not, in fact, generic. This allows it to be used in situations where the type we are converting to is not known at compile time but only at runtime. The very first step of this method:

if( convertToType == null ) { throw new ArgumentNullException("convertToType"); }

ensures that there's always a Type to which we will try to convert the value to. Next, we check if the value is null or DBNull, in which case the converted value will always be null, so we just return that:

if( value == null || value is DBNull ) { return null; }

Otherwise, we check if the type we're converting to is a nullable type - in which case we really need to perform a conversion to the type that underlies the nullable type. We determine this by using the Nullable.GetUnderlyingType() method, and set that as the type we are actually converting to.

if (convertToType.IsGenericType && 
    convertToType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
    convertToType = Nullable.GetUnderlyingType(convertToType);
}

The next step is to check if we are converting from a string representation to an enum representation, and if so, use Enum.Parse() to convert the value. Otherwise, we also need to check if we are converting from a primitive type to an enum representation:

if (value != null && convertToType.IsEnum && value.GetType().IsPrimitive &&
   !(value is bool) && !(value is char) && !(value is float) && !(value is double) )
{
    return Enum.ToObject(convertToType, value);
}

Here we should note that for such a conversion to be possible, the incoming value must not be null and must be one of the integral types other than char: byte, sbyte, short, ushort, int, uint, long, ulong). If this is the case, we use Enum.ToObject() to convert and return the result.

Finally, if no other case holds, we just delegate to Convert.ChangeType() to do all other conversion processing, and return its result.

And there you have it. Let's wrap things up and look at what we've figured out:

  1. Casting can be a tricky business, particularly when you don't know (or can't always know) the types you are converting from at compile time.
  2. You encounter runtime exceptions if you try to unbox a value from an object to a type other than what is actually boxed, even if a conversion exists.
  3. The Convert class provides a helpful suite of methods for runtime conversion, including the flexible ChangeType() method.
  4. Convert has a number of limitations - it doesn't deal with nullable types, DBNull, or enums, and it doesn't allow us to specify a default value for nulls.
  5. Using extension methods and type inference, we can create our own flexible conversion utility that overcome the limitations of ChangeType, and simplifies the syntax of runtime type conversion.

Posted by: Leo Bushkin
Posted on: 7/6/2010 at 5:33 PM
Tags:
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Ignoring Users and Roles On Deployment using VS2010 DB Project

I have run into this problem a couple times now:

The problem: Using a Visual Studio database project, I want to ignore users and roles on deployment AND keep the "Generate Drop statements for objects that are in the target database  but that are not in the database project" option checked.

There is no configurable way of doing this during the deploy with VS2010 (and earlier).  Please note that that is my post above and I am note shamelessly plagiarizing someone else's work!

A little background:  I am a consultant and have introduced this tool (visual studio database projects) to several customers.  Developers tend to like it and DBAs are on the wall (at best).  The DBAs don't care how developers create sprocs, tables, indexes and such but they want absolute control over users and roles and I frankly don?t blame them.  While I would certainly like to see this capability added, here is what I have done to deal with users and roles (bare in mind for this scenario I need to use a deploy, schema compare does offer some nice alternatives if that is not the case):

The environment: We have a development, test, and production environment.  We (QA and developers) prove things out in the dev environment, we promote the code and DB changes to Test for more QA and BA scrutiny, and when all tests have passed we promote to production.  This is a very typical process I see from customer to customer.

Developers have full access to the dev environment, limited (read only) access to test, and no access to production.  In other words, each environment has a different set of users and roles but we, of course, want to use the same database project for each environment. Oh and we do want to use the "generate drop statements" option to help manage our changes (dropping a sproc, index, whatever...).

The solution: Because we want to make the production script as clean as possible we synch the database project with a copy of the production database minus any confidential information (which is not trivial to do).  The project, therefore, contains all of the production users and roles (but none of the development and test users or roles).  If the production users tend to be static, deploying changes to production will create a script without create user and modify role statements which is something the DBAs demand of the production update scripts. If the users and roles in production are more dynamic we have to either work with the DBA to manage user/role scripts in the project at the same time they are changed in production (assuming they prefer to add users without using Visual Studio) or we have to add a step to our process to synch the users and roles with production before we create the final deploy to production script.  Using this process means our deploy to production scripts are nice and clean and void of any user and role changes - our primary goal is satisfied.

The down side of synching to production is that the development or test deploy script will generate "create user" and add rolemember statements for production users that we don?t want in the database and it will generate drop user statements for the users we do want in the dev and test environment .  Remember the users we have in the project only map to the users in production.  Well this is not the end of the world; it just means that we have some post deployment work to do.  We add a post deploy script to the project that is responsible for dropping all (production) users that the script created for us and adding the dev or test users and role membership.
The script we deploy to say dev might look something like this:

USE [$(DatabaseName)]

GO

 Pre-Deployment Script Template  
...

The VS generated script

CREATE USER [domain\ProdUser1] FOR LOGIN [domain\ProdUser1];
GO
PRINT N'Creating [domain\ProdUser1]...';
GO
CREATE USER [domain\ProdUser2] FOR LOGIN [domain\ProdUser2];
GO
EXECUTE sp_addrolemember @rolename = N'DataReader', @membername = N'domain\ProdUser1';
GO
EXECUTE sp_addrolemember @rolename = N'DataReader', @membername = N'domain\ProdUser2';
GO
DROP USER [domain\Dev1];
GO
DROP USER [domain\Dev2] ; 
GO 
Alter table, drop sproc...
GO

Post-Deployment Script 

IF (@@servername = 'DevDBServerName' )
begin

CREATE USER [domain\Dev1] FOR LOGIN [domain\Dev1];
CREATE USER [domain\Dev1] FOR LOGIN [domain\Dev2];
EXECUTE sp_addrolemember @rolename = N'DataReader', @membername = N'domain\Dev1';
EXECUTE sp_addrolemember @rolename = N'DataReader', @membername = N'domain\Dev2';';
EXECUTE sp_addrolemember @rolename = N'DataWriter', @membername = N'domain\Dev1';
EXECUTE sp_addrolemember @rolename = N'DataWriter', @membername = N'domain\Dev2';';
...
end

IF (@@servername = 'TestDBServerName' )
begin
CREATE USER [domain\Dev1] FOR LOGIN [domain\Dev1];
CREATE USER [domain\Dev1] FOR LOGIN [domain\Dev2];
EXECUTE sp_addrolemember @rolename = N'DataReader', @membername = N'domain\Dev1';
EXECUTE sp_addrolemember @rolename = N'DataReader', @membername = N'domain\Dev2';';
...

end

I would love to hear how others manage this problem, drop me a comment if you are willing to share.


Posted by: Tim Star
Posted on: 6/24/2010 at 5:27 PM
Tags: , ,
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

.NET WCF vs. Java JAX-WS and JAX-RS

by Jim White (Intertech Director of Training and Instructor)

I attended fellow instructor Andrew Troelsen?s Complete Windows Communication Foundation (WCF) class last week (recently updated for .NET 4.0). Andrew is a gifted teacher with a deep deep knowledge of .NET. If you want to learn anything about .NET, you really need to take a class from Andrew. Regardless of the topic, you are going to learn more in a day with Andrew than you will reading an entire library of books on your own. For those not aware, WCF is Microsoft?s relatively new service oriented framework. In Java, this would be equivalent to your JAX-WS and JAX-RS more on that in a bit APIs.

If you had to put me in one of the software-centricities today, I guess you would say I am a ?Java developer.? I have been doing Java for over 14 years. However, I have recently ?crossed to the dark side? (as some of my Java friends would say) as I am participating in and leading Intertech?s Cloud Computing efforts ? most notably with Windows Azure (Microsoft?s cloud platform). WCF is at the heart of a lot of Azure capabilities and APIs. I took Andrew?s class to get better insight into this Azure foundational element.

However, as a Java developer, I was also curious to see how the other world treated SOA and Web services. When writing interoperable Web services or consumer applications, I am always very curious how non-Java applications might work with my Java service or Java consumer. After all, SOA and Web services are all about interoperability.  This week?s class gave me a much better appreciation for that, at least from the current Microsoft stack. Below, I have provided a kind of compare and contrast look at how Java and .NET provide developers with tools and APIs for wresting with services. For those that spend a lot of time in SOA worlds, I hope you find the discussion encouraging. The point of this post is not to highlight the differences, but to really spotlight the fact that the two have to address many of the same issues and are therefore more alike than you might think. In other words, there is more that binds us (pun intended) than separates us.

First, some of the differences I saw. Note, ?differences? doesn?t not mean better or worse ? just different.

Support for Multiple Bindings

Java has an API for everything. Unfortunately, that means for each job, you need a different API. The JAX-WS API provides a great environment for writing interoperable SOAP-based Web Services and Web Service Clients. What if you need to communicate Java-to-Java using a different (more Java centric) protocol? Well, then it?s probably another distributed technology API (like RMI or EJB) that you probably want to explore ? at least if you want the performance and Java objects passed around. Want to do REST in Java? You need JAX-RS. In the .NET world, its WCF - period. In fact, what I was impressed with is that WCF has taken over as the communications framework in the Microsoft camps. Gone (not deprecated, but certainly relegated to legacy support) are .NET Remoting, ASP.NET web services, and other such APIs. Everything is now WCF. .NET to .NET, or .NET to Java using SOAP, it?s all the same. WCF offers multiple bindings. Bindings dictate the protocols, encoding mechanisms, and the transport layer used between consumers and service providers. What?s more, when you write a WCF service, the code doesn?t know or care what binding you choose. The binding is taken care of through configuration and hosting operations. In class, we wrote simple services in our lab that ran SOAP over HTTP in one minute and in TCP or named-pipe, .NET-centric fashion the next minute. Java wonks will argue you can do multiple bindings with Java APIs too. Yes you can, just like I can cut my yard with scissors ? doesn?t mean I want to or that it?s a good idea either.

WCF Host vs. the App Server

In Java, you typically create your service as a simple Java object (POJO or plain old Java object as it is know) and hand it off (with some configuration) to a Java application server/container to do the rest of the work. While Java services (like those produced in JAX-WS) can run in multiple environments, by and large, they are really engineered to be simply packaged and deployed into a managed Java runtime container (a Java application server). Nicely, the container manages the lifecycle of the service, routes traffic to and from the service, and generally handles all the details of the service as it is deployed and running. In the WCF, once you have created the service (which is also just a simple object), your work may only be half done. Now, you need to pick and possibly build its host environment. You can choose something like IIS to host the service (your job is now simpler) or you may choose to have a custom Windows service, or console application, Windows Server (through Windows Activation Service) host your service objects. Some choices will require you to write the code that essentially manages your service at runtime. Other options just need some configuration. Choices are good.  Allowing for you to pick how and what manages the life of your service.  However, choices can also lead to some complexity. I can see that making the wrong choice (or coding the host inappropriately) could lead to some issues (like poor service performance).

To be fair and honest, as those in the Java community know, running in an application container is not always a picnic - i.e. seamless or easy.  Your Java Web services don't always deploy simply or easily in containers as it often requires special libraries and/or configuration.  In fact, there is even a JSR (JSR-109) that attempts to address the deployment issue interoperable Web services.

Development Approaches (top-down, bottom up)

As Java?s main Web service stack (JAX-WS) is all about interoperable SOAP-based Web services, it should come as no surprise that the IDEs, tools, and API support both top-down (a.k.a. WSDL or contract first) and bottom-up (a.k.a. code first) approaches to building Web services. I?ll leave the pros/cons of both approaches to material you can find on the Internet. However, both are supported with neither relegated to an ?alternate approach? status. While you can do top-down service development in WCF, you need to use a command prompt tool (SvcUtil) to generate code from the WSDL and related schema documents. This seemed a bit kludgey to me. I am sure the tool works fine and once you are used to working with it, you can make it do all sorts of neat tricks. However, when I have a WSDL URL, I?d like to point my IDE to the WSDL and say ? go generate skeleton code for my new service. I didn?t see anything like that in WCF, which leads me to feel that the top-down approach is relegated to second class status in .NET. However, remember again that WCF deals with multi-bindings and the service code itself doesn?t know or care that it is doing SOAP or .NET binary. Top-down development is about using a contract to drive development of consumers and services. In an all .NET world, a top-down contract approach probably isn?t going to be an option (no WSDL to leverage there).

REST

Formal REST support is something added to WCF with the latest release (.NET 4.0). Frankly, it kind of looks like it was added recently.  For example, a number of configuration simplifications were made for "normal" services in .NET 4.0.  However, RESTful Web services must use the older form of configuration.  Further, the WCF templates in Visual Studio 2010 may still require a few reference updates and configuration changes when creating a RESTful service project.  These are minor issues, and I think we can all presume that things will be better and different in a future release of WCF.  However, WCF is the framework for any type of "communications" - REST or otherwise.  So again, when building a service using WCF, you can create a simple class that performs some sort of offering and you can make it available as a Web service, .NET named-pipe, or RESTful Web service all with the same framework.  Java's RESTful API (JAX-RS which is relatively young itself) is a separate API (and implementation) from its other service types (notably JAX-WS).  While it might be possible to have a class implement both JAX-WS and JAX-RS simultaneously, you are really talking about two different frameworks and two APIs for Java Web vs. RESTful services.

Security

WCF leverages Microsoft's Role Based Security system for most in-house (.NET to .NET) types of services.  This makes security slick and easy for service providers and consumers.  The API for determining who is the caller and what access they have is built into the API as well as a declarative model that makes securing services pretty easy.  For externally facing services, authentication and authorization are, like Java, a bit more manual (generating, handling and passing credentials and/or certificates in the message), and takes a bit more work on the part of the service provider/consumer to setup.  However, WCF applications can leverage the SQL Membership Provider API.  The SQL Membership Provider API, for non-.NET developers, is an auto-generated custom database (at runtime) for registering users and granting access.

Proxy API

In both Java and WCF, proxy classes are generated for the consumer developer.  The proxy makes communicating with the service easy and abstracts away the details of the protocol being used or even the fact that it is distributed computing going on.  Working with a WCF proxy is so simple, as they say in the commercials, even a caveman can do it.

BasicMathClient proxy = new BasicMathClient();
Console.WriteLine("1 + 1 = {0}", proxy.Add(1, 1));
proxy.Close();

In Java, there are actually two types of proxies.  Using the dynamic proxy client (a generated proxy), is very similar to using the WCF proxy.  I think JAX-WS client proxy coding is a bit more complex, but also offers the ability (in theory) to use different ports on the service (e.g. SOAP vs. RMI). 

BasicMathService service = new BasicMathService();
BasicMath port - service.getBasicMathSOAPPort();
System.out.println("1 + 1 = " + port.Add(1,1));

Java also offers the Dispatch Client.  This client requires more work (a lot more work), but allows the developer to have more direct control of the raw message (typically SOAP).

More That's The Same Than Different

As mentioned, there is really more that is similar between Java and .NET's Web service frameworks than is different.

Services as Simple Classes

Both rely on objects that come from simple classes dictated by interfaces for implementing services.  Plain old Java, C#, or VB objects are running the SOA world!  In fact, I even found it interesting that both environments encourage but do not require the use of an interface for defining the service.  Of course, services can contain complex logic and complex calls to other classes to get business done, but the service structure itself is simple and easy to understand.

Annotations or Attributes

Both rely on metadata (Annotations in Java and Attributes in .NET) to demarcate the service, its operations, and much of its runtime behavior.  Its fun to see that there is almost a one-to-one correspondence in the metadata tags in both worlds.  If you were a Java developers, I dare say you could pick up a C# Web service and translate it into Java code with only a little assistance.  And of course the opposite holds true for .NET developers.

//C# attributes
[ServiceContract]
public class ServiceTypeAsContract
{
[OperationContract]
public void SomeMethod() { /* Some interesting code. */ }
[OperationContract(IsOneWay = true)]
public void AnotherMethod() { /* Some interesting code. */ }
}
//Java annotations
@WebService
public class ServiceTypeAsContract
{
@WebMethod
public void SomeMethod() { /* Some interesting code. */ }
@WebMethod
@OneWay
public void AnotherMethod() { /* Some interesting code. */ }
}

Serialization/Deserialization

The frameworks are largely responsible for the creation of the request and response messages and marshalling/unmarshalling data to the applications.  The days of manipulating raw XML, JSON, or other formatted requests and responses are over in any language.  Let the framework do the grunge work of distributed communications and data formatting. 

WS-* and WS-I adherence

Both Java (JAX-WS) and WCF are now fully WS-I compliant.  This is good news for everyone.  While you can certainly use annotations/attributes or configuration to construct non-interoperable services, it requires work (and presumably acknowledgement on your part) to implement only for a certain platform.  There are still many gotchas in Web service interoperability, but developers now have a fighting chance of making things work with other platforms without having to know every detail about the other platforms.

Exceptions as faults

Both WCF and the Java frameworks translate language exceptions into faults.  Both provide a similar means of creating application specific faults that can contain more details about what went wrong to the client.

Filters vs. Channel

Both the Java frameworks and WCF provide for pre and post processes to operate on in bound and out bound messages at both the consumer and service provider levels.  They have different names, but provide similar capability to alter the message on the way to and from its destination and even to alter message flow under the right circumstances (say authentication failure).  In Java, these processes are called handlers.  In .NET/WCF they are called channels, but they serve the same general purpose.

I am sure a more experienced practitioner in both the Java and .NET SOA worlds can provide you with more detailed and better comparisons than I have here.  Hopefully, you get the idea that the software community is more united in its approach to SOA than divided - at least when it needs to be.  Sure, you can write applications in Java or C# that just need to communicate with their ilk and then things often get simpler.  But the design, patterns and approach to building services, no matter the platform, is starting to get more similar and that's good news for everyone.

Sign up today for Complete WCF or Complete Java Web Services to learn more about SOA in any environment.


Posted by: Jim White
Posted on: 6/21/2010 at 11:38 AM
Tags: , , , , , ,
Categories: .NET | Java | General | SOA/Web Services
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

The Role of, and Need For, Blend

When WPF first appeared on the programming landscape, (and once SL moved to version 2.0 and became something we could be proud of), it was clear that typing gobs of XML was in our future. 

Now, if you are anything like me, you may have thought that you could muddle through and simply leverage Visual Studio has you XAML editor of choice.  While you COULD do so, you would soon get massive hand cramps, as earlier versions of VS had very limited support for XAML editing, beyond simple code completion. 

Now that Visual Studio 2010 is here, many folks assume that this version of the IDE has ALL the features you could possibly need, it is simply not the case. VS2010 does have a number of improvements to be sure.  You can now extract resources, define complex brushes, establish (some) data bindings and so on, all from the comfort of your Properties window.  Furthermore, the WPF and SL designers have true drag-and-drop control placement.

But...

If you want to define animations, 3D graphics or generate UserControls on the fly, Visual Studio is not enough. And that is where Expression Blend comes in.

When Blend was first released, it was marketed as a tool for graphical artists. Now, I am not so sure. It seems that the line between programmer and graphical artist is blurring. While nobody should expect a programmer to generate top-notch graphics (anymore than a graphical artist should not be expected to generate C# code), it is clear that the modern day WPF/SL programmer *should* know the basics of the Blend IDE.

As suggested, Blend is a very elaborate XAML editor. Unlike VS 2010, Blend *does* allow you to work with complex animations, extraction of UserControls from graphical data, edit default styles, define visual states for custom controls, generate 3D effects, apply animation easings and dozens of other feature that VS 2010 simply does not support. 

So. the short answer is, unless you *really* like typing XML, you will need to flip between VS 2010 and Blend when you are building a WPF / SL program.  

Given this, the next several blog posts will address the key features of Blend from a programmer's point of view.  If you don't have your own personal copy of Blend, be sure to download an evaluation copy here.

My next blog post will start at the very beginning of working with Blend.  Look for it in a few days!

 


Posted by: Andrew Troelsen
Posted on: 6/21/2010 at 11:28 AM
Tags:
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

How to Select All Text in a WPF TextBox on Focus

WPF has made it possible to create beautiful and compelling user interfaces in .NET - but there are a few times when the built-in user experience behavior of some of the controls isn't quite what you'd expect.

One of these areas happens to be the focus behavior of text boxes.

The Problem

A common behavior in most Windows applications that users are accustomed to(often without realizing it), is that upon focus entering a textbox, the text is automatically selected. This makes it possible to click or tab in to a textbox and immediately start typing - and content will be automatically replaced. This behavior is part of standard Windows text boxes ... but not the WPF TextBox control.

The approach to resolving this that may occur to you, is to handle focus events on all TextBox control instances and call the convenient SelectAll() method to highlight all content. Unfortunately, it's not quite that simple. Beyond the fact that wiring every TextBox control in your application gets old fast, there are a number of subtle edge cases where this approach fails.

We're going to look at how we can restore this behavior to text box controls in your WPF applications with as little pain as possible - and make it work they way users would expect - in all cases.

The Approach

The first issue we're going to tackle is how to respond to focus behavior on all text boxes throughout an application. It may occur to you to create a global style for text box controls and use an EventSetter to subscribe to Control.GetFocus. Unfortunately, styles have a number of limitations that make them less than ideal for this purpose. You can't apply multiple styles to a single control in WPF - which means that text box styles throughout your application would need to replicate this behavior. The best you can do is create a common style that all other TextBox styles are based on. This is a fragile and awkward approach at best - and at worst it becomes problematic if one of the derived styles needs to apply its own processing on GetFocus.

Fortunately there's a better way: the EventManager class. EventManager provides us with a way to globally subscribe to events for a particular type of control, rather than on an instance-by-instance basis. As it turns out, a convenient place to put this code is in your Application class' OnStartup() method:

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent, 
new RoutedEventHandler(SelectAllText), true); base.OnStartup(e); }
private static void SelectAllText(object sender, RoutedEventArgs e) { var textBox = e.OriginalSource as TextBox; if (textBox != null) textBox.SelectAll(); }

So we're done now, right? Well ... not quite. A little experimentation will show that while using the keyboard to set focus works well, using the mouse doesn't work as expected: when clicked, the selection initially appears, and then promptly vanishes. The reason for this is that the TextBox control internally responds to the MouseDown event, which fires after GotFocus. The text box relies on that event to place the insertion caret at the location in the text box where the user clicked. Since all of this happens GotFocus, the selection we set is lost. We're going to fix that.

The Ultimate Solution

The solution presented here is a little different from that above - basically, we're going to divide focus processing into two separation mechanisms - one that deals with focus changes from the keyboard, and another that responds to focus established by clicking the mouse.

Dealing with keyboard focus is easy - WPF has a UIElement.GotKeyboardFocus event that we can respond to instead of the more generalized Control.GotFocus. The mouse is a little bit trickier. First, we don't want to break the default click handling that TextBox implements - so we're going to instead use the PreviewMouseLeftButtonDown event to intercept clicks before the control responds to them. Preview events, also known as tunneling events, are routed events where the direction of the route travels from the application root towards the element that raised the event and is reported as the source in event data. We can use the preview mouse event to selectively handle the mouse click only in those cases when the focus is not yet transferred to the text box.

Now that we've established the approach, let's look at the code:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent,
           new MouseButtonEventHandler(SelectivelyHandleMouseButton), true);
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotKeyboardFocusEvent,
          new RoutedEventHandler(SelectAllText), true);

        base.OnStartup(e);
    }

    private static void SelectivelyHandleMouseButton(object sender, MouseButtonEventArgs e)
    {
        var textbox = (sender as TextBox);
        if (textbox != null && !textbox.IsKeyboardFocusWithin)
        {
            if( e.OriginalSource.GetType().Name == "TextBoxView" )
            {
                e.Handled = true;
                textbox.Focus();
            }
        }
    }

    private static void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    } 
}

So let's break it down. In the OnStartup() method we globally register the GotKeyBoardFocus and PreviewMouseLeftButtonDown events to the handlers below.

The SelectAllText() method is the same as before. The SelectivelyHandleMouseButton() method provides the code that corrects the focus behavior on clicks. First, it checks that we're actually dealing with a TextBox control by casting the sender parameter to the appropriate type. If keyboard focus is not yet in that text box (which we check using the IsKeyboardFocusWithin property), it then marks the event as handled, and calls textbox.Focus() to transfer focus (which will trigger the GotKeyboardFocus event for us).

There's only one last bit of code here that deserves an explanation, the line:

   if( e.OriginalSource.GetType().Name == "TextBoxView" )

The last edge case we need to handle is when the user clicks in the "chrome" portion of a TextBox - things like the border or scroll bars. It would be really awkward to select the text each time the user clicked the scrollbar. To fix this, we need to test that the mouse click originated in the "textual" portion of the control - which happens to be implemented by the TextBoxView class. WPF is helps us out by notifying us of the original source of the event via the RoutedEventArgs.OriginalSource property. Unfortunately, this class is not public outside of WPF infrastructure code - so we have to test for it by it's name. This is by far the least attractive aspect of the code shown above ... but sadly, it's the only reliable solution I've found so far.

Conclusion

So let's look at what we've learned so far.

  1. The built-in WPF TextBox control doesn't automatically select text when it receives focus.
  2. We can globally respond to events from any WPF control using the EventManager.RegisterGlobalHandler() method.
  3. We can use the OnStartup() method of the Application class to centrally register our handlers when the application loads.
  4. Focus behavior in WPF varies slightly depending on whether the control receives focus via the mouse or keyboard.
  5. We can use the PreviewXXX family of events to intercept clicks and supply our own event handling before the TextBox controls responds.
  6. We can use the RoutedEventArgs.OriginalSource property to avoid highlighting a selection when the original click events occurs within a non-content area of the TextBox control.

Put this all together, and we have an elegant, centralized solution to selecting the text inside the TextBox control when it receives focus.


Posted by: Leo Bushkin
Posted on: 6/18/2010 at 11:11 AM
Tags: , ,
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

5 Reasons to Consider Moving an Application to Windows Azure

By Jim White (Director of Training and Instructor)

This is the first of a two part blog post on considering Windows Azure for your applications.  See the 2nd posting next week.

Cloud computing, and in particular Microsoft Windows Azure are hot topics in IT circles today.  A report on CNN has even suggested that Internet users will live in the cloud by 2020 (see here).  Why is cloud computing ?the next big thing? in IT? Here are five reasons you should explore Windows Azure ? Microsoft?s cloud computing platform.

1. Save money

In fact, I really wanted to name this blog post 10 reasons to consider moving an application to the cloud and have #1 ? 5 be about money. As that would be unfair to the reader, I kept it to five, but the importance of saving money via cloud computing and Azure should not be understated. Buying, building, and operating a data center, no matter how small it is, is an expensive endeavor. The initial costs for hardware, network, and software give managers sticker shock. Operating costs (electricity, heating/cooling, and personnel to operate it) are growing expenses. Just about the time you have it up and running efficiently, it (hardware, networks, OS, etc.) need to be upgrade. Because the demands on the data center do not stay constant, most of the time your data center is either over or under utilized. If your business takes off, you may not have enough computing resources to meet the need. If stay in front of resource demand, you have long periods of excess capacity.

clip_image002

Windows Azure affords organizations data center resources (and more) in a pay-for-use model. Cloud computing is called utility computing because like water or electricity, you pay for what you use and not what you think you might use ? or for having to build the entire water pump house or electric generator all on your own. Don?t take my word for the savings. Prove it for yourself. In fact, so confident are Microsoft and others about the savings in Azure that there are two return on investment (ROI) calculators that allow you to size up your savings. Microsoft?s own, very detailed and thorough ROI calculator is here. You can also check out Neudesic?s calculator (itself a cloud application) out for a simpler-big-picture ROI report here.

2. Scaling

Most organizations have a hard time building an application or data store that must ultimately support incredible scale. Most applications and data stores start out relatively small, and through success take on more and larger needs. How do you plan to take that garage web site to the top ten most visited sites of the Internet? Azure allows you to scale by adding more resources in support of your application on demand. Whereas it might take days or months to provision new hardware, networks, software, etc. to support increases of demand on your applications and data stores today, you can provision what for all practical purposes is an infinite supply of computing resources in Azure in a matter of minutes or hours. Remember, scaling computing resources is often a two way street. You may need extra storage and computing resources today, but you do not want to pay for that extra forever do you? Say you have an application that you know is going to achieve a spike in utilization during a short period (think Dominos Pizza on Super Bowl weekend ? they are in fact a user of Azure ? see here) but after that, it?s back to normal computing. Azure allows you to take down those same resources as fast as you put them up.

3. High Availability

No one likes to have to answer the beeper or cell phone go off in the middle of the night ? especially when it?s to learn that a server, network device, database, or application has gone haywire. Software engineers like to code and solve business problems. Baby sitting equipment typically comes with the territory, but it can hardly be classified as satisfying work. Let someone else manage the environments that run and support your applications and data store! Azure provides a service level agreement (SLQ) backed environment (computational resources are guaranteed at 99.95% up time ? see here). If you doubt the SLA is being achieved, you can see an Azure data center dashboard that tells you what the up-time of the Microsoft cloud is today (see here).

In Azure, if the server box running your application or data store dies or an application running on an Azure virtual machine falls over, the Azure Fabric Controller brings it back up automatically. Furthermore, all data stored in Azure (Azure storage or SQL Azure) is replicated three times. So, applications and more importantly users should never see unavailable applications or data. Geographical redundancy is something Azure developers have requested and may be available in future releases. That is, your application and/data may be made available in multiple Microsoft data centers located across the world to provide expanded availability. Even if one data center were down, the other would still be up and take on the requests. With Azure, organizations can focus on their core business solutions and not on keeping a data center operational.

4. Rapid Application Development/Testing

If you have ever worked in a relatively large organization and started on a new project, you have probably experienced the team down-cycles at the beginning of a project when new equipment, development environments, etc. have to be approved, then ordered, setup and made operational. What a drag on the ?rapid? part of RAD development. If someone in your organization has an idea about how to make the company more money or improve operations, how long does it take to get that idea in front of customers or decision makers? If the answer is too long, perhaps you need a better way to provision the RAD environments and get product to market faster. Azure offers a ready and waiting environment with developer tools to allow teams to get prototypes and early versions of applications up and running quickly and cheaply. Moreover, since Azure is .NET based, a lot of the tools and existing .NET skills can be applied and reused in cloud computing. If the project fails or needs to be moved to a more tightly managed environment, the cloud resources can be shed just as quickly with no wasted and unused equipment standing around. Azure can serve as an incubator to hot ideas that can help businesses move and react quicker.

5. Geographical Distribution

Who are your customers today? Are they all in your city? Your state? Your country? Increasingly, applications, content and data is shrinking the world. However, your applications and data are still probably located where you are. Is this a problem? Maybe. If your customers are around the world, you may be required to have your applications and data where the customers are and not where you are. Increasing legal and regulatory demands from governing bodies (local, national and international) make it necessary to put applications and data within certain geopolitical boundaries. Tax laws may encourage you to host your application and data in certain areas of the world while avoiding others. And even though the speed of light that pushes data through fiber optic cable is good, it may not be enough when that data has to travel half way across the world in a time-critical transaction. As many organizations ?go global?, they need to find a way to distribute applications and data geographically (without the expense and trouble of building their own data centers in several locations across the world). Microsoft has already done that for you. Azure is hosted in data centers around the world. When you build your application for any one Azure site, you can easily deploy it to an ever-increasing set of Azure data centers with no changes ? free (except for the actual resources you use in the cloud) geographical distribution.

If you would like to learn more about Windows Azure, check out our training course here. If your consultants can help you ?navigate in the clouds?, please contact Ryan McCabe for assistance. Also, I invite you to join the Windows Azure User Group ? it?s a virtual users group ? where you?ll find some great educational material and virtually meet people discussing Azure.


Posted by: Jim White
Posted on: 6/17/2010 at 1:42 PM
Tags: , , , ,
Categories: .NET | Cloud Computing
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (2) | Post RSSRSS comment feed

Top 10 Things Seasoned .NET Developers Understand or 10 Things New .NET Developers Need to Know

My coworker at Intertech (Jim White) wrote an interesting blog post which addressed the "10 topics advanced Java programmers need to know" (he's a Java-guy, but don't hold that against him ;-). I liked his article, so I thought I'd offer up a .NET version of the same post.  Here it goes, and thanks Jim for the idea!  By the way, these are *not* any any specific order...

10) LINQ

At first, LINQ was seen by many to be a interesting shortcut for grabbing data from a container.  Nowadays however, LINQ is everywhere.  LINQ to XML, LINQ to EF, PLINQ and LINQ to Objects are common place.  If you want to show your team mates you are up to speed on core .NET technologies, understanding LINQ should be on the top of your list of ToDos.

9) WPF (and therefore Silverlight)

Regardless if you are a "Web Person" or a "Desktop Person", Microsoft's current GUI APIs are quickly replacing older frameworks, especially Windows Forms.  Both WPF and Silverlight use the same core body of tech, so when you understand 1, the other is close behind.

8) The Blend IDE

I was a man who was fearful of Blend early on.  In fact, I wore my fingers to the bone typing in XAML by hand.  Trust me, if I can get over the Blend fear-zone, any one can.  If you are doing WPF or Silverlight, usnig Blend makes your work much easier, especially when working with templates, animations or graphics.

7) TPL

The Task Parallel Library is a new .NET 4.0 threading / multicore API.  Using TPL (and PLINQ) you can very easily add multithreaded functionality to your applications, using a framework which hides a good number of the low level details. Thanks thread pool!

6) Lambdas

The C# => operator, or the VB Sub/Function statements, can seem to be quite terse at first glance. However, lambdas are a great shortcut for working with delegates.  If you are serious about learning LINQ and the TPL, you *need* to be confortable with lambdas.

5) WF 4.0

OK, I know.  WF 3.0-3.5 had some warts.  But honest, WF 4.0 is a massive step in the right direction.  A whole new assembly stack, new designers, new engine and new activities make the process of modeling business processes clean and simple.  And, WF 4.0 is based on XAML!

4) Knowing if you REALLY need That Pattern

Design patterns *can* help you write easy to maintain code....or they can add layers of unnecessary complexity.  We programmers love the latest and greatest to be sure, but I have seen too many people cram patterns into projects that just don't need them.  Case in point?  ASP.NET MVC.  Yes, it is great for testing web sites, but there are ways to do so without MVC.  Don't use a pattern because it is the latest buzz word.  Use it because it will make your life better.

3) ADO.NET EF

The Entity Framework is a slick object model over relational database logic, which favor LINQ queries over T-SQL queries. While the connected and disconnected layers are certainly still part of the picture, the EF model can really simplify common database activities....and the VS 2010 designers are very solid.

2) Use of Dynamic Data

The DLR allows you to opt-into scripting like functionality, within a statically typed language. If you are doing any sort of COM interop, dynamic assembly generation or reflection tasks, dynamic data can reduce the amount of code you will need to write by a *great* deal.  Just watch your typing...

1) The .NET Type System

In a rush to get software out the door ASAP, many programmers "skip" over the foundational nuts and bolts, and google for the next "how do I make my grid look like this" sort of answer.  Google is great, but you really owe it to yourself to be solid on the ins and outs of classes, interfaces, structures, enums and delegates. These are the bread and butter aspects of every possible .NET application and API.

So, thanks again Jim for the idea. Hope to see some of you in class where we can learn about these (and many other) .NET topics

 


Posted by: Andrew Troelsen
Posted on: 6/7/2010 at 4:47 PM
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (3) | Post RSSRSS comment feed

Windows Azure Table Storage vs. Windows SQL Azure

By Jim White (Director of Training and Instructor)

Last week, my fellow Intertech colleague and Microsoft MVP, Tim Star, and I presented the Windows Azure Bootcamp for the Twin Cities.  According to Microsoft reps, we broke the record for the most attended bootcamp in the US with nearly a hundred people at the event.

A common question that I received during and after the bootcamp was "Why would I want to use Windows Azure Table Storage versus Windows SQL Azure to store my application data?"  A good question with the answer dependent on your application and data needs.

Table Storage and SQL Azure Defined

First, allow me to backup and set the stage a little for this discussion.  SQL Azure is essentially SQL Server in the Microsoft cloud computing environment known as Azure.  That is not quite true in that SQL Azure currently has a number of limitations and unsupported features that SQL Server 2008 has (here is a starter list of limitations:  http://msdn.microsoft.com/en-us/library/ee336245.aspx).  I like to say that SQL Azure is either SQL Server 2008 minus or SQL Express plus depending on how you want to view it.  Table Storage is one of three alternate storage mechanisms built into Azure that is collectively called Windows Azure Storage Services.  The other two being queues and blobs.  Table Storage allows you to store serialized entities in a table, but the term table here  is not a relational database table.  To provide people with some analogy they can use to get their arms around Table Storage, I like to tell people to think of Table Storage as a fancy spreadsheet.  You can store the state of your entities in the columns of the spreadsheet.  However, there is no linkage or relationship (therefore joins) between entities - at least none that is automatically managed and maintained by Azure.  There are no custom indexes - at least not today.

Interestingly, when Azure was first introduced in 2008, SQL Server was not part of the original picture.  Because of developer negative reactions, SQL Azure was added to the next preliminary release in 2009.  There is a growing faction that is trying to get the software community to look at SQL alternatives.  The "No-SQL" community (see here and here), to some extent, has influenced part of the Azure cloud computing platform through the Table Storage option, but not enough to eliminate it from the Microsoft cloud.

While both SQL Azure and Azure Table Storage provide data persistence via table structure, there are a number of differences between them.  The sections below outline some of the key differences and factors you want to weigh before building an application for Azure that requires some form of table persistence.

Scale and Performance

When looking at sheer volume, Table Storage is today far more scalable than SQL Azure.  Given a storage account (storage accounts hold blobs, queues and tables) is allowed to be 100TB in size, in theory your table could consume all 100TB.  At first glance, a 100TB chunk of data may seem overwhelming.  However, Table Storage can be partitioned.  Each partition of Table Storage can be moved to a separate server by the Azure controller thereby reducing the load on any single server.  As demand lessens, the partitions can be reconsolidated.  Reads of Azure Table Storage are load balanced across three replicas to help performance.

Entities in Table Storage are limited to 1MB each with no more than 255 properties (3 of which are required partition key, row key, and timestamp).  That seems like an absurd number, and it is, but remember that there are no relationships and joins in Table Storage.  Therefore, you might need some wide tables to handle associated data.

Today, SQL Azure databases are limited to 1GB or 10GB.  However, sometime this month (June 2010), a 50GB limit is supposed to be available.  What happens if your database is larger than 10GB today (or 50GB tomorrow)?  Options include repartitioning your database into multiple smaller databases or sharding (Microsoft's generally recommended approach).  Without getting into the database details of both of these database design patterns, both of these approaches are not without issue and complexity, some of which must be resolved at the application level.

Data Access

Data in the cloud, be it in SQL Azure or Azure Table Storage, can be accessed from in or out of the cloud.  To access data in SQL Azure, all the standard tools and APIs apply that work with SQL Server.  Meaning, your existing .NET/SQL Server knowledge and experience can be heavily leveraged.  ADO.NET and ODBC APIs can be used by application code to access the SQL Azure database.  Tools like SQL Server Management Studio and Visual Studio can be pointed to the SQL Azure instance and manipulate the schema and data just as you do today with SQL Server. 

Access to Azure Table Storage is accomplished either via REST API or Storage Client Library provided with the Windows Azure SDK.  Using the REST API allows client applications to communicate and use data from Table Storage without having detailed and specific knowledge of an Azure API, but it is more complex and difficult to work with.  The Storage Client Library (which leverages LINQ to Objects) provides a layer of convenience but requires the application reference the Storage Client Library APIs.  REST and the Storage Client Library incur a learning curve that is typically not there when using SQL Azure.

Portability

As mentioned, data in SQL Azure and Table Storage can be accessed from applications in and out of the cloud.  That means applications can be moved in or out of the cloud and still deal with the data in the cloud in the same way.  However, one question that may need to be considered is whether the data must always live in the cloud?  Applications generally view data in SQL Azure similar enough to data in a normal SQL Server database as to allow the data to migrate back and forth between the cloud and on-premise databases.  In fact, there are even migration tools to help move data between instances of SQL Server and SQL Azure. 

However, given the unique nature and access APIs of Table Storage, portability of the data is not as straight forward.  Table Storage tightly couples your data to the cloud.  Moving the data out of the cloud would require an on-premise data storage alternative, a data migration strategy, and likely require application code changes.

Transactions and Concurrency

SQL Azure supports typical ACID transactions for work within the same database.  Transactions across databases are not supported.  SQL Azure allows for typical optimistic and pessimistic concurrency strategies.

Table Storage supports transactions for entities in the same table and table partition, but not across tables or partitions.  Additionally, only 100 operations or less (what is called a batch in Azure Table Storage) can be part of the transaction.  Only one operation can be performed on each entity in the batch, and the batch must be limited to 4MB.  Table Storage abides strictly by an optimistic concurrent strategy.  If, on commit of the transaction, data has been changed by another process the whole transaction must be rolled back and retried.  Due to this single concurrency strategy, a built-in retry option is provided with the Storage Client Library.

Queries

Using Table Storage, queries are limited to 1000 entities by default.  If more than 1000 entities are found, a continuation token is returned and must be used by the application to retrieve the next set of entities.  Queries that take longer than 5 seconds also return a continuation token.  Queries that take longer than 30 seconds are cancelled.  Data in Table Storage is organized by partition key and indexed by row key.  Because there are no custom indexes in tables, queries by partition key and row key are fast, but queries that do not use partition key and row key are slow.

Generally speaking, SQL Azure has no limitations, issues or special programming requirements to work with large queries.  Good database and index design can help improve performance of queries; especially large ones.

Column types

Columns in Table Storage are limited to the types in the table below.

byte[]
bool
DateTime
double
Guid
Int32 or int
Int64 or long
String

Cost

Perhaps the most unique aspect to designing and architecting applications for the cloud is that it requires developers to think like businessmen.  Each technical choice often has direct costs associated with it when developing for the cloud.  The choice in data storage can have a huge impact on the cost of running an application.

Azure Table Storage costs 15? per GB of storage per  month.  Additionally, you pay 1 cent per 10,000 transactions with Table Storage.  SQL Azure costs are $9.99 for 1 GB of storage per month ($99.99 for 10GB). 

See Microsoft's sight for more details and specifics on costs here.

Bottom Line

Chris Hay and Brian Prince in their forth coming book Azure in Action (published by Manning - see here) provide a synopsis of the SQL Azure vs. Table Storage in a few paragraphs.  "If size is the issue, that would be the first flag that you might want to consider Azure Tables. As long as the support Tables has for transactions and queries meets your needs. The size limit surely will, at 100TB."  Further they suggest sophisticated transactions, or a complex authorization model might require the services of SQL Azure.  And as shown by the cost table above, "The final consideration is cost. I can store a lot of data in Azure Tables for a lot less money than I can in SQL Azure. SQL Azure is giving me a lot more features to use (joins, relationships, etc.), but it does cost more."

Future

We are given every indication by Microsoft that SQL Azure will have far more capability in the future - akin to the SQL Server you might find in your data centers today.   So some of the comparison above may be moot or less important over time.  Additional functionality is also being proposed to Table Storage as well.  For example, support of secondary (non-key) indexes is already been suggested for a future release (see here).  However, key architectural differences between SQL Azure and Table Storage will remain and leave application designers having to pick the best option for their systems.  Welcome to cloud computing.  There is a lot of ROI to be had by running in the cloud, but only with proper application design and architecture.

If Intertech can help you  negotiate the issues of cloud computing, please contact Ryan McCabe at ryan.mccabe@intertech.com.


Posted by: Jim White
Posted on: 6/1/2010 at 5:34 PM
Tags: , , ,
Categories: Cloud Computing | .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

A Review of VB Event Handling (WithEvents, AddHandler and AddressOf)

When you are building an application using VB, you will most certainly need to hook into various event sources.  While events are very common when you are constructing a GUI application (WPF, ASP.NET, Windows Forms), they are also very important for non-UI tasks such as working with threads, callbacks from database operations, and other tasks.

As it turns out, VB has a few "oddities" regarding how to hook into a given event, so I wanted to do a quick blog post which will hopefully clarify our choices.

First of all, when you are declaring a field of a Class, Structure or Module, you have the option of making use of the WithEvents keyword.  When you do so, you are able to selectively hook into events of interest using the Handles clause on a given class method. One part of this puzzle which is hidden from view is the fact that each and every .NET event is defined in termes of a related delegate.  As you may know, the .NET delegate type allows us to capture, in a strongly typed manner, the address of another method. Given this point, the method that uses the Handles clause must match the underlying delegate definition, or you will receive compile time errors!

Here is a simple example of capturing the Click event of the Windows Forms Button class.  Take note that the method receiving the event notification takes an Object as the first parameter, and a EventArgs as the second, given that the Click event has been defined in terms of a system delegate named System.EventHandler.

 Class MainWindow
 
Inherits Form

  ' Inform the Button we are interested in listening to
  ' events.
  Private WithEvents btnClickMe As Button

  Public
Sub New()
    btnClickMe =
New Button With {.Height = 100,
      .Width = 100, .Text =
"OK!"}
   
Me.Controls.Add(btnClickMe)
  End Sub

  Private Sub btnClickMe_Click(ByVal sender As Object,
   
ByVal e As System.EventArgs) Handles btnClickMe.Click
   
MessageBox.Show("Clicked!")
 
End Sub
End
Class

Now, one gotchya is that the WithEvents keyword can only be used for fields (local variables need not apply). When you wish to handle an event for a local variable, you are required to use the AddHandler statement.  Here, you will specify the event name and method to call (via the AddressOf operator).  However, in this case the Handles clause is not used.  Here is a re-working of the previous class which illustrates these points: 

Class MainWindow

Inherits Form
 
Public Sub New()
   
Dim btnClickMe As Button
   
btnClickMe = New Button With {.Height = 100,
      .Width = 100, .Text =
"OK!"}

   
AddHandler btnClickMe.Click, AddressOf btnClickMe_Click
    
Me.Controls.Add(btnClickMe)
 
End Sub
...
End Class

Of course, with the release of .NET 4.0, VB has full support for lambda expressions.  This is yet another way to hook into event sources, which was covered in a previous blog post.


Posted by: Andrew Troelsen
Posted on: 6/1/2010 at 10:03 AM
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

C# and the .NET Platform, 5th Ed.

Quick blog post this week to let people know that the 5th Edition of my C# book is in the stores!

C# 2010 and the .NET 4.0 Platform tops in at more than 1700 pages (eek!).

But there are a number of new topics, extended topics, additional examples and other goodies. Here is a hit list of the big topics:

  • Coverage of the C# dynamic keyword and DLR
  • Coverage of the ADO.NET Entity Framework / LINQ to Entities
  • Coverage of C# 2010's improved COM interop
  • Coverage of the TPL and PLINQ
  • Deeply expanded coverage of WPF
  • Deep coverage of Expression Blend
  • Coverage of WF 4.0 (which is totally different from the previous WF API)
  • The new WCF 4.0 bits.
  • etc, etc, etc.

As before, Apress is offering deals for a digital copy of the book if you buy the printed copy.  Check out the following link for more details.

Be back next week with some new tech-posts.  Thinking of starting a long blog tutorial about Expression Blend......hummmm.....

Happy coding,

Andrew

 


Posted by: Andrew Troelsen
Posted on: 5/21/2010 at 3:14 PM
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed