Programatically compose your config without requiring a derived configuration class

Topics: Web Api
Jan 17, 2011 at 5:57 AM

According to the release notes:
"Configuration has been redesigned. You can now programatically compose your config without requiring a derived configuration class. The new design uses an aggregate configuration object (Microsoft.ServiceModel.Description.HttpHostConfiguration) which is populated with various configuration strategies for configuring at the service, endpoint, contract or operation level. The new design also supports the old pattern of derving from HttpHostConfiguration and creating your own custom config. Look to Microsoft.ServiceModel.WebHttp.HttpHostConfiguration and to ContactManagerConfiguration in the ContactManager sample to see the changes."


But looking at ContactManagerConfiguration, it still derives from HttpHostConfiguration.
Is there a sample that doesn't derive from HttpHostConfiguration?

Cheers
John

Coordinator
Jan 17, 2011 at 7:04 AM
Edited Jan 17, 2011 at 7:32 AM

Not yet John, as I really wanted to get it out the door. But ContactManagerConfiguration is actually using it. If you look under the hood you will see that it implements various interfaces. As a convenience when the config class is created it looks to see if any of the interfaces are implemented and then if they are, it calls the correct methods to add the implementation to the config collections.

I am planning to get a sample done soon which I will probably initially put on my blog. But just for now to put you on the right path....

HttpHostConfiguration is not abstract, and it has several builder methods.

Basically you can do something like this

 

var config = new HttpHostConfiguration().
  SetInstanceFactory(new MyFactory()).
  SetProcessorProvider(new MyProcessorProvider()).
  AddOperationConfiguration(new MyOperationConfig());

Routes.AddServiceRoute<Contact>("Contacts", config);

Currently these methods are overloaded to accept instances and delegates, but I am thinking to refactor to also have generic overloads like SetInstanceFactory<T>().

Make sense?

 

Jan 17, 2011 at 9:29 AM

Yep, it makes sense.

So is there an easy way to say, apply these defaults to all Services, so I don't need to assign the config to all my service registrations?

And how about being able to register new service routes without having to o it in global.asax?

Cheers
John


 

Coordinator
Jan 17, 2011 at 10:06 AM

1. Yes to question 1.

2. That's an interesting idea. Do you mean having the config object do the route registration for you? In the future (soon) we're going to have a more proper resource model which will likely handle that.

 

Jan 17, 2011 at 1:02 PM

2. You can use same AreaRegistration mechanism as used in MVC. This means that your registration stays in the same assy as your code and you don't need to change global.asax every time.

Jan 17, 2011 at 9:07 PM

Yes, have some kind of bootstrapper mechanism.
The ideal is that you wouldn't do any explicit route registrations in the global.asax and instead each Service takes care of itself, so you can just xcopy a new assembly into the bin folder and automatically gets scanned and registered :)

This could be done with a simple interface such as IWantToRegisterRoutes

Thoughts?

Coordinator
Jan 17, 2011 at 10:18 PM

Ok.

It's very likely that this will be addresses as part of our forthcoming resource model. However, I will spike on it :-) One option is to allow you to specify in the configuration class....

Glenn

Jan 18, 2011 at 8:39 AM

Add a simple class to your service assy, such as...

public class MyWebAPIAreaRegistration : AreaRegistration
{
	public override string AreaName { get { return "MyWebAPI"; } }

	public override void RegisterArea(AreaRegistrationContext context)
	{
		var config = new HttpHostConfiguration().
		  SetInstanceFactory(new MyFactory()).
		  SetProcessorProvider(new MyProcessorProvider()).
		  AddOperationConfiguration(new MyOperationConfig());

		Routes.AddServiceRoute<Contact>("Contacts", config);
	}
}

AreaRegistration comes from System.Web.Mvc. Add "AreaRegistration.RegisterAllAreas();" to your Global.asax which is probably already there if you're using MVC for your web site.
All RegistraterAllAreas scans all assys for AreaRegistration classes.

This approach is working well for us.