- Home
- LLBLGen Pro
- Architecture
WCF + LLBL Advice
Joined: 29-Jul-2008
Hi,
I'm in the process of evaluating LLBL for an upcoming project and I am looking for a bit of advice.
I've only been looking at LLBL since yesterday, so please be gentle
The project is split into multiple pieces:
Business layer exposed as WCF services. Internal WinForms client. Public ASP.NET Web Site. Public API (WCF services). +Other WCF services the business layer communicates with (all internal, but running on seperate servers).
The database backend is SQL Server 2005 and we have control over the clients and services.
Internally all communication will be via WCF and all clients (WinForms, Web Site, API) are .NET based.
The only part that needs to be interopertable is clients of the API, however the API will simply accept/return simple types and DTO's (DataContracts).
Based on this, I'm presuming that my best option is to:
-
Use the DataAdapter template.
-
Pass Entities between the clients and services.
-
Compile both the Entities and the Services interfaces into shared assemblies and distribute them with each client.
-
Use ChannelFactory's to communicate with the business layer rather than using either svcutil or VS.NET to generate a proxy.
As I've managed to come up with about 4-5 ways of passing the objects around, I just wondered what others are currently doing...
Please feel free to tell me I've got it all wrong and I should be sticking with SOA tenets and not exposing types beyond the service boundary
Joined: 24-Jul-2008
sorry, this is not really an answer but it adds to your question., i am working on a similar project., Winforms + WCF (iis) + Sql server..
i "think" i will be doing something similar to what you are doing...
i used ormapper to generate all the fun code. created a WCF application.,
i am debating if i should create seperate service interfaces for the various components i want returned., or if i should just create one Iservice (default service created by wcf).. and put all my returns there (i will be returning entities/collections?)
i thought that i would have to create custom interfaces since most of my tables have FK's into look up/pick list tables.,.. but then i realised that OR mapper did that for me !!! so all i truely need to do is jsut return the ojbects entity,. for example a Media Server has media media has fk into MediaType, LicenseType... i can just request a specific mediaentity and then do a Media.MediaType.MediaName yeaaaa... (hopefully i have the right idea)
btw., i am also sing the DataAdapter template.. have not gotten to 3/4., but ill probably just let vs do the service xml for me
Joined: 29-Jul-2008
With regards to creating seperate service interfaces, it kind of depends on your entities and the number of methods etc.
Personally, I'm more than likely going to go down the route of creating an IEntityManager interface for each Entity, e.g. ICustomerManager for all methods relating to CustomerEntities and to then have each interface implemented by a specific service. I must admit though I haven't worked out the finer details of this and I'm not 100% sure if this is the route I'm going down as yet...
The nice thing about multiple interfaces/services is you can (if later required), move them off to seperate application servers quite nicely.
You could create multiple interfaces and have them implemented by one service, or you could create one interface and implement it in one service.
The only problem you might run into is with VS.NET and multiple services if you are relying on it to create the proxies. When I was testing multiple services with VS.NET I was attempting to put the proxies in a single namespace, e.g:
MyNamespace - CustomerManagerClient - OrderManagerClient - EmployeeManagerClient
However, if seems as if you can't create multiple proxies in the same namespace within VS...
Joined: 20-Apr-2005
I really would advise against passing entity graphs around using WCF - its design deliberately discourages this for a variety of reasons and it will punish you with performance issues if you rely on being able to throw entity graphs about.
If you do absolutely need to share entities between client and server, use remoting as it is designed for a shared type model and llblgen's optimised binary serializer murders WCF DataContract for performance - by anything up to 30x the speed.
Don't just go for WCF becuase it is new and shiny, it is best suited to loosly coupled service designs using DTOs or explicit messaging, it will be likely to burn you if you use it for remoting.
Joined: 29-Jul-2008
Hi Ryan,
The decision to use WCF is partially because its positioned to replace Web Services and Remoting and that both previous technologies are effectively made obsolete by WCF (well, nearly...). There are also a host of other reasons, including the ability to have a common technology for both exposing the API and the other elements of the system as well as the abstraction of the underlying plumbing and the extensibility WCF offers etc.
WCF isn't exactly new as it is coming up-to 2 years old and we are in our second incarnation. I take on board your comment regarding using something "new and shiny" however, but whilst we are intending to use WCF, we aren't intending on using WPF for example because IMHO it isn't currently good enough.
I do agree with you that passing entity graphs around with WCF isn't exactly encouraged, but on the other hand, WCF is touted as the replacement to remoting.
Performance is a concern, however from what I understand of LLBL it does use its own Compact25 format which would narrow the gap between plain remoting and WCF, but not remoting when used with FastSerialization.
There is also the option of using the "preserveObjectReferences" flag (http://blogs.microsoft.co.il/blogs/sasha/archive/2008/01/20/wonders-with-wcf-s-datacontractserializer.aspx) with the DataContractSerializer which does seem to greatly improve performance when comparing WCF to remoting with complex data.
NetDataContractSerializer is also another option rather than DataContractSerializer which behaves similar to BinaryFormatter in remoting and would be the fastest option.
Whether any of these options are as quick as LLBL's optimised binary serializer for remoting I'm unsure.
Even if I use DTO's rather than Entities they could still end up being complex structures with nested objects and collections which could suffer from the same performance issues as Entities. If the DTO's are created as single-level objects that don't reference other objects, the app would then require multiple calls to the services which will also result in performance hits...
On the other hand, am I just being lazy by not creating DTO's...
and/or have I just got this completely wrong
Joined: 20-Apr-2005
dotNetFreak wrote:
Hi Ryan,
I do agree with you that passing entity graphs around with WCF isn't exactly encouraged, but on the other hand, WCF is touted as the replacement to remoting.
Yes, which is quite a problem on MS' behalf. While WCF can be used with shared types on client and server you are likely to come across performance issues compared to optimised binary serialization, I have recent indirect experience of this where I created a [HackyAttribute] for another team that made WCF use a standard binary formatter (on top of the excellent llblgen binary formatter) and base64 encode it into the response. It had huge performance gains (25x or more for large result sets, and 10x less traffic) over DataContract, even after a lot of tuning. It's now the least interoperable WCF application ever though, so other than potential access to WCFs cross cutting features like security / reliable messaging etc it may as well be a remoting app.
Distributed systems are just plain difficult, and attempting to abstract away the communications in a system of any complexity is likely to bite you later (I'm surprised I can still sit down some days). Using DTOs / messaging makes what is going on the wire explicit for all of your service operations, rather than having it pop up 6 months down the line. It's an eventual labour saver, especially now that you can do projections in linq so elegantly.
Even if I use DTO's rather than Entities they could still end up being complex structures with nested objects and collections which could suffer from the same performance issues as Entities.
Possibly, but you would be making those choices on a per-case basis rather than coupling your client to the entities by default.
If the DTO's are created as single-level objects that don't reference other objects, the app would then require multiple calls to the services which will also result in performance hits
You can batch service calls too, if you want to keep a fine grained service layer. You will need to use explicit messaging along the lines of GetStuffRequest/GetStuffResponse rather than RPC style method calls. http://davybrion.com/blog/2008/06/batching-wcf-calls/. And caching is the special sauce for client server performance, though of course it comes with its own complexities.
Joined: 29-Jul-2008
Ryan,
So, in a WCF, .NET <-> .NET environment what would your recommendation be... To use DTO's on the wire and use projection in the service to project them into/outof entities?
Joined: 20-Apr-2005
dotNetFreak wrote:
Ryan,
So, in a WCF, .NET <-> .NET environment what would your recommendation be... To use DTO's on the wire and use projection in the service to project them into/outof entities?
Yes, that's likely to save time in the medium to long term with a WCF client/service of any complexity. Unless the projects are simple and unlikely to grow I would pay the (increasingly small) DTO tax. I resisted doing it for some time, but sending enties really does smuggle a lot of potentialy suprising complexity in through the back door, even when you don't consider multiple potential clients. Syntacticaly, things are much cleaner and terser with c#3.0 when it comes to dealing with the overhead of DTOs - we now have automatic properties, linq projection and attribute free datacontracts( in 3.5 SP1).
Joined: 29-Jul-2008
Hi Ryan,
Thanks for your advice!
The project certainly isn't a simple one and it will grow tremedously over the next 2-3 years which is why I'm concerned to get it right at the beginning.
I was reviewing the 3.5 SP1 Beta info yesterday and it is interesting to note that MS are changing DataContractSerializer to enable users to enable the perserveObjectReferences flag much easier by setting a value on the DataContract attribute.
Looking at it, this has been done for the Entity Framework, but I wonder how long it is before we see complex object graphs being thrown around as a consequence...
The attribute-free DataContract support in SP1 is a strange change and I'm not quite sure that this fits in with the SOA model that WCF is touted as...
Also, the fact that you can now use an IContractBehaviour to apply NetDataContractSerializer to an entire ServiceContract rather than applying it per Operation is interesting... I wonder how long it is before we find the NetDataContractSerializerAttribute present in the framework.
Perhaps MS is realising that WCF isn't quite the replacement for remoting that they've made it out to be and are making subtle changes to the framework...
Kevin