Thursday, October 26, 2006

Debugging with Reflector and Visual Studio

Mike Taulty recently posted about how he debugs using Visual Studio, Reflector, and SOS. I've been doing a similar style of debugging lately that I think is a bit more efficient, and here's how I do it. You may want to first take a look at what Mike's doing to put this in context.

First I use Jamie Cansdale's awesome TestDriven.NET which has the very cool Go To Reflector feature.

You can also Go To Reflector from any frame in a call stack:

One cool thing about this is that your Reflector instance stays open the whole time, and as you bounce around your call stack using Go To Reflector, the Reflector instance synchronizes to the new location that you specified using Go To Reflector.

You can also set breakpoints on code from within Reflector, which is a bit friendlier than setting breakpoints from the Disassembly window. Yes, you can set breakpoints on assemblies that you don't even have the source for.

Instead of dropping into SOS mode to look at local variables and the value of this, I simply pull up the Locals debug window. The Locals window shows values from the current stack frame as you double-click each frame in the Call Stack pane.

Sometimes the Autos window will show additional relevant variables that the Locals window doesn't and vice versa, so you may want to check both if you don't find what you're looking for.

Unfortunately I haven't found a way to get Visual Studio to do the equivalent of SOS's !dumpheap or !dumpobj for browsing and searching the heap, so you'll still need to drop down to SOS/WinDbg if you want to find all in-memory instances of particular objects or if you're analyzing a dump file. Supposedly you can load WinDbg/AdPlus dumps in Visual Studio, but I haven't gotten that to work very well with dumps of managed code. If anyone knows the secret to getting Visual Studio to analyze dumps of managed code in the same level of detail as it analyzes managed processes, I'd love to find out.

For more commentary on Mike's original goal of being able to debug the .NET Framework using its actual source code, see this post by Andrew Stopford about using Rotor to debug with source, and check out the comments regarding Deblector.

Tuesday, October 24, 2006

WCF Service Dependency Injection

Whoops, I accidentally got some link love from Phil Haack, but my blog has been dormant for 8 months!  Time to start posting all those half-finished Windows Live Writer drafts!  Here goes...

Say you've implemented a WCF service that uses a business logic layer which in turn uses a data access layer.  Rather than hard-code these dependencies into your service's constructor, you would like to use dependency injection to enable unit testing of each layer using a mock object framework such as Rhino Mocks.

For our purposes we'll do constructor injection using Spring.NET, although I've also heard good things about the Castle containers, and ObjectBuilder from Microsoft patterns & practices looks promising.

So we have a few simple classes and interfaces that we'd like to automagically hook up:

    [ServiceContract]
public interface IServiceContract
{
[OperationContract]
...
}

public class ServiceLayer : IServiceContract
{
IBusinessLogic _businessLogic;
public ServiceLayer(IBusinessLogic businessLogic)
{
_businessLogic = businessLogic;
}
...
}

public interface IBusinessLogic
{
...
}

public class BusinessLogic : IBusinessLogic
{
IDataAccess _dataAccess;
public BusinessLogic(IDataAccess dataAccess)
{
_dataAccess = dataAccess;
}
...
}

public interface IDataAccess
{
...
}

public class DataAccess : IDataAccess
{
...
}

We'd like to accomplish the equivalent of the following code whenever our service is created:

    return new ServiceLayer(new BusinessLogic(new DataAccess()));

What does the Spring.NET equivalent look like?

    IApplicationContext ctx = ContextRegistry.GetContext();
return (ServiceLayer)ctx.GetObject("ServiceLayer");

How does Spring.NET know how to wire up the dependencies?  It uses reflection and config hints to determine who depends on whom:

    <configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object name="DataAccess" type="NamespaceA.DataAccess, AssemblyA" />
<object name="BusinessLogic" type="NamespaceB.BusinessLogic, AssemblyB" autowire="constructor" />
<object name="ServiceLayer" type="NamespaceC.ServiceLayer, AssemblyC" autowire="constructor" />
</objects>
</spring>

That's great, but how do we get WCF to do this for us at the right place at the right time?  By using WCF's "behavior injection" functionality of course!


We'll need to implement an IInstanceProvider that allows us to serve up instances of our service each time WCF needs a new instance.

    public class DependencyInjectionInstanceProvider : IInstanceProvider
{
private Type _serviceType;

public DependencyInjectionInstanceProvider(Type serviceType)
{
_serviceType = serviceType;
}

public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}

public object GetInstance(InstanceContext instanceContext, Message message)
{
object result = null;

IApplicationContext context = ContextRegistry.GetContext();
string[] objectNames = context.GetObjectNamesForType(_serviceType);
if (objectNames.Length != 1)
{
throw new YourOwnException(
string.Format(
CultureInfo.InvariantCulture,
"There must exist exactly one <object> definition for the {0} service in the Spring configuration",
_serviceType.Name)
);
}
return context.GetObject(objectNames[0]);
}

public void ReleaseInstance(System.ServiceModel.InstanceContext instanceContext, object instance) { }
}

Then we'll need an IServiceBehavior that plugs in our IInstanceProvider at the right place at the right time.  Remember, WCF could choose to activate our service per call, per private session, per shared session, or as a singleton.

public class DependencyInjectionServiceBehavior : IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher cd = cdb as ChannelDispatcher;
if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider =
new DependencyInjectionInstanceProvider(serviceDescription.ServiceType);
}
}
}
}

public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {}
}


Now we want to actually use this behavior.  You could implement classes to apply this behavior using custom attributes, via config, or programmatically via a custom ServiceHost.  I chose to go the ServiceHost route.

    public class MyServiceHost : ServiceHost
{
public MyServiceHost() : base() { }
public MyServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { }

protected override void OnOpening()
{
this.Description.Behaviors.Add(new DependencyInjectionServiceBehavior());
base.OnOpening();
}
}

And of course a custom ServiceHost needs a custom ServiceHostFactory if you want IIS to host it (you can use your custom ServiceHost directly when self-hosting):

    public class MyServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new MyServiceHost(serviceType, baseAddresses);
}
}

This factory can then be referenced from your .svc files:

<%@ ServiceHost
Service="NamespaceC.ServiceLayer, AssemblyC"
Factory="NamespaceD.MyServiceHostFactory, AssemblyD"
%>

Steve Maine has a great series of posts with more details on how service activation and hosting work: