Ben Lovell has started a great series on incremental development with MonoRail. This is exactly what a new (and not so new) Castle or MVC or TDD developer needs to get going in the right direction. He even is posting the code on Google. Great work, Ben!
Monthly Archives: April 2008
JSONP Support Added to ArcDeveloper REST
I have previously blogged about the ArcDeveloper REST Service that a few of us ESRI .NET developers have thrown together. Until today, the only format you could request was GeoJSON. Now, through the miracle of something-I-needed-on-a-project, I have added JSONP support to the project. For those of you who don’t know what JSONP is, it is JSON wrapped in a javascript call. So, if you have JSON that looks like:
“type”: “FeatureCollection”,
“features”: [
{
“type”: “Feature”,
“geometry”: null,
“properties”: {
“Facility”: “SI”,
“Shape_Area”: “4.93182604749608E-05”}
},
{
“type”: “Feature”,
“geometry”: null,
“properties”: {
“Facility”:”Test”,
“Shape_Area”: “2.27729778462692E-05”,
}
} ]
}
With JSONP, it looks like:
 ‘jsonpCallComplete(json)’, then the script block comes back as: ‘f’ querystring parameter (i.e., f=json or f=jsonp) which maps to a ‘format’ parameter on the service methods. The value of the ‘f’(‘dojo.io.script’) for this to ‘load’.
I’ll edit the post if I hit other issues in the testing.
Here’s What I Like!
I read a lot of blogs, and many of them have a page dedicated to utilities they use and books they like. Those blogs are cool, and I want to be like them. So, here is my page of tools and books (and frameworks). I plan to add to it as I remember stuff or find new toys. Feel free to suggest any.
Castle Windsor and WCF: A Match Made in Heaven
(Note: I’ve been out for a bit due to new recent additions to my life. The first was a (third) daughter born 2 weeks early and the second is an aggressive vasectomy schedule. Too much information, you say? I agree.)
If you’ve read any of my other posts, you know I dig Castle Windsor. It’s cool and allows a “special” developer like me to look pretty smart without actually being all that smart. I also really like WCF, as I feel it lead the charge of “things Microsoft started getting right”, again helping me look smart by abstracting all the WS-*** and other service gobblety-gook out of my life. Since I REALLY like both of these technologies, I was hesitant to put them together, fearing I couldn’t take the shear joy it would create. However, Ayende and Craig have created the WCF Facility, allowing me to register my services on the Windsor container, and thus use dependency injection to handle all the stuff my services need. This post is a (hopefully) quick “how to” on this really cool facility.
(Note: This is my first foray into using Binsor for Windsor Configuration. All the smart guys were using it while I was still XMLing in the dark ages, so I had to follow suit.)
Step Uno: Write a Service
Let us create a simple WCF service. It looks like:
[ServiceContract()]
public interface IService1
{
[OperationContract]
string MyOperation1(string myValue);
[OperationContract]
void ThrowError();
}
public class Service1 : IService1
{
private ILogger logger; //Yes, yes, should init to a NullInstance.
public ILogger Logger
{
get { return logger; }
set { logger = value; }
}
#region IService1 Members
public string MyOperation1(string myValue)
{
logger.Info(“MyOperation1 called with {0}”,myValue);
return “Hello: “ + myValue;
}
public void ThrowError()
{
throw new Exception(“AAAAAAH!”);
}
#endregion
}
So, you see the service contract, you see the implementation. Please notice the following details:
- I added an ILogger property. This is a dependency.
- There is a method that just ralphs an error. Usually I am not as obvious with my errors, but at least I will be able to debug this one.
Usually, at this point, you’d open up the web.config file and start writing mountains of <service> tags and <behaviors> and all that. We aren’t going to do that. We are going to bring in Windsor to take care of all our needs. Yay!
Bring in da Noise, Bring in da Windsor
I am going to presume that you, the reader, knows about Windsor and, at least at a high level, how to configure it. Basically, for a web app (we are gonna host our services in IIS) you need to:
- Write the configuration files for Windsor, consisting of properties, facilities, and components. Go read the castleproject.org site for some decent examples.
- Register the container at startup.
As I stated previously, I am using Binsor to write my config files. (Tangent: I need to learn Boo. Ayende, is that book done yet?) Here goes:
import System;
import System.Reflection
import System.ServiceModel
import System.ServiceModel.Description from System.ServiceModel
import Castle.Facilities.Logging
import Castle.Facilities.WcfIntegration
import Ruprict.Grok.Castle.WcfIntegration.Core
facility LoggingFacility:
loggingApi = LoggerImplementation.Log4net
configFile = ‘log4net.config’
facility WcfFacility
component ‘windsor.service’, IService1, Service1:
ServiceModel = WcfServiceModel().Hosted() \
.AddEndpoints(WcfEndpoint.BoundTo(BasicHttpBinding()))
component ‘error.handler’,IServiceBehavior, LogExceptionHandler
component ‘metadata.behavior’,IServiceBehavior, ServiceMetadataBehavior:
HttpGetEnabled = true
This is Binsor 2.0 syntax, which is (from what I understand) yummier than ever. I do like it. It’s compact and readable and I don’t end up getting errors b/c I forgot to close a tag. Looking at the import statements, you see I bring in whatever namespaces I need, including my service namespace and any of it’s dependencies. Here, I’ve yanked in the ServiceModel stuff from WCF so I can hook up my IServiceBehavior extension classes, as well as some other Castle Facility namespaces (namely, the Logging facility). Then, I start defining things. I grab the LoggingFacility from Castle, telling it I am using Log4Net and pointing it at the right config file. Then it’s on to the star of our show, the WcfFacility. It seems odd that it just takes two words to bring in a facility that does so much. Ahh, simplicity, you are truly beautiful. Anyhoo, the first component is my WCF service (line 16) where you can see that I add a singular endpoint, bound to the BasicHttpBinding, um, binding. (NOTE: If you are using the BasicHttpBinding, like I am here, you don’t even have to specify a service model, as the facility will deduce it from the base address.) Finally, I add 2 more components, both IServiceBehaviors. For those that don’t know, IServiceBehavior is a way to extend WCF by create custom service (there are also endpoint and operation behaviors, all of which are treated the same by the WcfFacility) behaviors. In our example, I have created a LogExceptionHandler that will log errors to a log file. I also used a WCF core service behavior, ServiceMetatadataBehavior so I can use an HTTP GET to look at the service WSDL.
With the configuration defined, we have to get our IIS web app to use it, right? That’s done in the Global.asax by putting some code in the HttpApplication.Application_Start event.
public class Global : HttpApplication, IContainerAccessor
{
private static IWindsorContainer container;
protected void Application_Start(object sender, EventArgs e)
{
container = new WindsorContainer().Install(BinsorScript.FromFile(“windsor.boo”));
}
protected void Application_End(object sender, EventArgs e)
{
container.Dispose();
}
#region IContainerAccessor Members
public IWindsorContainer Container
{
get { return container;
}
#endregion
}
That single line in Application_Start tells Windsor that I am using Binsor and the name of my config file. Gorgeous!
Now, in order to host a WCF service in IIS, you need a .svc file as an endpoint, and (usually) web.config configuration sections out the yin-yang. We still need the former, pointing it to our WindsorServiceHostFactory and using the name from our Binsor config file.
<%@ServiceHost Language=”C#”
Service=”windsor.service” Factory=”Castle.Facilities.WcfIntegration.WindsorServiceHostFactory”
%>
Now, when we crank up the application, the Windsor Container will attach the IServiceBehaviors in the config to our services, automatically wiring up my LogExceptionHandler and ServiceMetadataBehavior. This is especially sexy when you have multiple services in a single application and they ALL get the behaviors. Furthermore, since my service has an ILogger property (remember that?) and I am also using the LogFacility, it will create my Log4Net logger and give my service an instance. POW! BLAM! KABLOOEY! This is how we do it.
I was going to put some examples of the service getting called using WcfTestClient.exe (free with .NET 3.5) so you could see my error behavior doing it’s thang as well as prove to you that we don’t need no stinking web.config sections, but I find them superfluous in a post that already is larger than I wanted it to be. If you have more questions, hit me with a comment.
So, in summary, the keypoints here are:
- Windsor rocks, and the WcfFacility is all that and a bag of chips.
- You can have web.config <service> section-less WCF services, complete with auto-wired behaviors and dependencies.
- Ayende and Craig are really, really smart.
More Examples
These two posts (here and here) in the Castle Dev Google Group go through some more examples from Craig. You’ll even get to see me asking very basic questions. Also, Craig has promised he will post some stuff focusing on the client side of things, which should be very interesting.
Update: Another, example of the newer (2008/12/02) stuff here.