Sunday, August 16, 2009
INETA UG Talks This Week
I gave two talks in SoCal this week, one at the San Diego .NET User Group Connected Systems SIG in San Diego and one at the South Bay .NET User Group in Torrance. The San Diego talk was titled Exercise WCF Best Practices and was a collection of practices with context and explanation on employing features and capabilities in the WCF stack in the best way. I talked about server side considerations including interface and layer separation, instancing model, exception handling, security model, and hosting, as well as client side considerations such as proxy creation, caching of proxies, and exception handling on the client side. The slides and demos for this talk can be downloaded here: Slides Demos The Torrance talk was A First Look at WF 4, which covered all the new features coming in WF 4. I covered the new designer, declarative XAML workflows, new activities in the base activity library, the flowchart workflow model, hosting of workflows, arguments, variables, and expressions, workflow services, and runtime improvements to name a few things. The slides and demos for this talk can be downloaded here: Slides Demos
Tuesday, August 04, 2009
TechEd Africa Sessions and Demos
This week I had the pleasure of speaking at TechEd Africa in Durban South Africa. It was a great venue, great attendees with insightful questions, and generally just a lot of fun to get to see a part of the world I’ve never been to while still teaching people about the cool capabilities of the .NET Framework and the best ways to employ those capabilities. I did 5 sessions, briefly outlined here: WUX303: New Tools and Controls for Building Rich WPF Line of Business Apps The real title was something else, horrendously long and un-pronounceable in one breath, but that covers the gist of it. I showed how to use the DataGrid, DatePicker, and Calendar controls that are available for .NET 3.5 development today with the WPF Toolkit. If there are any WPF developers out there that don’t have that as part of their standard development machine set up after installing VS 2008, they are selling WPF short and hindering the user experience for their user (unless they have a third party control library that gives them similar and more functional versions of those kinds of controls). Those controls will also be incorporated as part of the framework in .NET 4.0, so I also demoed their use in VS 2010 along with the great new data binding features in the designer, which closely mimic the capabilities in Windows Form 2.0 that I covered extensively in my data binding book. I also talked about the new WPF Ribbon control and showed its use, and briefly talked about the MVVM pattern, showed an implementation in the demos, and mentioned the MVVM Toolkit that is in development that will make it easier to do. SOA305: Exercise WCF Best Practices In this session, I went through a bunch of best practices for WCF, along with their context, to help people identify practices they should be following regularly when implement WCF services and clients. I covered things like starting your services as PerCall rather than the default of sessionful, exception management on the server and client side, implementing and attaching error handlers, picking a hosting model from IIS, WAS, self-hosting, and eventually Dublin, self-hosting coding patterns, proxy creation and management patterns, and a brief touch on REST vs SOAP at the end. It was a jam packed session and I unfortunately did not have enough time with a 1 hour session to show as many code samples of the practices I was covering as I wanted. SOA401: Developing Service Oriented Workflows This was pretty much the same session I gave at TechEd US, with the exception that I had to cut some content and do less coding from scratch because the session here was only an hour vs 1:15 in the states. SOA201: New Features in WCF and WF 4.0 This was a packed session, standing room only, so obviously a lot of people want to know what is coming down the pike. I covered the new features in WCF 4.0 including simplified configuration, Discovery, Router Service, REST features, and a few others. Then I switched to WF 4.0 since the changes are even more sweeping there and covered the new declarative workflow model, data flow with variables and arguments, workflow services and more. Fun session, just wish I could have twice as much time to give all the great new features better coverage. Whiteboard Session: Are WCF and WF for Mere Mortal Developers? Had good attendance and some great questions and discussions with the attendees about the barriers to adoption with WF, what are some of the scenarios where you should just not bother with WF, where those scenarios change with WF 4 compared to 3, and what some of the pain points are with WF in terms of adoption. There was also a fair amount of discussion on WCF, talking about challenges and solutions as far as managing configuration of services, diagnostics and tracing capabilities, factoring of service interfaces and moving to WCF from other technologies and architectures. For those that attended, thanks! For them and others who want the demo code, here is one zip with all session demos in it.
Thursday, July 23, 2009
Obscure WCF Exception – Mislaid Blame
I lost a couple hours today to perhaps the most obscure WCF error message I have encountered yet. I do tons of WCF and have been working with WCF extensively since 2003 timeframe when I had access to the private betas. I would consider myself a top expert on WCF, and yet this one really was kicking me in the butt. Without a methodical approach to troubleshooting it, I never would have sorted it out. Most WCF errors, after developing a good experience base with the technology, you can rapidly solve. You will either get to know some common ones and know where to jump in your configuration to sort it out, or you can Bing/Google the error message and you will usually find some forum posts where someone suggests the right configuration fix. I was putting together a very simple WCF call from a client to a service, using username security with the WsHttpBindiing. When I got everything set up the way I had done hundreds of times before, I was getting an exception whenever I tried to make the method call on the client. The error I got stuck on was telling me this: Outer exception: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail. Inner Exception: An error occurred when verifying security for the message. OK, fine. I’ve seen those many times before. Went back and quadruple checked all my security settings on both the client and server. All seemed well there. Time to search. Lots of people have apparently had this error, and every solution I found had to do with making sure the clock on the client and server were matched up. Hmm, I’m running client and server localhost. I’m no time-space continuum expert, but I’m relatively certain when two parties reference the same clock, they are in sync. So then it became an exercise in eliminating variables. Change the service method to return null to eliminate some kind of serialization error. No, not it. Snap back to a default WsHttpBinding with no modifications. All works well there. Gotta be the binding. So I look closer at what I had hacked together for a server binding: <wsHttpBinding>
<binding name="MyBinding" maxReceivedMessageSize="20000000">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
<!--Remove the readerQuota or increase its size, problem goes away-->
<readerQuotas maxArrayLength="2000"/>
</binding>
</wsHttpBinding>
Thanks to the fact that I had just observed a conversation on a connected systems email alias regarding maxBufferSize and why it doesn’t exist on WsHttpBinding, it occurred to me that it could be my (arbitrarily chosen) message size or array length.
Sure enough, if I removed the readerQuotas maxArrayLength altogether, or just bump it up by one extra zero, the problem disappeared. I know that there is some coupling between maxReceivedMessageSize and maxArrayLength, but don’t know the specific rules off the top of my head. But I just wanted to get this out there that if you have those errors indicating security problems and you are convinced your security is configured correctly, try tinkering with your sizes in the binding. That could very well be the cause as it was for me.
You can download a sample application that demonstrates the problem here.
Wednesday, July 22, 2009
Implementing Plug-Ins with a DI Container
If you are building a highly extensible application, the right answer these days seems to be to look into MEF. It is a very flexible approach to extensibility and plug ins that works for 3.5 and will become part of the .NET Framework in 4.0. However, sometimes you just need a simple plug in capability to load some components provided by others. If there is any chance those plug ins will depend on each other and need to talk to each other, bite the bullet and learn and use MEF. But if they just need to be loaded up and called, you can use a simple factory to get the job done. About 4 years ago, I put together a little sample of doing this with a generic factory class here. A similar requirement came up with a customer this week, but with one twist: we were already using a DI container (Unity) and the plug ins that were going to load were going to have dependencies on some objects and services that the DI container already knew about. Since the container is really a generic factory itself, I decided to put together a little sample of using Unity as a plug-in factory and thought I would share it here. Defining the Plug-ins The first step to a plug-in architecture is to define the common interface(s) that the plug-ins themselves will implement. Say you have this interface definition in a common library: public interface IPlugIn
{
void DoSomething();
}
Then you define some implementations of that interface in other class libraries (the plug in libraries):
public class PlugIn1 : IPlugIn
{
public PlugIn1(ILogger logger) { }
public void DoSomething()
{
Console.WriteLine("PlugIn1 called");
}
}
Note that this plug in has a dependency on some service (ILogger) that our DI container will know about.
Using the Container As the Plug-In Factory
Now all you need to do is use the ability to configure the Unity container through a config file to have the construction of those plug ins loosely coupled from the code.
Define the config info to configure the container with the plug in types, as well as the dependent types:
<configuration>
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<unity>
<typeAliases>
<!-- Lifetime manager types -->
<typeAlias alias="singleton"
type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
Microsoft.Practices.Unity" />
</typeAliases>
<containers>
<container>
<types>
<type type="Common.IPlugIn, Common" mapTo="PlugIns.PlugIn1, PlugIns" name="PlugIn1"/>
<type type="Common.IPlugIn, Common" mapTo="PlugIns.PlugIn2, PlugIns" name="PlugIn2"/>
<type type="SomeDependencyLibrary.ILogger, SomeDependencyLibrary"
mapTo="SomeDependencyLibrary.Logger, SomeDependencyLibrary" >
<lifetime type="singleton" />
</type>
</types>
</container>
</containers>
</unity>
</configuration>
Then just configure the container and resolve the plug-ins through a call to ResolveAll:
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section =
(UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(container);
IEnumerable<IPlugIn> plugIns =
container.ResolveAll<IPlugIn>();
foreach (IPlugIn plugin in plugIns)
{
plugin.DoSomething();
}
And viola. you have a simple plug-in factory using the container.
Sunday, July 12, 2009
Comments on The Myth of Developer Productivity
Scott Bellware put together a great post emphasizing the importance of organizational productivity over developer productivity that I wanted to point people to and make some additional comments on. In his post, Scott points out the pitfalls of focusing only on developer productivity as a way to ship your product faster. He elaborates on the fact that if you don’t have a good quality-focused process and organization, the short term gains (or local optima as he describes them) created by developer productivity or efficiency tools may actually compound your problem in several ways. Organizational Productivity I totally agree with several things Scott points out in his post. First, a lot of the customers I deal with in consulting do have immature processes and organizations, so they need to fix those first and foremost if they really want to ship higher quality products faster. Following agile practices including the following are some of the minimum bars I think development teams should be targeting for most business applications: - Practicing Scrum or having daily stand up meetings to facilitate team communications and collaboration
- Practicing Pair Programming or at a minimum having diligent code reviews on all production code
- Practicing TDD/BDD/DDD or at a minimum having a high degree of unit test coverage combined with a good loosely coupled design
- Documenting requirements in a light weight, but easy to understand and location form (user stories, bullet lists, work items all suffice if done coherently)
- Having a good CM process including good source control tools
- Having an automated build process that runs nightly at a minimum, or better yet trending to continuous integration
There is a lot more to having a good agile process in place than I can document here, but the point is that too many teams recognize that these are things they should be doing, but they never get around to establishing as a repeatable part of their process. Then they hear about developer productivity tools and think that just by using those, they will somehow overcome the organization-level lack of productivity with the micro-productivity enhancements that developer productivity tools can often have. The Hazard of Developer Productivity Tools Also as Scott points out, when used blindly, some developer productivity tools can actually cause grave damage to product-level productivity. One example of this includes some of the developer productivity tools in Visual Studio, specifically some of the code produced by designers and code generation. This has gotten better from version to version, but there is still the tendency to put things into Visual Studio that demo well and might be OK for toy applications, but should never be used for serious applications. For example, the SqlDataSource in ASP.NET encourages developers to drag and drop their way to a functional data driven page. Looks great, and you are done in minutes. Developer productivity nirvana. But what happens after that? You end up with hundreds of these scattered across your project, each with embedded markup tightly coupling the page to the database schema. Bad, bad, bad for overall productivity in developing a product because it is a maintenance nightmare. But these kind of features are often hyped in the VS demos as if it will make you able to ship your product so much faster. It might let you get a simple first version out the door faster. But even the first version of a moderately complex app will suffer in timeline as the schema changes throughout the development cycle and you have to keep tracking down the resulting breakage in the tightly coupled pages. The remedy is taking the time up front to put a good layered design in place, and use the right developer productivity tools in the right way (i.e. bind an ObjectDataSource to the domain objects coming out of a repository) to speed up the coding process slightly, but not end up with messy un-maintainable code from using them. Another hazard I see with developer productivity tools (VS ones in particular) are that especially for less experienced developers, it tends to teach them that if they can’t do it through the tool, it can’t be done. I had this at a customer site the other day. We were using a mapping component, and the developer came in complaining something that we needed to do wasn’t supported by the component. After drilling into the problem, it turned out that what the developer really meant is “my Visual Studio integration for that component is not working, and if I can’t drag and drop it and hook things up in the designer, I have no clue how to code against the component itself”. If you are going to use any developer productivity tool, the developers have an absolute responsibility for understanding what the generated code does, and how to write that code themselves if the tool is not available or is not doing things quite right. If they are going to use features that produce code that is not great for long-term productivity, they need to fix the code to make it more maintainable as soon as the code is generated. If fixing the generated code right then takes them longer than it would have to code it all by hand, then they shouldn’t be using the tool in the first place. Another example is the WCF proxy generation in Visual Studio. While it is great for quickly the code in place to make calls to a service that exposes metadata, the proxy code that it generates is usually much more verbose than it needs to be, and it can totally garbage up your app.config or web.config file with unnecessary configuration elements that become your maintenance burden. It is usually more productive from an overall productivity perspective to do what we call “hand coding” the proxy. The Benefit of Developer Productivity Tools and Why You Should Still Use Them - Correctly However, that being said, I am a firm believer in not wasting developers time, as well as trying to keep developers focused on the logic they are implementing, instead of spending too much time banging on the keyboard and worrying about the structure of the code instead of its content. So even when I say “hand coding” above, I would prefer to use a developer productivity tool such as CodeRush + Refactor, ReSharper, or just Code Snippets in Visual Studio to output clean, templated code for those places where repetitive coding patterns are required. If possible, I would then look for opportunities to refactor some of that repetitive code into base classes or helpers, but that is not always possible. So I actually often say that I firmly believe that every developer should have a copy of CodeRush+Refactor or ReSharper on their machine, and should spend a little time learning how to use the basic features of those products right. As Scott points out, doing so is not going to affect your overall timeline one bit if you don’t already have a highly efficient and streamlined organizational process. And if the developers don’t understand the code that is being spit out or when it is appropriate, it is again a liability , but that again comes back to professional responsibility of being a good developer. But at a minimum, I do think the tools mentioned above save the developers tons of time in terms of not wasting time banging out snippets of code character by character, but instead lets them spit out the right code with minimal keystrokes. This frees their time and their mind to focus more on the logic of the code instead of the structure. It also lets them blaze through throw away implementation of prototypes and spikes much faster than if they didn’t have those tools, and if done right, that code is getting dumped once you figure out what you are going to do and how to do it anyway. Using CodeRush/Refactor or ReSharper also tend to produce better consistency in the code, because if the tool templates are spitting the small structural elements out, those elements are more likely to be coded consistently across developers. Finally, both of those tools have great features for continuous refactoring of code to clean up things like redundant/unused declarations, replacing string concatenation with string.Format, and hundreds of other things that might otherwise be missed, or just take more time to do manually than they do using the tool. Wrap Up So bottom line, I agree with almost everything Scott says in his post. I just think in some places it paints an overly negative picture of developer productivity tools and could lead someone like a product manager to say “I don’t need to buy my developers these tools because they won’t help anyway”. If you don’t focus first at the process level, you still won’t ship your products any faster by using developer productivity tools. But I think with the right tools and the right approach to using them, you will still improve the quality of the code the developers are producing by using these tools, and that is worth it in its own right. And you may get through the experimentation implementation portions of your lifecycle a little faster as well. But don’t fool yourself into thinking that just throwing these tools at the developer is all you need to do. And also approach any developer productivity tool with jaded optimism and get a real understanding of what it is producing and what the long term impact of that code is before you think it is really going to save you any time before committing to using it for production coding.
Saturday, May 30, 2009
Debuggable Self-Host Windows Service Projects
When developing self-hosted WCF services, you really need two things: - A windows service project that will be the host for the deployed environment.
- A console self-host project for easy debugging while developing the service.
Yes, there is also the option to use a WCF Service Library project with its associated WcfServiceHost.exe process that self hosts the service for debugging. However, I have run into too many occasions where something is going wrong and not having direct access to the hosting code wastes more cycles than it takes to set up my own service host, so other than quick demos, I never use the WcfServiceHost.exe in production development. Having two separate projects to address 1 & 2 above is not really that great either, but if you try to run a service project in the debugger, you get an error telling you it can only be run through the services panel in Windows. However, through a quick and easy pattern, you can make your service projects so they run as a console for development, but run as a service just fine when installed. Step 1: Create a Windows Service project for the self host environment. This is just the standard selection in the project dialog for a Windows Service project. Once you have your service class, rename it as appropriate and right click on the designer surface to add an installer class for the service. Standard stuff here. Step 2: Implement your hosting code in a separate class from the service class itself. For example, here is a very simple hosting class that can be used for any service in any project (with some appropriate exception handling and logging added in for production purposes): public class SelfHost<T>
{
ServiceHost m_Host;
public void Start()
{
m_Host = new ServiceHost(typeof(T));
m_Host.Open();
}
public void Stop()
{
m_Host.Close();
}
}
From the service class itself, you can just instantiate an this class and call its Start and Stop methods.
public partial class SimpleServiceHostService : ServiceBase
{
SelfHost<SomeService> m_Host = new SelfHost<SomeService>();
public SimpleServiceHostService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
m_Host.Start();
}
protected override void OnStop()
{
m_Host.Stop();
}
}
Now when you install this service, the service host will be started and stopped through the services panel or automatically depending on the service configuration.
Step 3: Modify the Main method to start conditionally as a Console or a service.
Modify the default main declaration with no parameter to the signature for a main that takes a string[] of arguments. If arguments are present, run the code as if you are in a console app. If no arguments, call the default code for starting it as a service. For the console host mode, just call the Start and Stop methods on an instance of your host class just like the windows service did.
static void Main(string[] args)
{
// Run as console if there are command line arguments
if (args.Length > 0)
{
SelfHost<SomeService> host = new SelfHost<SomeService>();
host.Start();
Console.WriteLine("Press Enter to Exit...");
Console.ReadLine();
host.Stop();
}
else // run as service
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new SimpleServiceHostService()
};
ServiceBase.Run(ServicesToRun);
}
}
Step 4: Modify the project properties to be a console application and add a debug command line parameter.
That is basically it. Change the code shown above to use your service type, add an app.config with the appropriate WCF service code, and you are ready to run as a console app in the debugger, but when you build and install your service as a service, it will run fine as that as well.
You can download a full sample application here.
Wednesday, May 13, 2009
TechEd SOA401 – Developing Service Oriented Workflows
This morning I am giving the subject session at TechEd. For those of you that attended, thanks! You can probably jump to the link at the bottom for the demos unless you want a quick review of what we covered by reading the rest of this post. This session discusses .NET 3.5 Workflow Services, and I also touch on what is different in .NET 4.0 throughout and at the end. I also have a brief discussion at the end about cloud workflows, using workflow activities from .NET Services and running workflows in the cloud with Windows Azure. In the talk, I demonstrate the use of the ReceiveActivity for exposing service operations from a workflow. I show how to add the receive activity to a workflow, hook it up to a service contract and the operations on that contract, how to bind the incoming parameters to other workflow properties and how to retrieve the return result from workflow properties through a binding. I then show how to host the workflow as a service using the WorkflowServiceHost class, how to get a reference to the WorkflowRuntime from the host (to hook up to workflow events), and how to configure the right bindings (context bindings) to expose the workflow. Then I write a quick client that is able to call the workflow to get it running and pass parameters to it. Then I jump to a more complicated workflow that represents a loan application process as a state machine workflow. The loan application is submitted through a service call, and then approve or reject actions can be taken through service calls. I show how calls from the same client work out automatically through the passing of the instance ID through the context bindings, and how to allow multiple clients to interact with the same workflow by setting and getting the instance ID out of the context. Then I show that the loan application workflow also needs to make service calls out to another credit checking service. So I demonstrate how you can use a SendActivity to act as a dynamic proxy in the workflow to call another service. Like the ReceiveActivity, you use bindings on dynamic properties to provide values for the outgoing parameters and to deal with any returned values. I also discuss the limitations of the SendActivity and how to work around it by creating a simple custom activity to encapsulate a normal WCF proxy over which you have complete control. Then I show an application that is composed of two workflows, a parent workflow and a child workflow. The parent invokes the child workflow and gets results back from the child. The trick with this scenario is how you need to pass the context to the child workflow of the receive activity that the call will come back into in the parent workflow so that the workflow runtime can reassociate the incoming call with the right instance and right receive activity. If you want to take a look at the demos that do all of the above, here you go.
Thursday, May 07, 2009
NoVa Code Camp – 23 May
Update: Apparently I found a wormhole this morning and stated January instead of May. That would be May 23!
We have a code camp coming up on Saturday 23 May in Northern Virginia at the Reston Microsoft Training Center at 12012 Sunset Hills Rd, Reston, VA. There is a great line up with 4 tracks and over 20 speakers. I’ll be giving a session on Developing Service Oriented Workflows, come out and expand your brain!
|






| January, 2012 (1) |
| November, 2011 (4) |
| October, 2011 (1) |
| September, 2011 (2) |
| August, 2011 (1) |
| July, 2011 (1) |
| May, 2011 (5) |
| March, 2011 (4) |
| February, 2011 (2) |
| January, 2011 (3) |
| November, 2010 (4) |
| October, 2010 (1) |
| September, 2010 (5) |
| August, 2010 (5) |
| July, 2010 (6) |
| June, 2010 (8) |
| May, 2010 (2) |
| April, 2010 (2) |
| January, 2010 (1) |
| December, 2009 (3) |
| November, 2009 (2) |
| October, 2009 (3) |
| September, 2009 (3) |
| August, 2009 (2) |
| July, 2009 (3) |
| May, 2009 (3) |
| April, 2009 (2) |
| March, 2009 (1) |
| February, 2009 (2) |
| January, 2009 (2) |
| December, 2008 (1) |
| November, 2008 (2) |
| October, 2008 (5) |
| September, 2008 (4) |
| August, 2008 (2) |
| July, 2008 (1) |
| June, 2008 (2) |
| May, 2008 (2) |
| April, 2008 (3) |
| February, 2008 (6) |
| January, 2008 (3) |
| December, 2007 (1) |
| November, 2007 (1) |
| October, 2007 (5) |
| September, 2007 (1) |
| July, 2007 (3) |
| June, 2007 (8) |
| April, 2007 (2) |
| March, 2007 (4) |
| February, 2007 (1) |
| December, 2006 (2) |
| November, 2006 (9) |
| October, 2006 (5) |
| September, 2006 (3) |
| August, 2006 (2) |
| July, 2006 (4) |
| June, 2006 (5) |
| May, 2006 (10) |
| April, 2006 (4) |
| March, 2006 (2) |
| February, 2006 (12) |
| January, 2006 (7) |
| December, 2005 (2) |
| November, 2005 (15) |
| October, 2005 (6) |
| September, 2005 (7) |
| August, 2005 (3) |
| July, 2005 (10) |
| June, 2005 (11) |
| May, 2005 (7) |
| April, 2005 (8) |
| March, 2005 (6) |
| February, 2005 (2) |
| January, 2005 (6) |
| December, 2004 (3) |
| November, 2004 (5) |
| October, 2004 (2) |
| September, 2004 (5) |
| August, 2004 (13) |
| July, 2004 (6) |
| June, 2004 (14) |
| May, 2004 (17) |
| April, 2004 (12) |
| March, 2004 (8) |
| February, 2004 (10) |
| January, 2004 (14) |
| December, 2003 (9) |
| November, 2003 (13) |
| October, 2003 (3) |


Sign In
|