, DomainService), you might have already seen the dreaded "This DomainService has not been initialized." error when trying to perform even the simplest of queries.
To work around the initialization issue, we first need to create a DomainServiceContext instance and pass it into the DomainService.Initialize(DomainServiceContext) method. Doing so takes several steps, however.
1. First, create a simple ServiceProvider class that we will use later:
using System;
using System.Security.Principal;
using System.Web;
public class ServiceProvider : IServiceProvider
{
private HttpContextBase _httpContext;
public ServiceProvider(HttpContextBase context)
{
this._httpContext = context;
}
public object GetService(Type serviceType)
{
if ( serviceType == null )
{
throw new ArgumentNullException("serviceType");
}
if ( serviceType == typeof(IPrincipal) )
{
return this._httpContext.User;
}
else if ( serviceType == typeof(HttpContextBase) )
{
return this._httpContext;
}
return null;
}
}
2. Next, create a couple of helper methods to encapsulate the creation of the DomainServiceContext. Note that the GetHttpContext() method will create a mock HttpContext instance that can be used during unit testing (not hosted in IIS).
using System;
using System.IO;
using System.Security.Principal;
using System.Web;
using System.Web.DomainServices;
using System.Web.Hosting;
public static DomainServiceContext CreateDomainServiceContext()
{
var provider = new ServiceProvider(new HttpContextWrapper(GetHttpContext()));
return new DomainServiceContext(provider, DomainOperationType.Query);
}
public static HttpContext GetHttpContext()
{
var context = HttpContext.Current;
#if DEBUG
// create a mock HttpContext to use during unit testing...
if ( context == null )
{
var writer = new StringWriter();
var request = new SimpleWorkerRequest("/", "/", String.Empty, String.Empty, writer);
context = new HttpContext(request)
{
User = new GenericPrincipal(new GenericIdentity("debug"), null)
};
}
#endif
return context;
}
3. Finally, we can initialize our domain service from within our unit test methods.
[Test]
public void Test_Service_Initialization()
{
var context = CreateDomainServiceContext();
var service = new NorthwindService();
service.Initialize(context);
var query = service.GetCustomers();
var count = query.Count();
Assert.Greater(count, 0);
Console.Write("Count = {0}", count);
}
4. Extra Credit: You can combine these helper methods into a static class and create a simple extension method to tighten up the code even more!
public static class ServiceExtensions
{
public static TService Initialize<TService>(this TService service)
where TService : DomainService
{
var context = CreateDomainServiceContext();
service.Initialize(context);
return service;
}
// place other helper methods here...
}
[Test]
public void Test_Service_Initialization()
{
var service = new NorthwindService().Initialize();
var query = service.GetCustomers();
var count = query.Count();
Assert.Greater(count, 0);
Console.Write("Count = {0}", count);
}
Hope that helps!