public
Created

A generic service provider to simplify Controller constructors and testing in ASP.NET MVC.

  • Download Gist
IServiceProvider.cs
C#
1 2 3 4 5 6 7 8 9
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
public interface IServiceProvider
{
T GetService<T>() where T : class;
}
SampleController.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
public class SampleController : Controller
{
protected readonly IServiceProvider _serviceProvider;
public SampleController(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public ActionResult Index()
{
// If the service is used across multiple actions,
// this line can be moved to the constructor and setup with a protected variable
var userService = _serviceProvider.GetService<IUserProvider>();
ViewData.Model = userService.GetUser("jbubriski");
return View();
}
}
ServiceProvider.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
 
/// <summary>
/// Default implementation of IServiceProvider.
/// Uses MVC's built in DependencyResolver to get a requested service.
/// In my app I used Ninject, but you should be able to use anything compatible with the DependencyResolver.
/// </summary>
public class ServiceProvider : IServiceProvider
{
private Dictionary<Type, object> _services = new Dictionary<Type, object>();
 
public T GetService<T>() where T : class
{
var serviceType = typeof(T);
 
if (!_services.ContainsKey(serviceType))
{
var service = DependencyResolver.Current.GetService(serviceType);
 
_services.Add(serviceType, service);
}
 
return (T)_services[serviceType];
}
}
TestServiceProvider
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting;
using Moq;
 
/// <summary>
/// Implementation of IServiceProvider for testing with Moq.
/// Provides easy access to mocks, and the service provider interface returns the mocked services.
/// </summary>
public class TestServiceProvider : ISfcServiceProvider
{
private Dictionary<Type, object> _mocks = new Dictionary<Type, object>();
 
public T GetService<T>() where T : class
{
var serviceType = typeof(Mock<T>);
 
if (!_mocks.ContainsKey(serviceType))
{
var service = new Mock<T>();
 
_mocks.Add(serviceType, service);
}
 
return (T)((Mock<T>)_mocks[serviceType]).Object;
}
 
public Mock<T> GetMock<T>() where T : class
{
var serviceType = typeof(Mock<T>);
 
if (!_mocks.ContainsKey(serviceType))
{
_mocks.Add(serviceType, new Mock<T>());
}
 
return (Mock<T>)_mocks[serviceType];
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.