For those of you in the San Diego area, I'll be speaking at the San Diego .NET Developers Group tomorrow night (March 6th). Details are available here: San Diego .NET Developers Group.
The topic is IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces. We'll take a look at what it means to program to an abstraction rather than a concrete class, see how interfaces can help us accomplish that, and then review some real life examples of how we can use interfaces to make our code more robust and extensible. Hope to see you there.
Happy Coding!
Monday, March 5, 2012
Web Service Proxy Collection Types
SOAP-based web services are self-documenting. This means that tools like Visual Studio can create a proxy class for us based on the service description (generally with WSDL -- the web service definition language).
Collection Types
SOAP web services are designed to be interoperable. This means that we can consume a SOAP web service with whatever development environment we are using (.NET, Java, PHP, etc.) regardless of the language that the web service itself is written in. (The converse is also true - we can write our .NET web services so that they can be easily consumed by other development environments.)
When talking about interoperability, this usually means that we are coding to the lowest common denominator -- meaning that we use the constructs that can be understood by the most development environments. For collections in .NET, we have a tendency to use a generic list such as List<T>. But when thinking about interoperability, we need to consider that generic lists do not exist in every environment, and so we take a step down to an Array object.
When consuming web services, we run into the same issue. The service may expose an Array object as a return type. But we would much rather use a generic list in our code. So, what do we do?
Did You Know? Advanced Proxy Settings
The Visual Studio service proxy generator actually gives us control over the types of collections that are exposed by our proxy. When you select "Add Service Reference" for a project, the resulting dialog has an "Advanced" button. If we click this, we get the following screen:
If you have already created a service reference, you can also get to this screen by right-clicking on the service reference in the Project Explorer and selecting "Configure Service Reference".
Notice that there is a setting for "Collection Type". The default for this will vary depending on the environment and type of service that we are consuming. For example, the sample above is a SOAP 1.1 service, and so it has defaulted to the Array collection type (System.Array). But we can change this with the drop-down:
This lets us change from Array to List<T> without having to do any casting or conversion in our code. All of this is handled for us in the proxy that Visual Studio creates for us. Any Arrays that are specified in the service (either as parameters or return types) will be converted to generic lists automatically. Pretty cool, huh?
You can see that we have a number of options to choose from. The List<T> (System.Collections.Generic.List) is just one of them. We could also use an ObservableCollection (which has special features in the XAML world) or one of the other types that meets our needs.
If the services are using Dictionaries, there is a similar option to choose the specific dictionary type -- whether a sorted list, generic dictionary, hashtable, or something else.
SOAP Services Are Still Cool
SOAP services have been getting some bad publicity lately ("They are too verbose") as people move toward REST services. But like everything else in the programming world, there is room for both. Each have advantages and disadvantages; it's our job as developers to weigh those benefits and costs and determine which is appropriate for our situation.
The big advantage to SOAP services is that they are self-describing. This means that we can use tools such as Visual Studio to create a proxy class that makes it extremely easy for us to interact with the service. (Most other development environment have this same sort of WSDL importer tool.)
Visual Studio is a great development environment that gives us quite a bit of control over how the SOAP service proxies are generated. We've seen how we can control the collection types; you can take a look at the "Advanced" features to see what other options are available.
Happy Coding!
Collection Types
SOAP web services are designed to be interoperable. This means that we can consume a SOAP web service with whatever development environment we are using (.NET, Java, PHP, etc.) regardless of the language that the web service itself is written in. (The converse is also true - we can write our .NET web services so that they can be easily consumed by other development environments.)
When talking about interoperability, this usually means that we are coding to the lowest common denominator -- meaning that we use the constructs that can be understood by the most development environments. For collections in .NET, we have a tendency to use a generic list such as List<T>. But when thinking about interoperability, we need to consider that generic lists do not exist in every environment, and so we take a step down to an Array object.
When consuming web services, we run into the same issue. The service may expose an Array object as a return type. But we would much rather use a generic list in our code. So, what do we do?
Did You Know? Advanced Proxy Settings
The Visual Studio service proxy generator actually gives us control over the types of collections that are exposed by our proxy. When you select "Add Service Reference" for a project, the resulting dialog has an "Advanced" button. If we click this, we get the following screen:
Notice that there is a setting for "Collection Type". The default for this will vary depending on the environment and type of service that we are consuming. For example, the sample above is a SOAP 1.1 service, and so it has defaulted to the Array collection type (System.Array). But we can change this with the drop-down:
This lets us change from Array to List<T> without having to do any casting or conversion in our code. All of this is handled for us in the proxy that Visual Studio creates for us. Any Arrays that are specified in the service (either as parameters or return types) will be converted to generic lists automatically. Pretty cool, huh?
You can see that we have a number of options to choose from. The List<T> (System.Collections.Generic.List) is just one of them. We could also use an ObservableCollection (which has special features in the XAML world) or one of the other types that meets our needs.
If the services are using Dictionaries, there is a similar option to choose the specific dictionary type -- whether a sorted list, generic dictionary, hashtable, or something else.
SOAP Services Are Still Cool
SOAP services have been getting some bad publicity lately ("They are too verbose") as people move toward REST services. But like everything else in the programming world, there is room for both. Each have advantages and disadvantages; it's our job as developers to weigh those benefits and costs and determine which is appropriate for our situation.
The big advantage to SOAP services is that they are self-describing. This means that we can use tools such as Visual Studio to create a proxy class that makes it extremely easy for us to interact with the service. (Most other development environment have this same sort of WSDL importer tool.)
Visual Studio is a great development environment that gives us quite a bit of control over how the SOAP service proxies are generated. We've seen how we can control the collection types; you can take a look at the "Advanced" features to see what other options are available.
Happy Coding!
Saturday, February 25, 2012
XAML Namespaces and Default Properties
Here are a few questions that have come up during some recent "XAML: Don't Fear the Markup" presentations.
Question: How can you tell what is in the namespaces that are included by default in the XAML markup?
MSDN and the Visual Studio Help contain listings of the elements that are in the namespaces. For example, the "x:" namespace (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml") is available in this article: XAML Namespace (x:) Language Features. It's interesting to take a quick tour through this list. It shows the "x:Class", "x:Name", and "x:Key" that were mentioned in the presentation; but it also shows things like "x:Null" which are useful for resetting a property that would normally be inherited. For example, if you have a custom Style, you can choose to have that style automatically applied to all of the applicable controls in the XAML document. If a control needs to use the default style rather than the custom style, you can set that control's style to "{x:Null}" to reset the value.
The other namespace that we looked at a little was the "d:" namespace (xmlns:d="http://schemas.microsoft.com/expression/blend/2008"). This also has an article describing the members: Design-Time Attributes in the Silverlight Designer. This shows the "d:DesignHeight" and "d:DesignWidth" that we saw in the sample. It also has some interesting things to look into further such as "d:DataContext" which lets you set up a design-time data context for data binding. In our sample, the databinding was hooked up to a local object, so the design-time view worked without doing anything special. But if you had remote data (for example, customer data coming from a SQL database), then you wouldn't have that data available at design time. In that case, you could use the "d:DataContext" to hook up to a local object that had some sample hard-coded data. These are all design-time functions. They are there to help you with your XAML page/window/user control creation. At run time, your actual data context would be used.
Question: The XAML namespaces use the URI format ("http://..."). How should you name your own namespaces?
When creating your own namespaces, you should follow whatever namespace naming convention that you have in place. There is no need to use the URI format; instead, simply use the standard .NET namespace naming -- usually something like "CompanyName.Product.Module". In the sample, we saw how to bring in a namespace that is local to our project, which ended up looking like this: xmlns:local="clr-namespace:JeremyBytes.StopWatch". But it is fairly simple to bring in namespaces from other assemblies that are referenced in the current project. You can get more information here: XAML Namespaces and Namespace Mapping for WPF XAML.
Question: How can you identify the default property of a XAML element?
The default property of a XAML element is the property that we can simply put "between the tags" without any specific references. In our sample, we saw that we could specify the content property for a button by simply putting the content between the opening and closing tags: "<Button...>Start</Button>". The question is how do we know which property is the default property?
The default properties are specified in the help file. So, all we need to do is press "F1" on any of our controls to see what the value is. Here are a few samples:
Here, we can see what the default properties are for each of these elements. As we saw in the sample, we are always free to explicitly specify the property, but using the default property syntax can help keep our markup more readable.
If you have any questions about the XAML presentation or walkthrough, feel free to send them along to me.
Happy Coding!
MSDN and the Visual Studio Help contain listings of the elements that are in the namespaces. For example, the "x:" namespace (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml") is available in this article: XAML Namespace (x:) Language Features. It's interesting to take a quick tour through this list. It shows the "x:Class", "x:Name", and "x:Key" that were mentioned in the presentation; but it also shows things like "x:Null" which are useful for resetting a property that would normally be inherited. For example, if you have a custom Style, you can choose to have that style automatically applied to all of the applicable controls in the XAML document. If a control needs to use the default style rather than the custom style, you can set that control's style to "{x:Null}" to reset the value.
The other namespace that we looked at a little was the "d:" namespace (xmlns:d="http://schemas.microsoft.com/expression/blend/2008"). This also has an article describing the members: Design-Time Attributes in the Silverlight Designer. This shows the "d:DesignHeight" and "d:DesignWidth" that we saw in the sample. It also has some interesting things to look into further such as "d:DataContext" which lets you set up a design-time data context for data binding. In our sample, the databinding was hooked up to a local object, so the design-time view worked without doing anything special. But if you had remote data (for example, customer data coming from a SQL database), then you wouldn't have that data available at design time. In that case, you could use the "d:DataContext" to hook up to a local object that had some sample hard-coded data. These are all design-time functions. They are there to help you with your XAML page/window/user control creation. At run time, your actual data context would be used.
Question: The XAML namespaces use the URI format ("http://..."). How should you name your own namespaces?
When creating your own namespaces, you should follow whatever namespace naming convention that you have in place. There is no need to use the URI format; instead, simply use the standard .NET namespace naming -- usually something like "CompanyName.Product.Module". In the sample, we saw how to bring in a namespace that is local to our project, which ended up looking like this: xmlns:local="clr-namespace:JeremyBytes.StopWatch". But it is fairly simple to bring in namespaces from other assemblies that are referenced in the current project. You can get more information here: XAML Namespaces and Namespace Mapping for WPF XAML.
Question: How can you identify the default property of a XAML element?
The default property of a XAML element is the property that we can simply put "between the tags" without any specific references. In our sample, we saw that we could specify the content property for a button by simply putting the content between the opening and closing tags: "<Button...>Start</Button>". The question is how do we know which property is the default property?
The default properties are specified in the help file. So, all we need to do is press "F1" on any of our controls to see what the value is. Here are a few samples:
Here, we can see what the default properties are for each of these elements. As we saw in the sample, we are always free to explicitly specify the property, but using the default property syntax can help keep our markup more readable.
If you have any questions about the XAML presentation or walkthrough, feel free to send them along to me.
Happy Coding!
Monday, February 20, 2012
San Diego .NET UI Developers SIG
For those of you in the San Diego area, I'll be speaking at the San Diego .NET UI Developers SIG tomorrow night (February 21, 2012). Details are available here: San Diego .NET User Group.
The topic is XAML: Don't Fear the Markup. We'll be getting comfortable with the XAML markup and see how we can tweak it to meet our UI needs. In addition, we'll take a look at a few cool design tricks that we can use to add a little "glow" to our UI. Hope to see you there.
Happy Coding!
The topic is XAML: Don't Fear the Markup. We'll be getting comfortable with the XAML markup and see how we can tweak it to meet our UI needs. In addition, we'll take a look at a few cool design tricks that we can use to add a little "glow" to our UI. Hope to see you there.
Happy Coding!
Sunday, January 1, 2012
Happy New Year!
Another year has gone by, and we have another year to look forward to. Thank you to everyone who attended one of my sessions at a code camp or user group. You are why I keep presenting.
Over the last 2 years, you've come out to see me at 45 sessions across 20 events, with a total of over 1,500 people in attendance (1,510, but who's counting?).
We've got another great year coming up. I've already got several sessions scheduled, and I hope to see you at one in the future.
Happy Coding!
Over the last 2 years, you've come out to see me at 45 sessions across 20 events, with a total of over 1,500 people in attendance (1,510, but who's counting?).
We've got another great year coming up. I've already got several sessions scheduled, and I hope to see you at one in the future.
- Jan 28 & 29 - So Cal Code Camp (Fullerton, CA)
- Mar 6 - San Diego .NET Developers Group (San Diego, CA)
- Mar 20 - Disney .NET Developers Group (Burbank, CA)
- Mar 21 - San Gabriel Valley .NET Developers Group (Monrovia, CA)
- Apr 26 - Southern Nevada's .NET User Group (Las Vegas, NV)
- May 8 - Inland Empire .NET User's Group (Riverside, CA)
Happy Coding!
Sunday, November 13, 2011
Exceptions in Multi-Cast Delegates
At the last 2 code camps (So Cal Code Camp and Desert Code Camp), the same question came up. How do exceptions affect the process flow when invoking a multi-cast delegate? Let's do a quick review and then take a closer look. For more information, please take a look at Get Func<>-y: Delegates in .NET.
Multi-Cast Delegates
All delegates in .NET are multi-cast delegates. This means that we can assign multiple methods to the same delegate variable. When we invoke the delegate variable (to run the methods), then all methods that have been assigned are run.
For example, take a look at this Action variable:
Action<List<Person>> act;
Then we can assign multiple methods as follows (in this case using lambda expressions):
act += p => Console.WriteLine(p.Average(r => r.Rating)).ToString();
act += p => Console.WriteLine(p.Min(s => s.StartDate));
Then we can invoke the delegate (assuming that "people" is a list of Person objects):
act(people);
The resulting output to the console window is as follows:
6.4285714285714288
10/17/1975
Single-Threaded Execution
.NET does not do anything magical when it runs the methods assigned to the delegate. They simply run in order, synchronously, on the same thread where the delegate is invoked. In the examples from the "Get Func<>-y" session, we invoke the delegate from the UI thread of a WPF application, and we see that if one of the methods is blocking (such as a MessageBox.Show() method that waits for user input), then the other methods do not execute until that method has completed. (As you can imagine, if we wanted the methods to run on separate threads, we could do that; but that is not the default behavior.)
Exceptions
Now, what happens if we add an exception into the mix:
act += p => Console.WriteLine(p.Average(r => r.Rating)).ToString();
act += p => { throw new Exception("Error Here"); };
act += p => Console.WriteLine(p.Min(s => s.StartDate));
What do we expect to happen? Will all 3 methods execute? None of the methods? Only the first one?
The answer turns out to be pretty simple. Since the methods are run in order, the first method will execute successfully, the second method will throw an exception, and the third will not execute. Since we do not have any exception handling defined, our application will stop working. The console window will have the following:
6.4285714285714288
So, we can see that the first method did in fact run, but the third method did not.
Exception Handling
We can keep our application operational by adding a try/catch block around the invocation of the delegate. This will keep our application from completely erroring out:
try
{
act(people);
}
catch (Exception ex)
{
Console.WriteLine("Caught Exception: {0}", ex.Message);
}
And our output now looks like the following:
6.4285714285714288
Caught Exception: Error Here
But something to notice, even though our application continues (and completes normally), the third method still does not run. And this should not be surprising. When an exception is thrown, the system will walk up the call stack until it finds an exception handler. If it does not find one, then the application will error out. In this case, when the exception in the second method is thrown, it walks back up the call stack to the method that invoked the delegate. There it finds the try/catch and handles the exception. But since we exited out of the actual delegate invocation, the third method is not called.
[Update: For a more robust solution, see More Delegate Exception Handling.]
Some Things to Think About
Now let's consider a bit how we use delegates. Generally, we (as developers) are on one end of the delegate or the other -- meaning we are creating a delegate so that other developers can hook into our code, or we are using a delegate to hook into someone else's code.
If we are creating a delegate that we invoke (such as the call to act(people) above), then we should definitely consider wrapping the invocation in a try/catch block. When someone assigns a method to a delegate that we then invoke, we really have no control over what that assigned method does. This means that we need to protect our code to make sure that someone else's mistake does not cause our code to crash. We need to handle any exceptions that are generated by the invocation so that our application can continue to operate (or at least fail gracefully).
Also, as we noted in "Get Func<>-y", we should be checking the delegate before invocation to make sure that it is not null. In this code sample, it would look like the following:
try
{
if(act != null)
act(people);
}...
If we try to invoke a delegate variable that does not have any methods assigned, then we will get a null reference exception. Alternately, we could handle the NullReferenceException in our catch block, but it's usually better to avoid the exception if it can be anticipated.
But what if we're on the other side of the delegate? What if we are a developer who is assigning methods to a delegate to hook into someone else's code? In that case, we need to follow standard practices for error handling in those methods. We could easily add a try/catch block to the method that we assign to a delegate variable. This way we would have the first shot at handling the exception. And since the exception is happening in our code, we are probably in the best position to try to handle it. If we cannot handle the exception, then we can let it bubble up (as we saw in the sample above). How we handle this will depend on the type of delegates that we are working with, what our business processes are, and how we have designed our error handling and failure modes through the rest of the application.
We always need to be on the lookout for the unexpected. In the sample code that shows up in my demos, the error handling has been excluded (just so that we can more clearly focus on the topic at hand). But when building our applications, we need to make sure that we are following good programming practices and making sure that we can handle the exceptions that may occur in our code.
Happy Coding!
Multi-Cast Delegates
All delegates in .NET are multi-cast delegates. This means that we can assign multiple methods to the same delegate variable. When we invoke the delegate variable (to run the methods), then all methods that have been assigned are run.
For example, take a look at this Action variable:
Action<List<Person>> act;
Then we can assign multiple methods as follows (in this case using lambda expressions):
act += p => Console.WriteLine(p.Average(r => r.Rating)).ToString();
act += p => Console.WriteLine(p.Min(s => s.StartDate));
Then we can invoke the delegate (assuming that "people" is a list of Person objects):
act(people);
The resulting output to the console window is as follows:
6.4285714285714288
10/17/1975
Single-Threaded Execution
.NET does not do anything magical when it runs the methods assigned to the delegate. They simply run in order, synchronously, on the same thread where the delegate is invoked. In the examples from the "Get Func<>-y" session, we invoke the delegate from the UI thread of a WPF application, and we see that if one of the methods is blocking (such as a MessageBox.Show() method that waits for user input), then the other methods do not execute until that method has completed. (As you can imagine, if we wanted the methods to run on separate threads, we could do that; but that is not the default behavior.)
Exceptions
Now, what happens if we add an exception into the mix:
act += p => Console.WriteLine(p.Average(r => r.Rating)).ToString();
act += p => { throw new Exception("Error Here"); };
act += p => Console.WriteLine(p.Min(s => s.StartDate));
What do we expect to happen? Will all 3 methods execute? None of the methods? Only the first one?
The answer turns out to be pretty simple. Since the methods are run in order, the first method will execute successfully, the second method will throw an exception, and the third will not execute. Since we do not have any exception handling defined, our application will stop working. The console window will have the following:
6.4285714285714288
So, we can see that the first method did in fact run, but the third method did not.
Exception Handling
We can keep our application operational by adding a try/catch block around the invocation of the delegate. This will keep our application from completely erroring out:
try
{
act(people);
}
catch (Exception ex)
{
Console.WriteLine("Caught Exception: {0}", ex.Message);
}
And our output now looks like the following:
6.4285714285714288
Caught Exception: Error Here
But something to notice, even though our application continues (and completes normally), the third method still does not run. And this should not be surprising. When an exception is thrown, the system will walk up the call stack until it finds an exception handler. If it does not find one, then the application will error out. In this case, when the exception in the second method is thrown, it walks back up the call stack to the method that invoked the delegate. There it finds the try/catch and handles the exception. But since we exited out of the actual delegate invocation, the third method is not called.
[Update: For a more robust solution, see More Delegate Exception Handling.]
Some Things to Think About
Now let's consider a bit how we use delegates. Generally, we (as developers) are on one end of the delegate or the other -- meaning we are creating a delegate so that other developers can hook into our code, or we are using a delegate to hook into someone else's code.
If we are creating a delegate that we invoke (such as the call to act(people) above), then we should definitely consider wrapping the invocation in a try/catch block. When someone assigns a method to a delegate that we then invoke, we really have no control over what that assigned method does. This means that we need to protect our code to make sure that someone else's mistake does not cause our code to crash. We need to handle any exceptions that are generated by the invocation so that our application can continue to operate (or at least fail gracefully).
Also, as we noted in "Get Func<>-y", we should be checking the delegate before invocation to make sure that it is not null. In this code sample, it would look like the following:
try
{
if(act != null)
act(people);
}...
If we try to invoke a delegate variable that does not have any methods assigned, then we will get a null reference exception. Alternately, we could handle the NullReferenceException in our catch block, but it's usually better to avoid the exception if it can be anticipated.
But what if we're on the other side of the delegate? What if we are a developer who is assigning methods to a delegate to hook into someone else's code? In that case, we need to follow standard practices for error handling in those methods. We could easily add a try/catch block to the method that we assign to a delegate variable. This way we would have the first shot at handling the exception. And since the exception is happening in our code, we are probably in the best position to try to handle it. If we cannot handle the exception, then we can let it bubble up (as we saw in the sample above). How we handle this will depend on the type of delegates that we are working with, what our business processes are, and how we have designed our error handling and failure modes through the rest of the application.
We always need to be on the lookout for the unexpected. In the sample code that shows up in my demos, the error handling has been excluded (just so that we can more clearly focus on the topic at hand). But when building our applications, we need to make sure that we are following good programming practices and making sure that we can handle the exceptions that may occur in our code.
Happy Coding!
Sunday, September 18, 2011
Upcoming Code Camps
Code Camps are a great way to spend a day or two hearing great presentations, talking to other developers, and seeing what's hot in the dev community. Best of all Code Camp is always FREE!
If you are a developer, you have something to share. Sign up as a speaker. It's easy, it's fun, and you'll learn a lot doing it. Here are some tips for Code Camp Speakers: Meet the Next Code Camp Speaker: You!
So Cal Code Camp - Los Angeles, CA
October 15 - 16, 2011
If you're in the Southern California area (or are looking for an excuse to go there), come join us at the So Cal Code Camp. There are a ton of sessions to choose from, lots of developers to meet, and always a good time to be had.
So Cal Code Camp
I'll be speaking. Will you?
Desert Code Camp - Chandler, AZ
November 5, 2011
If you're in the Phoenix area (or are looking for a reason to head out to the desert), come join us at the Desert Code Camp. There are great developers to meet, a ton of variety in the sessions offered, and even session tracks just for kids.
Desert Code Camp
I'll be speaking. Will you?
Hope to see you there!
If you are a developer, you have something to share. Sign up as a speaker. It's easy, it's fun, and you'll learn a lot doing it. Here are some tips for Code Camp Speakers: Meet the Next Code Camp Speaker: You!
So Cal Code Camp - Los Angeles, CA
October 15 - 16, 2011
If you're in the Southern California area (or are looking for an excuse to go there), come join us at the So Cal Code Camp. There are a ton of sessions to choose from, lots of developers to meet, and always a good time to be had.
So Cal Code Camp
I'll be speaking. Will you?
Desert Code Camp - Chandler, AZ
November 5, 2011
If you're in the Phoenix area (or are looking for a reason to head out to the desert), come join us at the Desert Code Camp. There are great developers to meet, a ton of variety in the sessions offered, and even session tracks just for kids.
Desert Code Camp
I'll be speaking. Will you?
Hope to see you there!
Subscribe to:
Posts (Atom)




