Composable services with ASP.NET WebApi…sort of

A while ago I had blogged about Service Composition using ServiceStack and MEF. With ServiceStack no longer free, I figured I’d try the same thing using ASP.NET Web Api from Big Mike. The result was…not as good.

To make it work, I had to rely heavily on Autofac and their Web Api Integration packages.

First I defined the IComposableApiMetadata interface which is to be implemented by my clients. It’s 2 methods are pretty simple: one takes a ContainerBuilder to allow them to inject anything extra as per their needs, while the other returns the specific Assembly from which the ApiControllers would be loaded.

public interface IComposableApiMetadata
{
void Compose(ContainerBuilder builder);
Assembly ApiAssembly();
}

Here’s an example of what it would look like

[Export(typeof(IComposableApiMetadata))]
public class ExternalApiMetadata : IComposableApiMetadata {
public void Compose(ContainerBuilder builder) {
builder.Register(e => new BookRepository()).As<IBookRepository>().InstancePerApiRequest();
}
public Assembly ApiAssembly() {
return typeof(BooksController).Assembly;
}
}

With that done, all that should be left is calling it from the Application Start (i.e. Global.asax) right?

public class WebApiApplication : System.Web.HttpApplication {
[ImportMany]
List<IComposableApiMetadata> m_composers;
private CompositionContainer m_container;
protected void Application_Start() {
var catalog = new AggregateCatalog();
var servicesFolder = @"C:\dllFolder";
catalog.Catalogs.Add(new DirectoryCatalog(servicesFolder));
m_container = new CompositionContainer(catalog);
m_container.ComposeParts(this);
var builder = new ContainerBuilder();
foreach (var composableApiMetadata in m_composers) {
composableApiMetadata.Compose(builder);
builder.RegisterApiControllers(composableApiMetadata.ApiAssembly());
}
var container = builder.Build();
var resolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}

view raw
Global.asax.cs
hosted with ❤ by GitHub

Sadly, this isn’t enough. I had to actually reference the client dlls in my ASP.NET MVC project, which somewhat defeats the purpose of using such a Composer. Sure I could have a process automatically update the csproj with the adequate references but that feels silly.

I am sure there is a better way and once I find it I will make sure to blog about it. Until then I hope the hour or so I spent on this will help one of you guys out there.

Composable services with ASP.NET WebApi…sort of

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s