Yesterday, the first ever TechMixer University was held at the BJCC. Hats off to the organizers of the event. It seemed to be very well planned and coordinated. Everyone that I spoke with was enjoying themselves. I hope there will be more of these events in the future. They are great for building the overall technical community in the Birmingham area.
Right after lunch, I gave a presentation entitled "Hit the Ground Running with WCF Services." It was an introduction to some of the core concepts in WCF. Based on a rough estimate, I would say about 40 or so were in the session. I greatly appreciate the feedback that I received from several attendees. Hopefully, it will ease the learning curve for some of you.
As promised, I have posted the slides and code for my presentation. You can download it here. If you have any questions, feel free to ping me at jeff _ at_ jeffbarnes.net.
There will be a special presentation by Sara Ford on Monday, August 25th about Visual Studio IDE Tips and Tricks. For those of you that don’t know, Sara Ford maintains the popular blog Visual Studio Tip of the Day and works on the CodePlex team. She will be passing through the Birmingham, AL area after the DevLink event and has graciously agreed to drop by and give a talk to the area. It will be held at the Southern Living Auditorium on the Southern Progress Campus located at 2100 Lakeshore Drive. Here is a link to the event registration with complete details: https://www.clicktoattend.com/invitation.aspx?code=130429
Those of you that know me are already aware how I am a big advocate of time savers in the IDE. This will be a great opportunity to learn a few things to add to your bag of tricks for getting things done in Visual Studio. I hope to see you there!
Here is the abstract for the presentation:
Performance improvements begin by speeding up the simple task you do every minute of every hour of every day you use Visual Studio. Just like a coin jar where you place your spare change, you’ll see the time you save add up into the days, weeks, and into the months. This talk provides the best of the best, 21 tips that can be used in any language, which stretched across your 3 primary activities in the IDE: coding, customizing, and debugging.
Sara Ford is the program manager for CodePlex, Microsoft’s open source project hosting site. Prior to CodePlex, she worked on the Visual Studio team for six years, where she continues to run the Visual Studio Tip of the Day on her blog. Her life-long goal is to become a 97 year old weightlifter, so she can be featured on the local news.
On Tuesday, August 19th, TechMixer University will be held in Birmingham, AL. This will be a large community driven training event that covers a wide spectrum of technologies. The organizers have strived to offer a little something for everyone including developers, database professionals, project managers, and network professionals. The event also provides coverage of non-Microsoft technologies such as Oracle, MySql, and Ruby.
Even if you can’t attend the entire event, I would encourage you to drop by for one or two sessions that interest you. Visit the website for complete details: http://www.techmixeruniversity.com/TechMixer_University.html
I’ll be delivering a session on WCF entitled “Hit the Ground Running with WCF Services”. Here is the abstract:
Windows Communication Foundation (WCF) is a major advancement within the Microsoft .NET platform that allows for easily exposing units of functionality as services that are accessible via a broad spectrum of communication protocols. WCF has been built from the ground up around a highly flexible and extensible model that allows developers to concentrate on business problems rather than the details of communication plumbing. Write your business logic once and simply expose it over the necessary protocols via configuration without changing a line of code! If this sounds interesting, please join me for a crash course in the fundamental concepts of WCF. This session is packed with material and strives to significantly reduce the learning curve for those that are new to the technology by providing an introduction to major features and capabilities of the WCF platform.
In case you haven't heard, Microsoft has formally announced plans to provide a service pack (SP1) for Visual Studio 2008 and .NET Framework 3.5 by the end of the year. There is a long list of items that will be included, but the most notable one to me was the ADO.NET Entity Framework.
I'll avoid repeating all of the information here. My intent was to simply help propagate the information to the masses. For all of the details, go read Brad Abrams' extensive blog post about the framework portion of the news. The WebDev Tools Blog also has a long blog post that details more of the Visual Studio portion of the release. You should also listen to the latest episode of Dot Net Rocks (Show #340). Carl Franklin and Richard Campbell interviewed Brad and Omar Khan about a lot of the details.
Over the next few months, I will be closely following this release and tinkering with the betas as much as possible. Once EF is officially released, I'm hoping to get it into my production environment as soon as possible.
It is an exciting time to be a .NET developer!
In case you haven't heard, it was formally announced that a new release of BizTalk Server 2006 is being planned to provide better support for Windows Server 2008, SQL Server 2008, and .NET Framework 3.5.
Here are the major highlights:
- New web service registry capabilities with support for UDDI (Universal Description Discovery and Integration) version 3.0
- Enhanced service enablement of applications (through new and enhanced adapters for LOB applications, databases, and legacy/host systems)
- Enhanced service enablement of “edge” devices through BizTalk RFID Mobile
- Enhanced interoperability and connectivity support for B2B protocols (like SWIFT, EDI, etc)
- SOA patterns and best practices guidance to assist our customer’s implementations
The major goodness will still have to wait for Oslo. :)
Next week, the annual Microsoft MVP Summit will be held in Seattle. The event runs for four days and will be split between the Washington Convention Center and Microsoft's campus in Redmond. The majority of my focus will be on Oslo. At this point, I'm not sure how much of the information will be subject to NDA, but I will definitely pass along any interesting tidbits that are eligible for disclosure.
If nothing else, I'm sure that I will be twittering a lot during the week. So, you can follow along with what's happening via my twitter feed: http://twitter.com/jeff_barnes. I'm looking forward to the opportunity to hang out and speak geek with a number of other MVPs and Microsoft employees. It has been far too long since I have spoken with a number of those guys due to my crazy workload over the last couple of months.
Between work and stuff going on in my personal life, there hasn't been a lot of spare time for blogging and developer community things over the last few weeks. Hopefully, that will be changing in the near future. In the meantime, I wanted to squeeze in a quick blog post about something that came up today regarding StringBuilder.
It was pointed out someone on my team was concatenating several strings to build a query in a few methods. It is arguable whether these particular queries should be embedded in the source code, but that isn't what this post is about. It was requested that the developer modify the source code to use a StringBuilder rather than concatenating the strings. Generally speaking, I would agree with this approach as the StringBuilder is more efficient when concatenating several strings, but this wasn't one of those cases.
Consider the following two methods:
public static string LiteralConcatenationExample()
{
return "SELECT T1.Field1, " +
"T1.Field2, " +
"T1.Field3, " +
"T2.Field4 " +
"FROM Table1 T1 " +
"INNER JOIN Table2 T2 ON T1.Field1 = T2.Field1";
}
public static string StringBuilderWithLiteralsExample()
{
StringBuilder sb = new StringBuilder();
sb.Append("SELECT T1.Field1, ");
sb.Append("T1.Field2, ");
sb.Append("T1.Field3, ");
sb.Append("T2.Field4 ");
sb.Append("FROM Table1 T1 ");
sb.Append("INNER JOIN Table2 T2 ON T1.Field1 = T2.Field1");
return sb.ToString();
}
Which method do you think would be more efficient?
If you chose the second method, you should take a closer look at the generated IL:
.method public hidebysig static string LiteralConcatenationExample() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init ([0] string CS$1$0000)
IL_0000: nop
IL_0001: ldstr "SELECT T1.Field1, T1.Field2, T1.Field3, T2.Field4 "
+ "FROM Table1 T1 INNER JOIN Table2 T2 ON T1.Field1 = T2.Field1"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method Program::LiteralConcatenationExample.method public hidebysig static string StringBuilderWithLiteralsExample() cil managed
{
// Code size 90 (0x5a)
.maxstack 2
.locals init ([0] class [mscorlib]System.Text.StringBuilder sb,
[1] string CS$1$0000)
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldstr "SELECT T1.Field1, "
IL_000d: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
IL_0012: pop
IL_0013: ldloc.0
IL_0014: ldstr "T1.Field2, "
IL_0019: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
IL_001e: pop
IL_001f: ldloc.0
IL_0020: ldstr "T1.Field3, "
IL_0025: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
IL_002a: pop
IL_002b: ldloc.0
IL_002c: ldstr "T2.Field4 "
IL_0031: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
IL_0036: pop
IL_0037: ldloc.0
IL_0038: ldstr "FROM Table1 T1 "
IL_003d: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
IL_0042: pop
IL_0043: ldloc.0
IL_0044: ldstr "INNER JOIN Table2 T2 ON T1.Field1 = T2.Field1"
IL_0049: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
IL_004e: pop
IL_004f: ldloc.0
IL_0050: callvirt instance string [mscorlib]System.Object::ToString()
IL_0055: stloc.1
IL_0056: br.s IL_0058
IL_0058: ldloc.1
IL_0059: ret
} // end of method Program::StringBuilderWithLiteralsExample
As you can see, the string concatenation is considerable more efficient. This may be a bit confusing to some people as you have undoubtedly had it hammered into your head that a StringBuilder should be used when concatenating strings. Well, I would agree when you are dealing with dynamic strings that are built using parameters. However, literal strings are a different story.
Since this scenario is using literal strings, the compiler can optimize the values into one large string that can be loaded with a single load string operation (ldstr). If the code is modified to use a StringBuilder for each line of the query, it actually increases the number of operations by four for each line of the query.
In fairness, most situations will probably be dealing with dynamic strings, which would change this scenario back to favor the usage of a StringBuilder. However, you should keep in mind that a StringBuilder doesn't automagically give you a more efficient solution in every situation, especially if you are only concatenating a few strings.
The last time that I purchased a computer was 2003. I bought all the parts and built my own gargantuan desktop, which has been my faithful servant for the nearly five years. Unfortunately, all good things must come to an end. Although my old desktop would still get the job done, it was becoming noticeably outdated. During the last few years, I have also found myself becoming more and more dependent upon the need for a laptop. It is a little difficult to drag around a mammoth desktop to code camps and user groups when I'm doing a presentation. While my employer issued laptop was adequate, it certainly left a lot to be desired.
After debating for some time as to whether I wanted another desktop or a kick ass laptop, I finally decided it was time to say good bye to my desktop. It is difficult for me to come up with many valid reasons for going the desktop route again. Five years ago, I was a fairly intense MMORPG gamer, but I have finally beaten that addiction and have no desire to return to such a waste of time (albeit a fun waste of time). My gaming itch is now satisfied via XBox 360. Games that can be paused are much more attractive to me these days. Since PC gaming is removed from the picture, a laptop was the logical choice.
After researching quite a few options and waiting for the right deal to come along, I finally went with the Dell XPS M1530. It was the perfect balance between price and power. I have spent many hours over the last several nights trying to get it setup with all of my software and various tweaks. Finally, it is beginning to feel like home rather than a stranger's computer.
Here is a photo of the model that I bought as well as the specs:
- Intel Core 2 Duo Processor T7500 (2.2Ghz / 800Mhz FSB / 4MB L2 Cache)
- 4GB DDR2 667Mhz
- 200GB 7200RPM SATA (with Free Fall Sensor)
- 256MB NVIDIA GeForce 8600M GT
- 8X DVD+/-RW Slot Load Drive
- Intel 4965AGN Wireless N Mini-Card
- 85 WHr 9-cell Lithium Ion Primary Battery
- Integrated Biometric Finger Print Reader
- Integrated Web Camera
As I write this post, my old desktop is being reformatted and reinstalled with Windows Server 2003. It will now become a file server for my wife and me, and it will probably serve a few other experimental purposes as well. I would love to have loaded Windows Server 2008 on it, but the hardware isn't 64 bit. At least, my old companion will continue to live on in some other capacity rather than being sent to the big hardware dumpster in the sky.
In .NET 3.0, WCF did not have any built-in support for syndication feeds, such as RSS and ATOM. As a result, it was necessary to roll your own solution anytime you wanted to render a syndication feed from your service. While this wasn't an incredibly difficult task, it was still rather tedious. Fortunately, .NET 3.5 introduced rich support for easily enabling syndication feeds from your service with relatively little effort. Overall, it does a great job of handling the dirty work for you. Let's take a look at how to set it up.
For this example, let's say that you have a WCF service that provides product information. We want to enhance this service to provide an RSS/ATOM feed containing the product information. The first thing we need to do is setup our service contract.
[ServiceContract(Namespace = "JeffBarnes.Samples.Syndication")]
[ServiceKnownType(typeof(Rss20FeedFormatter))]
[ServiceKnownType(typeof(Atom10FeedFormatter))]
public interface IProductService
{
[OperationContract]
[WebGet(UriTemplate = "/product/{code}")]
Product GetProduct(string code);
[OperationContract(Name = "GetAllProducts")]
[WebGet(UriTemplate = "/products?format={format}")]
SyndicationFeedFormatter GetProductSyndicationFeed(string format);
[OperationContract(Name = "GetProductsByCategory")]
[WebGet(UriTemplate = "/products/{category}?format={format}")]
SyndicationFeedFormatter GetProductSyndicationFeed(string category, string format);
}
If you are familiar with WCF services, the ServiceContract and OperationContract attributes should already be familiar to you. Depending upon whether you have written many advanced services, you may also be familiar with ServiceKnownType. If not, it is essentially used to inform the WCF runtime that it needs to be aware of a specific type for the purpose of serialization.
The WebGet attribute is a newcomer in .NET 3.5. It is part of the new REST stack. I have already written about WebGet in a previous post. You should refer to it for a more thorough overview. The abridged version is that it allows the WCF runtime to dispatch HTTP GET requests that match the specified UriTemplate to the given method. As you can probably discern from the code, the GetProductSyndicationFeed method returns a feed of products in a specified format (RSS or ATOM).
So, what does the implementation look like? I'm going to trim it down to the most interesting pieces for the sake of brevity.
// Create the syndication items from the products.
IEnumerable<SyndicationItem> items =
from product in products
orderby product.Code
select new SyndicationItem(...);
// Create the syndication feed.
SyndicationFeed feed = new SyndicationFeed(
"Jeff's Product Catalog",
feedDesc,
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri,
items);
// Determine the format to use.
SyndicationFeedFormatter formatter = null;
if (String.Compare(format, "rss", true) == 0)
{
formatter = new Rss20FeedFormatter(feed);
}
else
{
formatter = new Atom10FeedFormatter(feed);
}
return formatter;
First, a LINQ query is used to construct an enumerable collection of SyndicationItems based upon the product information. SyndicationItem offers a lot of flexibility and extensibility. It provides seamless support for formatting your content as html, xml, or custom formats. Next, the SyndicationItems are supplied to a SyndicationFeed that decorates the items with some other information. Ultimately, the SyndicationFeed is wrapped by a feed formatter. Depending upon the requested format, either RSS or ATOM will be used.
There is one last gotcha to keep in mind in regards to the hosting of the service. In order to enable the REST stack, there is a specific binding and behavior that must be used: webHttpBinding and webHttpBehavior. You can manually set these up via configuration. However, there is a new ServiceHost subclass available that offers a configuration free alternative. Check out the following snippet:
using (WebServiceHost host = new WebServiceHost(typeof(ProductService), new Uri("http://localhost:8000/ProductService")))
{
host.Open();
Console.WriteLine("Service Ready");
Console.Read();
}
WebServiceHost will automatically create an endpoint with the necessary binding and behavior to enable the REST stack. I don't even have a configuration file in this demo. The only configuration code is what is shown above. If you are using IIS to host your service, you can still use WebServiceHost, but it requires referencing System.ServiceModel.Activation.WebServiceHostFactory from your SVC file.
Once you get everything wired together, it's as easy as typing a URL into your web browser of choice and viewing the results. Most browsers are aware of syndication feeds and apply special formatting to them. For example, here is a screen shot of IE when you hit http://localhost:8000/productservice/products/Beverage for the demo.
I have barely scratched the surface of the capabilities of the syndication infrastructure in WCF, but this example effectively demonstrates how little effort is required to get started. I'll probably do some additional posts on some of the more advanced syndication abilities at some point in the future.
You can download the complete sample here.
Due to the persistence of Keith Elder, he has managed to convince several of the speakers at Alabama Code Camp to either sign up for Twitter or start using it again. Some of the suckers that fell into the trap include Robert Cain (Arcane Code), Todd Miranda, and Doug Turnure.
Several months ago, I signed up for Twitter and managed to stick with it for a little while, but it became too much effort. One of the biggest gripes that I had with it was the limited abilities to send updates. At the time, you were restricted to the web site or text messages from your phone. Personally, I'm not a huge fan of text messaging, especially when I'm sitting at the computer. There was supposedly an IM interface, but it never worked.
Fast forward to present day and it appears as though their web site has been greatly improved. Twitter has opened up some web services that have enabled a number of custom clients to be created. Keith was a big advocate of Witty, which is a WPF smart client. (What a shocker...Keith evangelizing a smart client application). After getting it downloaded and setup, I have to admit that it is quite nice. The application has that smooth WPF look and it appears to be fairly responsive.
So, I have made my return to Twitter. For the last couple of days, I have been sending periodic updates. Admittedly, I can feel it becoming somewhat addictive. When there is a moron at the office causing the day to suck tremendously, it provides a nice little outlet to let everyone know about it. If you are interested in following stalking me, here is the link to my twitter feed: http://twitter.com/jeff_barnes.
More Posts
Next page »
Disclaimer:The opinions and views expressed within this blog are solely my own and do not represent those of my employer or anyone else.