WCF Best Practice for Data Contracts, Shared Classes, and DTOs - wcf

Before I break my application, my current namespace look something like this:
CompanyAbc.Core
CompanyAbc.AppXyz.Web
CompanyAbc.AppXyz.Business
The CompanyAbc.Core namespace contain common code used by all applications in our company. An example would be a class called "ClientMessage" which we use as a container to carry messages from one tier to another tier (e.g. to abstract out and support showing success or error messages when saving data at the data-tier all the way to the UI-tier)
We are now making the CompanyAbc.AppXyz.Business into a WCF Service. My question is this: What is the best practice for 'sharing' (or not sharing) these base/common entities?
For example, would you:
a) add the [DataContract] attributes directly to classes in the CompanyAbc.Core namespace, even though it has nothing to do with WCF.
CompanyAbc.Core.Entities
ClientMessage.cs
OR
b) create a Data Transfer Object that is an exact copy from the CompanyAbc.Core namespace?
CompanyAbc.Core.Entities
ClientMessage.cs
CompanyAbc.AppXyz.Business.DataContracts
ClientMessageDto.cs
OR
c) Other options?
Another complexity is that we intend to share these assemblies. But to enforce decoupling and not share assemblies/business entities, would you go all out crazy and do something like this?
CompanyAbc.Core
CompanyAbc.Core.Shared.Entities
ClientMessage.cs
CompanyAbc.AppXyz.Web
CompanyAbc.AppXyz.Web.Entities
ClientMessage.cs --> derives from the Core.Shared, or just duplicate code?
CompanyAbc.AppXyz.Business.Entities
ClientMessage.cs --> derives from the Core.Shared, or just duplicate code?
CompanyAbc.AppXyz.Business.DataContracts
ClientMessageDto.cs

I would suggest you make "hierarchy groups" in your assemblies, in order to make it more concise and its use be more intuitive. For instance:
(Taking the #learner example as a base)
ABC.Common (It communicates better the intention)
ABC.Core
ABC.Core.Web
ABC.Core.Windows
ABC.Services.DataContracts
ABC.Services.ServicesContracts
And so on ...
Making a clear hierarchy stimulates its use by the developers, as it fits with the previous assembly already deployed.
Take a look at the .NET assemblies for a reference.

Here is how my namespaces look like, as I used it so far:
ABC.Core
ABC.Data
ABC.Business
ABC.Web;
ABC.Services (common)
ABC.Services.DTO (common)
ABC.Services.Svc1
ABC.Services.Svc1.DTO
ABC.Services.Svc2
ABC.Services.Svc2.DTO
In practice you won't like to have so many shared classes between the services, because they would probably want to be separated one of the other. The better are independent one of the other, the better you can version them, but is true that it would require a bit of duplicated code in the DTO level of each service. Many people use Automapper to project the Core classes into DTOs.
Let me know what you think.

Related

Converting a Library to WCF web service

As the subject line describes, I am in the process of exposing a C# library into a WCF Service. Eventually we want to expose all the functionality, but at present the scope is limited to a subset of the library API. One of the goals of this exercise is also to make sure that the WCF service uses a Request / Response message exchange pattern. So the interface /API will change as the existing library does not use this pattern
I have started off by implementing the Service Contracts and the Request/Response objects, but when it comes to designing the DataContracts, I am not sure which way to go.
I am split between going back and annotating the existing library classes with DataContract/DataMember attributes VS defining new classes which are like surrogate classes to the existing classes.
Does anyone have any experience with similar task or have any recommendations on which way works best ? I would like to point out that our team owns the existing library so do have the source code for it. Any pointers or best practices will be helpful
My recommendation is to use the Adapter pattern, which in this case basically means create brand new DataContracts and ServiceContracts. This will allow everything to vary independently, and will allow you to optimize the WCF stuff for WCF and the API stuff for the API (if that makes sense). The last thing you want is to go down the modification route and find that something just won't map right once you are almost done.
Starting from .NET 3.5 SP1 you no longer need to decorate objects that you want to expose with [DataContract]/[DataMember] attributes. All public properties will be automatically exposed. This being said personally I prefer to use special DTO objects that I expose and decorate with those attributes. I then use AutoMapper to map between the actual domain models and the objects I want to expose.
If you are going to continue to use the existing library but want to have control over what you expose as the web service API, I would recommend defining new classes as wrapper(s) around the library.
What I mean to say is don't "convert" the existing library even if you think you're not going to continue to use it in other contexts. If it has been tested and proven, then take advantage of that fact and wrap around it.

Is there any reason to keep the WCF interface in a separate file?

Just personal style, I guess, but I hate having 2 files for my WCF Services. I tend to like to copy/paste the interface into the .cs file so that I only have to deal with a single file.
Any dangers in doing this?
Not dangers per se - but there are times when it is very useful to have a separate assembly with your service, operation and data contracts (just the contracts, the interfaces, basically) - when you need to share those between the server and the client side.
There's really no point in sharing the whole service implementation code (the actual service class, that implements the service interface), with the client.
Plus: if you have your interfaces in a separate file (and possibly assembly), it makes it easier to write unit tests, especially if you want to mock a service. Gets a bit messy if you mix interface and class into a single file.
So I consider it a useful and helpful best practice to have separate files for interfaces and implementations (actually: always one class per file only), and to put all service- and data contracts (and fault contracts) into a separate assembly.
Actually, I like to go beyond two files, and have two separate projects. One project holds the interface definition. The primary value is for integration testing. I like to make a third project with a WCF client. That client accesses the interface in the "shared" assembly.
Remember the mantra of Testivus: "When writing the (production) code, think of the test; When writing the test, think of the code."

n-tiered architecture with Silverlight, WCF and nHibernate

I try to set-up a clean and flexbible application-framework for data-centric applications with silverlight-only UI. I want to have a strict seperation of concerns, and want to be as flexible as possible (e.g. exchange the ORM later) while still reducing the amount of code.
It took me weeks to figure out an appropriate architecture, and although my latest approach seems to fit my requirements I'm still not completely convinced, that this way will be the best and is technically possible.
Here is how my solutions-explorer looks like:
MyCompany.MyApplication.Entities
Class library - project, which contains only the domain (business) objects, such as Customers, Adresses, etc. These are POCOs with the [Serializable] - attribute, but do not any other code. All properties are marked as virtual, so that classes could derive and overwrite the properties.
MyCompany.MyApplication.DataAccess
Class library - project, which contains the nHibernate - specific code (Sessions) to load, save and delete the domain objects. This project has references to the Entities-project and also to the nHibernate-libraries.
MyCompany.MyApplication.Core
Class library - project, which contains the business logic, and often just maps the methods form the DataAccess - project, such as GetAllCustomers, SaveCustomer, etc.
It has references to the Entities-project and the DataAccess-project.
MyCompany.MyApplication.Web
Web-application - project, which hosts the silverlight-client-app and also the WCF-services to communicate with the client-side. To expose the domain-objects to the client-side, these classes are derived and all the properties are overwritten and marked with the [DataMember] - attribute. It has references to the Entities-projects and the Core-projects.
MyCompandy.MyApplication.Silverlight
Sivlerlight 3.0 - project, which represents the userinterface. It has only service-references to the WCF-Services exposed by the Web-project. The actual domain-objects aren't accesssible, but the auto-generated proxy-classed replace them.
Please tell me, what do you think about this architecture, and if there are any conflicts! Further question: Is there any way, to avoid the properties of the domain-objects being virtual and the need to overwrite them in order to make them accessible trough WCF?
Best regards,
Daniel Lang
Daniel, you are not going to get around the nhiberante requirement of virtual properties. Have you thought about using Dto's?

WCF Web Service Bloat

I am developing a WCF web service which has become quite bloated. What techniques do you use to split up the implementation of the contract?
Well you have a couple choices:
First, you could leave it all in one class, but split up into different files using the partial class feature of C#.
Second, you could have the main service class just pass requests off to one of a number of other actual classes that are organized logically.
A third alternative is to consider refactoring to reduce the number of operations you have. Is there actually a use to all of the methods you're exposing?
Finally, you could always split up the service into multiple WCF services.
It's hard to answer your question if you don't give any more information.
Do you mean that your service interface is bloated, or the class implementation? It's hard to answer well, if I don't see the code, or have no other information, anyway, I'll try:
Notice that WCF service is basically just a regular class that implements an interface and has some attributes on its methods. So all the other good OO design rules apply to it. Think about what it does, does it have really single responsibility, if not try to outsource some of that responsibility to other classes that your service depends on. If you need a non-default constructor, use IInstanceProvider to create the service class, and supply it with its dependencies (or if you use Windsor Container use WCF Facility).
If you really want to you can streach your inheritance chain, and move some of the code to a base class. I don't do it, however and always prefer to use composition over inheritance.
Inspect your service contract, and think about how cohesive it really is. Maybe what you should do is to split it, into few smaller, more cohesive services.

WCF Contracts from Entity Framework?

I've been coming up with a lot of dead ends on this question. Supposedly, .NET 3.5 SP1 has Support for ADO.NET Entity Framework entities in WCF contracts. But when I look for solid info on it I'm not getting a lot of answers. I found this one snippet on an MSDN thread. Does anyone have any experience with this? What happened to the [DataContract]? Is this all there is to it? Why is there so little material on this?
This the answer from Tim Mallalieu in Microsoft.
Entity Types that are generated in the Entity Framework are, by default Data Contracts.
If I were to create a simple model in the Entity Designer like the following:
The cart Entity Type is by default a DataContract with all properties annotated as data members. We can then use this in a WCF service as follows:
[ServiceContract]
public interface IService1
{
[OperationContract]
Cart[] AllCarts();
}
public class Service1 : IService1
{
public Cart[] AllCarts()
{
using (MSPetShop4Entities context = new MSPetShop4Entities())
{
var carts = from c in context.Carts select c;
return carts.ToArray();
}
}
}
As the Entities are DataContracts you can now roll your services as you see fit and send these across the wire.
I recommend that you not return Entities directly. Unfortunately, Microsoft chose to include implementation-specific data as part of the DataContract for entities. This will not interoperate with other platforms, and is the sort of thing that might fail to interoperate even between .NET versions.
Instead, I recommend you follow the Data Transfer Object pattern and just return POCO classes that are copies of the data in the entities, with no behavior. You can return List of such classes to represent a table, etc.
The "sharing interfaces and not type" tenet presupposes that you don't own both ends of the wire and/or you're writing a public-facing web service. WCF can be used (and is used) in contexts where this is decidedly not the case. Many enterprise n-tier architectures have a WCF-fronted application tier to facilitate load-balancing among other things. In these cases it is perfectly valid to share type and, in fact, is desired.
You could go the easy way and use ADO.NET Data Services.
Some more detail in response to comments:
There are several problems with the classes generated by EF. I'm looking now at an AdventureWorks example with SalesOrderHeader and SalesOrderDetail. The SalesOrderDetail entity has both "SalesOrderHeader" and "SalesOrderHeaderReference" properties, both marked as DataMembers. This looks like a bug, since the "SalesOrderHeader" property is also marked [XmlIgnore] and [SoapIgnore].
Also, consider whether you want to serialize the link back to the parent SalesOrderHeader in the first place. Besides, what exactly should be serialized? SOAP doesn't support references in an interoperable manner.
Finally, the base classes of the entities are also data contracts. Yet they have nothing to do with the data you are returning - they are purely an implementation artifact.
In short, Microsoft screwed up on this one. They didn't think it through.
About ways to generate the DTO classes, I suggest looking into various code generation tools, like CodeSmith. You can write code to do this yourself; I did so in my previous position. The nice thing about generating the DTO is that you also get to generate the methods to translate to and from the DTO.
As to overhead, the overhead of moving some data around in memory is nothing compared to the amount of time it's going to take to send the data over a network!