program to interface… in sharepoint

[Update]  

I’ve posted a workaround to this issue here: http://blogs.msdn.com/erwinvandervalk/archive/2009/06/08/using-interfaces-and-base-classes-in-different-assembly-using-vsewss-1-3.aspx .  

[Original post] 

One of the common practices I try to follow is: Program to interface, not implementation.

It allows you to decouple components from each other and easily plug in different implementation. This is great for test driven development, where you can replace all the dependencies of the object under test with Mock objects.

But when I tried to do something similar in our Sharepoint Guidance project, I ran into a problem with the Visual Studio Extensions for Windows Sharepoint Services (VSSeWSS) 1.3.

The problem

I had created two assemblies, one with an interface definition and the other with the actual implementation. Seems pretty basic, but when I tried to use it to create a WSP package, I got the following error:

Error    1    VSeWSS Service Error: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

Log file written to: C:\Windows\system32\config\systemprofile\AppData\Roaming\Microsoft\VSeWSS 1.3\VSeWSS1.3 service.log        0    0   

Ok, maybe the log file explains what’s wrong?

2009/04/10 11:13:59    Error System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.    at System.Reflection.Module._GetTypesInternal(StackCrawlMark& stackMark)    at System.Reflection.Module.GetTypes()    at Microsoft.SharePoint.Tools.Reflection.ModuleWrapper.GetTypes()    at Microsoft.SharePoint.Tools.Reflection.TypeFinder.GetTypesAsType(IAssemblyWrapper assembly, ITypeWrapper targetType)    at Microsoft.SharePoint.Tools.Reflection.TypeFinder.Find(IAssemblyWrapper assembly, ITypeWrapper targetType)    at Microsoft.SharePoint.Tools.SharePointProxies.WSPViewFacade.CreateWebPartReferenceResolverClassMap(String[] paths)    at VSeWSS.Server.Services.SPService.CreateWebPartReferenceResolverClassMap(String[] paths)

How incredibly useful.

The solution

After a lot of puzzling, I found out that the VSSeWSS 1.3 tool has problems with separating the implementation and interfaces in seperate DLL’s. Even if you reference the DLL’s, but not add project references, it gives the previous error message when packaging it.

However, i found if you set ‘copy local’ to False in the assembly references, the problem goes away. Of course, it does create another problem. How do you get the dll’s on sharepoint.

The solution I’m going to take is: Create a feature that puts the DLL’s on the server. Create another feature that wants to use the dll’s, but has ‘copy local’ to false. I know, it’s not pretty, but it works.

Hope this helps,

_Erwin