Using S#arpLite with ASP.NET Web API

If you are planning to use S#arp Lite with ASP.NET Web API then this guide provides just what you need. This is not a Wiki on what S#arp Lite is and how to use it in an ASP.NET project. If you are looking for that information please go here

For those that have not used S#arp Lite you can use a tool that will  greatly help you jump start your first S#arp Lite project. The tool is called Templify and you can get it from here. Be sure you read the “README.txt” that comes along with the project so you are properly guided in creating your first S#arp Lite project.

S#arp Lite works with MVC 4 out of the box but if you want to use it with Web API then you would need to get the code from this  repo and add some configuration to your project. Now it’s nice that you can use S#arp Lite with Web API but it is much better that your S#arp Lite project can support both MVC and Web API. In order to do so, you need to add three new classes to your {YourProjectName}.Init project. The first two classes involves setting up the structure map resolver, there is already a great project on this and so we will be borrowing codes from it. Your code should look like the following:

public class StructureMapDependencyScope : IDependencyScope
{
    public StructureMapDependencyScope(IContainer container)
    {
        _container = container;
    }

    public object GetService(Type serviceType) {
        if (serviceType.IsAbstract || serviceType.IsInterface) {
            return _container.TryGetInstance(serviceType);
        }
        else {
            return _container.GetInstance(serviceType);
        }
    }

    public IEnumerable<object> GetServices(Type serviceType) {
        return _container.GetAllInstances(serviceType).Cast<object>();
    }

    public void Dispose()
    {
        _container.Dispose();
    }

    protected readonly IContainer _container;
}

public class StructureMapResolver : StructureMapDependencyScope, IDependencyResolver, IHttpControllerActivator
{
    private readonly IContainer container;

    public StructureMapResolver(IContainer container)
        : base(container)
    {
        if (container == null)
            throw new ArgumentNullException("container");

        this.container = container;

        this.container.Inject(typeof(IHttpControllerActivator), this);
    }

    public IDependencyScope BeginScope()
    {
        return new StructureMapDependencyScope(container.GetNestedContainer());
    }

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        return container.GetNestedContainer().GetInstance(controllerType) as IHttpController;
    }
}

At this point you should already have a reference to System.Net.Http and System.Web.Http.

The next class you need to create is for the initialization of the dependency resolver that was just created. I named the new class after DependencyResolverInitializer that already exists in the S#arp Lite template project, named it WebApiDependencyResolverInitializer. You can of course give your class what ever name you prefer. The Initialize method of WebApiDependencyResolverInitializer is almost identical to DependencyResolverInitializer.Initialize method with the exception of, as you may have guessed it, how the StructureMap dependency resolver was registered (see line 24).

using System;
using System.Web.Http;
using NHibernate;
using SharpLite.Domain.DataInterfaces;
using SharpLite.NHibernateProvider;
using StructureMap;

using NHibernateProvider;

public class WebApiDependencyResolverInitializer
{
    public static void Initialize(HttpConfiguration config)
    {
        _container = new Container(x =>
        {
            x.For<ISessionFactory>()
                .Singleton()
                .Use(() => NHibernateInitializer.Initialize().BuildSessionFactory());
            x.For<IEntityDuplicateChecker>().Use<EntityDuplicateChecker>();
            x.For(typeof(IRepository<>)).Use(typeof(Repository<>));
            x.For(typeof(IRepositoryWithTypedId<,>)).Use(typeof(RepositoryWithTypedId<,>));
    });

    config.DependencyResolver = new StructureMapResolver(_container);
}

    public static void AddDependency(Type pluginType, Type concreteType)
    {
        _container.Configure(x => x.For(pluginType).Use(concreteType));
    }

    private static Container _container;
}

Then we just need to call the Initialize method from Application_Start in Global.asax file. The Application_Start method should look like:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        DependencyResolverInitializer.Initialize();

        WebApiDependencyResolverInitializer.Initialize(GlobalConfiguration.Configuration);

        GlobalConfiguration.Configuration.MessageHandlers.Add(new BasicAuthenticationMessageHandler());
}

There is one more thing we need to do and that is to configure a new httpmodule in web.config. If you have used Templify in creating your S#arpLite project then you should already have the following:

<system.web>
    .
    .
    .
    <httpModules>
        <add name="SessionPerRequestModule" type="SharpLite.NHibernateProvider.Web.SessionPerRequestModule, SharpLite.NHibernateProvider" />
    </httpModules>
</system.web>
<system.webServer>
    .
    .
    .
    <modules runAllManagedModulesForAllRequests="true">
        <add name="SessionPerRequestModule" type="SharpLite.NHibernateProvider.Web.SessionPerRequestModule, SharpLite.NHibernateProvider" />
    </modules>
</system.webServer>

What you need to do is add the Web API verison of SessionPerRequestModule like so:

<system.web>
    <httpModules>
        <span style="color: #ff0000;"><add name="WebApiSessionPerRequestModule" type="SharpLite.NHibernateProvider.WebApi.SessionPerRequestModule, SharpLite.NHibernateProvider" /></span>
        <add name="SessionPerRequestModule" type="SharpLite.NHibernateProvider.Web.SessionPerRequestModule, SharpLite.NHibernateProvider" />
    </httpModules>
</system.web>
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <span style="color: #ff0000;"><strong><add name="WebApiSessionPerRequestModule" type="SharpLite.NHibernateProvider.WebApi.SessionPerRequestModule, SharpLite.NHibernateProvider" /></strong></span>
        <add name="SessionPerRequestModule" type="SharpLite.NHibernateProvider.Web.SessionPerRequestModule, SharpLite.NHibernateProvider" />
    </modules>
</system.webServer>

That’s it! Now your application can inject repositories to both MVC and API controllers.

Advertisements

2 thoughts on “Using S#arpLite with ASP.NET Web API

  1. Hi thanks, however the repo link didnt work change it to point https://github.com/vonbv/Sharp-Lite/tree/WebApi
    Also why and where did you get “using NHibernateProvider” from?

    The Initialize method doesn’t work at Use(() => NHibernateInitializer.Initialize().BuildSessionFactory());

    Good stuff if i could make the Initialize method in WebApiDependencyResolverInitializer class work.

  2. Sorry for the late response. You can get the NHibernateProvider project if you use Templify. That will be created for you along with some other projects to get you started with S#arpLite quicker.

    What error are you having with “() => NHibernateInitializer.Initialize().BuildSessionFactory()”? Can you post the exception you got?

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s