tags:

views:

289

answers:

4

What's the most common/best way to setup a WCF service project and applications?

Here's an example:

  • Solution: "MyProject"
  • Class Library: "MyProject.Common"
    • Contains ServiceContract interface, and any DataContracts
  • Class Library: "MyProject.Impl"
    • Contains implementation of service contract, and a client class that can be used to call the service
  • WCF Service Web Application: "MyProject.Service"
    • Contains references to MyProject.Common and Impl, so that it can host the service
    • WCF service app would configure the endpoints in the web.config
  • ASP.NET Web Application: "MyProject.Web"
    • Contains references to "MyProject.Common" and "MyProject.Impl" so that it can use the client class
    • Web app would also need to configure the endpoints in the web.config, etc.

My question is whether it makes sense to split the contract and implementation into separate DLLs, and whether the application(s) should reference the Common/Impl libraries, or if the application(s) should just make a service reference (using "Create Service Reference" or SvcUtil). I'm thinking it might make sense for the apps to just make a service refernce, so you don't couple the Common/Impl to the app. In this case, does it even make sense to create a client class in MyService.Impl?

+2  A: 

Check out the Web Service Software Factory. It's got lots of great guidance for building WCF applications including some guidance on the solution structure. Also, IDesign.NET (Juval Lowy) has some guidance on that as well (zip link).

JP Alioto
+1 thanks for the links, I'll check those out
Andy White
+1  A: 

Hi Andy You should include the service interface and common classes in the client application if you are using complex types otherwise the generated proxy will duplicate the definition of the types that you used in your service, and it could cause you headaches with serialization later...

Then you can manually generate a proxy that uses the types from the common assembly and does not re create other classes simulating your types.

C:\Samples\WcfSerialization>svcutil.exe /out:WcfServiceProxy.cs /d:Schmu rgon.WcfClient.Web /r:Schmurgon.Data.Contracts\Schmurgon.Data.Contracts\bin\debu g\Schmurgon.Data.Contracts.dll http://localhost:5150/Schmurgon.WcfService.Host/S ervice.svc?wsdl

The switches are:

/out: param is simply the name of the output proxy class.

/d: the directory in which to store the proxy class.

/r: the assembly containing the types that would otherwise be included in the proxy class

[none] the address of your WCF service.

(This is pasted from http://schmurgon.net/blogs/ben/archive/2006/12/17/wcf-proxy-generation-without-types.aspx)

Hugo Zapata
+1 Not sure why this was downvoted
Andy White
Well, it wasn't me :-) but I can see a reason - sharing the contract between server and client - while common - is not exactly a good practice in SOA. It's all about decoupling, but by sharing contract at the file level (via a shared assembly) causes dependencies which can be bad. Also, while your .NET client to your .NET server might work that way, a different client (Java, PHP) cannot use shared assemblies. So I would argue don't share assemblies with contracts - use the service interface at all times.
marc_s
Good point, that makes sense to me
Andy White
Well. It then depends on your requirements, not every service is part of a SOA architecture. Thats why WCF supports multiple transport mechanisms, some of them closed ( but more powerful) and some of them open ( but without the advantages of type serialization in .NET)...
Hugo Zapata
Let me echo the "depends on your requirements". Pure decoupling (where there no shared code or interface definitions) is good if you are targeting a multi-platform environemt. But if you know you're only going to be using .NET/WCF it is probably wrong to have duplicate object definitions. Especially for the data contracts. I can see keeping the service interface separate in some cases, but for data contracts, I think it's a big deal to reduce duplication unless there's a good reason not to.
Simon Gillbee
+1  A: 

It depends.

Normally the generated proxy class is enough for client programs to call the WCF service, so a client library isn't necessary. Of course there are situations where it is, for example if your contract only specifies Message as its parameters, and you use data contracts under the hood, but those are pretty rare!

What I wouldn't do is put the client class, if you feel you need one, in the same library as your service implementation - clients don't need to know about how the service is implemented, just how to call the service. By putting both together you're distributing your service implementation too.

The complex types issue alluded to by Hugo won't happen if you mark the classes you use with Data Contracts, which you should be doing anyway to allow for easy versioning of services.

blowdart
+1  A: 

My question is whether it makes sense to split the contract and implementation into separate DLLs, and whether the application(s) should reference the Common/Impl libraries, or if the application(s) should just make a service reference (using "Create Service Reference" or SvcUtil). I'm thinking it might make sense for the apps to just make a service refernce, so you don't couple the Common/Impl to the app. In this case, does it even make sense to create a client class in MyService.Impl?

Bingo - you "got" it! Even when theoretically, technically can share contracts and interfaces using shared assemblies, I would rather recommend not to.

First of all, other clients (e.g. Java, PHP, Ruby) won't be able to use shared .NET assemblies. So suddenly they use a different interface than your client which might cause subtle variations which could be hard to debug.

Secondly, SOA is all about decoupling parts of your system into separate, distinct entities with well defined service borders. Sharing assemblies introduces dependencies you're trying to avoid.

So therefore I would agree you're on the right track - whether or not to separate the contract interfaces from their concrete implementation can be debated. One benefit might be if you ever need to create a second, third implementation of the same interfaces, or if you have certain commonly used helper interfaces in a separate assembly used by various of your services. One more assembly doesn't really hurt - my recommendation would be to do exactly as you outlined in your post!

Marc

marc_s