- Home
- LLBLGen Pro
- Architecture
Using LLBLGen Pro and WCF
Joined: 21-Nov-2006
Frans,
Are you saying that DTO's aren't really needed and it is ok to pass entities in most situations? If you are then I agree. It seems like only in a situation where extremely low bandwidth communication is possible would it make that big a difference.
Jaschag,
I am not abandoning you at all . I think this a great discussion to have, but after evaluating the situation it seems like passing Predicates and Prefetch paths from the client to the server is wrong. That means I understand why Frans doesn't see the need to make these xml serializable given the concrete usage example we are talking about. I would however like to bring up the fact that there may be other uses for this, such as storing predicates in a SQL 2005 table in xml. This might be a good way to handle handle a configurable user experience.
Frans,
Consider these 2 service interfaces:
public interface ICustomerService
{
CustomerEntity GetCustomer(int id);
CustomerEntity GetCustomerWithOpenOrders(int id);
CustomerEntity GetCustomerWithFulfilledOrders(int id);
CustomerEntity GetCustomerWithHistoricalOrders(int id, int daysOfHistory);
EntityCollection<CustomerEntity> GetCustomerList(string lastNameLike);
EnitityCollection<CustomerEntity> GetCustomerList(string city);
}
public interface ICustomerService
{
CustomerEntity GetCustomer(int id, bool loadOrders, HashTable orderFilters);
EntityCollection<CustomerEntity> GetCustomerList(hashTable customerFilters);
}
Which do you see as preferable in most situations? I have to say that option 2 looks better, and feels more natural. I would worry about the perliforation of service methods if the first approach was used.
Either way, no matter which interface defines the service, the service implementation code should be relatively insignificant, calling on the domain code which consumes, manages and coordinates work against the business entities to really do its work. I think the service code should only be about message passing. Am I correct in this? It doesnt seems so important when the service is doing data retrieval but it does when you consider something like this:
public interface IOrder
{
bool CancelOrder(int orderId);
}
because it may require cordination of a serveral operations, which may or may not be part of the natural transaction.
When I started this thread, I was trying to program at the interface / base class level, never worrying about concrete instances of the customer or the order. In normal OO that is a good thing, but doesnt really fit when you are talking about services, does it?
Keeping the predicates and other support classes off the client seems like it protects the seperation of concern, and ensures that the client and service remain as thin a layer as possible.
Thoughts?
-Casey
Joined: 15-Jul-2005
My 2 cents.
Web Services were (are?) supposed to allow for cross-platform interoperability. That was one of the main reasons web services were pushed several years ago, and still is the only reason I can see to use them.
If you are a .NET shop and you're creating a simple app that will only be used internally, why create web services? Our inclinations toward web services in this case, I think, are to "be prepared just in case". This is NOT forward-thinking design though in my opinion. It is unnecessary overhead that complicates (and in some cases kills) a project.
If your app later on needs to serve up data to clients over the internet (like the big guys' public web service APIs - Amazon, eBay, etc.) then you can create contract-first web services that define an API that can be understood on ANY platform. And then go ahead and use WSE 3.0. In that case go ahead and create an XML schema that defines the messages you expect to receive and send back.
And this is where Microsoft's tools just plain suck. They force you down an implementation-first approach which allows you to pass objects back and forth that have no meaning outside of the .NET world. Yes, you CAN serialize a DataSet as XML, but is this really what you want to send to a Java or PHP client? Web Services should really only pass simple objects that contain scalar types, and/or arrays of such objects. This can easily be understood on any platform.
But everyone wants their objects to "just work" with web services. So we keep shoe-horning stuff to make it work without looking at what we are gaining from it. Is anyone going to use LLBLGen Pro objects on a PHP platform? No? Then why are we passing LLBLGen objects back and forth from our web service? Because we are using web services just to use web services in my opinion.
Joined: 28-Dec-2006
To throw another 2 cents in ...
In the real world, web services are used more often as a facade to another tier. 90% of the time this is a way of pushing data and business operations to an applciation server, leaving your web server to deal with what it does best, creating HTML and dealing with GUI situations.
In fact most applciations I work on apply this principle, the n-tier architecture isn't about separation of business logic from presentation logic, it is about separation of processing demands for load balancing and security (web servers sit inside DMZs, and DMZs are rarely allowed to communicate over TCPIP to an internal network where the applciation and database servers reside ... http is often the only allowed transport mechanism.
What this then boil down to is that almost all applications I write must be able to communicate over web services, remoting, and directly to their database, which allows the client to decide which they would like to use in their specific environment (and yes we have one client who does the reverse of all other clients and only allows remoting out of their DMZ, never http web services).
So that means you engineer your services layer (I hate the term web services) to operate in any manner needed - and essentially that means you create DTO objects for the transfer and forget your business entities.
As I think Frans said a few times, services (web or otherwise) are about transferal of data, not logic.
So surely the logical conclusion is you write your own DTO objects that abstract at the level you would like, and you reconstruct the logic on your applciation tier (server).
The web (presentation / whatever) tier should know nothing about the data or business logic tiers ... the idea of putting any LLBLGen code or objects in the presentation tier is somewhat bizzare to me - after all, what logic could a presentation tier need from the objects?
And to finish off, to answer that last point, this hs come about largely due to the MS idea of objects like ObjectDataSource that intrinsicly bind your presentation tier to your data ... a really horrible idea.
Joined: 28-Dec-2006
Or to put it in a shorter way ...
You are viewing a web service layer (or just a services layer) as an RPC call ... and that is where the problem lies.
A web service (or any service) should be a discrete piece of business functionality, not just a remote procedure call - if you see yourself using a web service (or remoting for that matter) as an RPC call - rethink your architecture, it plain sucks
Appropriate services therefore would be:
GetCustomersByFindCriteria(string[][] optionsCollection)
- (leaving your service layer to interpret optionsCollection as it sees fit, optionsCollection is your business logic contract here)
GetCustomersWithOutstandingOrders()
etc
Inappropriate use of services (web or otherwise) would be: GetCustomers(ISearchPredicate searchOptions) - Why should a presentation or logic tier know how to construct data layer objects? THat is the job of the data tier sitting well behind the service.
Joined: 28-Oct-2005
caseyc69 wrote:
The web (presentation / whatever) tier should know nothing about the data or business logic tiers ... the idea of putting any LLBLGen code or objects in the presentation tier is somewhat bizzare to me - after all, what logic could a presentation tier need from the objects?
And to finish off, to answer that last point, this hs come about largely due to the MS idea of objects like ObjectDataSource that intrinsicly bind your presentation tier to your data ... a really horrible idea.
This is where I disagree. If you think you can make your presentation layer without any knowledge of business logic you are wrong.
And for validation, for example, you have to either duplicate your validation code in presentation layer and service layer, or do a server roundtrip to perform the validation. Server roundtrip is bad in a lot of ways, not only performancewise. If you want intuitive and responsive UI, you have to do the validation in the presentation layer.
I have no problems using entity objects in the presentation layer. Actually, I would not want to do it other way. All this talk about decoupling... there will always be somekind of dependencies with your business logic and presentation layer there is no way around it. The point in decoupling (imho) is that it should be relatively easy to maintain your system. Also, a lot depends what you mean with word application or system in general. Decoupling between different systems (meaning integrations here), that is another matter, and there decoupling is very important.
Joined: 28-Dec-2006
sami wrote:
This is where I disagree. If you think you can make your presentation layer without any knowledge of business logic you are wrong.
Alternatively, if you think a presentation tier should know anything about your business logic, then you have your application architecture screwed from the beginning.
If I have a detached presentation tier, I can replace that with a web front end, a CE front end, a Winforms front end, a Delphi or VB6 front end .. and so on. None of them need to know anything other than what I choose to expose to them via the services layer. And consequently, I can change my business and data implementations completely independently.
This is the whole principle of design by contract, not by implementation.
sami wrote:
And for validation, for example, you have to either duplicate your validation code in presentation layer and service layer, or do a server roundtrip to perform the validation. Server roundtrip is bad in a lot of ways, not only performancewise. If you want intuitive and responsive UI, you have to do the validation in the presentation layer.
No presentation validation is ever 100% representative of your business or data logic validation, it is a leaky abstraction at best. You should do both.
That doesn't mean you have to pass business obejct to the front, you only have to pass the rules.
sami wrote:
I have no problems using entity objects in the presentation layer. Actually, I would not want to do it other way.
Oh yuk, horrible. How do you deal with the scenarios I just gave you for deployment? YOu can't - and that is why RPC views of services are just wrong. If you are developing small scale systems, then sure, link your gui to your database, but in the real world that just isn't an option.
sami wrote:
All this talk about decoupling... there will always be somekind of dependencies with your business logic and presentation layer there is no way around it.
Why? Just because you cannot deal with proper decoupling, doesn't mean the rest of the world can't do it properly. Yes SOA is abused, but so are people who view sevices as RPC.
sami wrote:
The point in decoupling (imho) is that it should be relatively easy to maintain your system. Also, a lot depends what you mean with word application or system in general. Decoupling between different systems (meaning integrations here), that is another matter, and there decoupling is very important.
Decoupling is essential for a myriad of reasons, code maintenance, scalability, security, deployment, testing, and a hundred other reasons.
Look at it this way, a well defined services layer is like Dependency Injection (or Inversion of Dependency depending on your background) - done properly it creates beautifully engineered systems that are a joy to develop, expand and maintain... done badly it creates a horrible nightmare.
But whichever way you deal with it, putting 'entity' objects such as LLBGen uses into your presentation tier for anything other that using their data is a recipe for a disaster unless you are working on very small systems.
Joined: 28-Oct-2005
I can change my business and data implementations completely independently.
So when you add a new column in database table, which does not allow null values and no default values are acceptable, you don't need to change presentation and/or business layers, right?
No matter what, you still need to change some code somewhere, and probably all your data consumers need to change their code too - no matter how much you put decoupling in between.
No presentation validation is ever 100% representative of your business or data logic validation, it is a leaky abstraction at best. You should do both.
That doesn't mean you have to pass business obejct to the front, you only have to pass the rules.
I was not implying that ALL validation is done in presentation layer. Usually entity validation can be done in presentation, cross entity validation and other more complex validation is done on other layers.
Also, I you are passing rules from somewhere, you are essentially exposing your business logic anyway. Also, probably when the rules change, it might require changes in presentation layer.
Oh yuk, horrible. How do you deal with the scenarios I just gave you for deployment? YOu can't - and that is why RPC views of services are just wrong. If you are developing small scale systems, then sure, link your gui to your database, but in the real world that just isn't an option.
I have no problems switching from windows forms to web forms if I use llblgen objects in presentation layer.
Also it depends what are your requirements for your system. If you need to consume your data in some mainframe system coded with cobol thats a different thing. But for your applications presentation layer, there is no need to do so strong decoupling as you are suggesting.
Why? Just because you cannot deal with proper decoupling, doesn't mean the rest of the world can't do it properly. Yes SOA is abused, but so are people who view sevices as RPC.
You see, opinions are like armpits, everyone has a couple and they usually stink. What I find interesting is that you see your way of doing things "proper" and everything else is wrong.
What I am suggesting here is that decoupling you are talking here, is not needed in every application. Take a look for HND source code for example. It is not using DTOs, and it does what it is supposed to, and pretty well too. Should it be refactored to use DTOs just for the sake of using them - of course not.
But whichever way you deal with it, putting 'entity' objects such as LLBGen uses into your presentation tier for anything other that using their data is a recipe for a disaster unless you are working on very small systems.
I would like to see Otis opinion about the above comment.
Anyway, IMHO, you are wrong. It all depends of your requirements. On some cases it is okay, and also better to use llblgen entities, sometimes you might want to opt for DTOs. You might even gasp use both ways in your system, for example, one could offer an "integration layer" which uses DTO objects and webservices.
Joined: 28-Dec-2006
Well - you are still talking like a small systems developer.
On large scale systems (I hate the phrase 'enterprise' too) you just cannot use entity objects or direct database access in your presentation tier - clients dictate otherwise.
The examples I gave back a few posts were real world examples, the the average cost of those systems to the client was around $5 million. When people spend real money on a system, it has to work in their architecture, and that is when your approach hits brick walls.
Telling a client that they will have to re-architect their network as you want to persist objects across layers isn't going to happen - and that is if it was even half desirable.
If you view services as RPC, then you have your design wrong... use COM+ or Remoting ... but not web services ...
And what on earth is wrong with absrtracting your data and business logic from your presentation .. .you sure as hell won't have to recode your entire application when you decide to move to Linq, NHiberante, LLBLGen or ADO.NET ... your approach will result in a LOT of pain.
In the short term you think using entity objects in a presentation tier is quicker and easier ... in the long term it results in a nasty mess - which is fine if you don't have to sort it out.
Joined: 17-Aug-2003
Just a quick break: please keep it modest It's a hot topic, and the opinions are sometimes far apart.
About my opinion: I think I've written more than enough on this. I asked a well-known webservice guru (let's not name names) about this and he too said it's not a problem with a single simple answer. He leaned towards Service.InsertCustomer(...) and Service.UpdateCustomer(field, ... ) instead of sending entities back/forth, but I won't pin him down on that, as he said, and I agree with that: it's not a problem you can give a single answer to which always applies to all situations.
That's also the reason why entities are xml serializable, because some people just want to use it in that way. Some people find it great to have just 2 tiers, use lazy loading wherever they can etc. etc. while others think that's bad and want to abstract away as much as possible. Whatever the reasons are for BOTH (and even others), each one can do what they like, and at the same time probably will never agree on what's 'best'.
End january/february, I hope to have some WCF code which should illustrate some of the possibilities. However, as the scope of WCF is BIG and the # of ways how to construct/design services is also high, we cannot and won't support all of the possible situations out of hte box, we just try to implement required interfaces so alot, if not all, situations are supported. Though if the code doesn't work as great in one situation but does in another, you either should consider opting for the situation where it does work great, or use another construct.
It's similar to this metaphore I always use: you have two situations: 1) a service which is pretty dumb and sends data to a client. The client has the processing code. THe client needs 100,000 entities of a given type. The service sends these, client processes these and sends them back. This appears to be slow. 2) a service which is pretty smart. Client sends commands to service what to do. Client sends command to process 100,000 entities of a given type. Service does this and sends to the client it has done the task. This appears to be fast.
You could say: 1) is a dumb idea. And it at first looks that way. But, 2) has limits that 1) doesn't have. Now, 100,000 is a pretty high number, but if hte number is much lower, would 1) still be a dumb idea? Not necessarily but 2) could be more efficient and easier to design for.
1) requires a smart client, but dumb (and thus scalable) server. 2) requires a dumb client (so much more platforms can be supported) but the service has to be smart, so with a lot of clients, the service could require more hardware etc.
Which one is better? It 'depends'. However if the situation is known, you COULD say 'for that situation, 1) is better' or '2 is better', htough without knowing the exact situation, you can't say that.
Joined: 28-Dec-2006
I think confusion is coming from some misunderstandings ...
The first is, why are you using Web Services if it isn't a large scale application? They are just not needed. The most common reasons for using web services are: 1) To pass across a firewall 2) to expose functionality to an external client (external to the application containing the services) 3) To join in an SOA architecture such as BizTalk or SharePoint 4) To pass processing to a remote server (while under a restriction that prevents remoting)
None of these apply to small applications, so drop the web services. Use Remoting if you really need to run on a different server.
The next is that some are confusing services with RPC - and that is what won't work in LLBLGen at present. If you want services that use LLBLGen objects, then as Otis said a long time ago, use Remoting - that's what Remoting is there for. Web services are not able to transfer objects, they are able to transfer data only.
The only remaining issue then is WCF ... which actually makes the whole thing a lot simpler. Just use Remoting over http. Problem solved. In fact in the last product, we just wrote our services facade so it could work over Remoting, COM+, Web Services or direct instantiation - all transparently to the application, to be decided by the deployment and project teams. Oddly, it is not a lot harder than just writing a Web Service layer.
The only reason I can see for people wanting to use Web Sevices here is that they are easier than Remoting or COM+ - that doesn't make them a better option, it just makes them a better option for those that don't want to do things a better if more complicated way.
Last word from me : If you have a need for Web Services, you also have a need to decouple. If you need to decouple, do it properly, not in some half-baked attempt to decouple but keep knowledge of objects. Experience (too much experience) tells me it will never work, and I'm the poor sod that usually ends up fixing it.
Joined: 28-Oct-2005
Just to make clear, I have had my share of years working with enterprise system, mainly taxation systems. As you would guess those are as mission critical, expensive and huge as you could ever imagine.
Still, I am not applying every possible enterprise architecture pattern or development process on every project I am involved with.
Btw, I am not using web services to transfer llblgen objects. I did test that, but went with remoting - for use with windows forms smart client. For integrations, we have web services layer, which is not exposing llblgen objects.
The beaty and difficulty in software development is that you have a lot choices how you can solve your problems - you just need to find the right way to do it within the problem domain.
And last but not least, remember that rule of thumbs (_You shall not use web services to do xxx_, or Keep transactions short, or Do not use chatty interfaces) are just that - rule of thumbs. Usually, that is how things are, but they are no absolute truths.
Happy new year!
Joined: 19-Apr-2006
I don't often lol when reading posts on these forums but you gotta love "opinions are like armpits..."
This subject certainly seems to polarise the participants - it must be worth at least a dollar in 2 cents contributions! I have to echo Sami's last post (and Fran's previous one) - there are many right solutions to a problem and they tend to be those that are appropriate to the nature of the problem taking into account functional and non-functional requirements, size and planned longevity of system, commercial constraints/considerations and so on. Most development sees ROI as a key factor which to me means deliver the simplest solution that meets the requirements. I.e. structure the system appropriately and avoid the pitfall of blindly over-engineering the solution in accordance with the perceived best practice of the day regardless of whether those practices are actually appropriate to the problem. Since we all seem to be claiming that we have been in the industry for some time then we must all surely have observed that the fashion for the "right" way of doing things is a moving, and sometimes contradictory, bandwagon, witness mainframes vs client server, hierarchical vs relational databases, procedural vs oop vs soa... Let's not pretend that the current state of play is the end game and that we have found the holy grail and silver bullet!
Caseyc69, I agree with you and others previously that webservices is a technology choice that would suggest a service-oriented design approach. My concern here is that it seems to me that MS are pushing in a direction where webservices becomes the only practical option for distributed communication. With each new WS-* enhancement, the differential between the functional power of webservices and other communication protocols grows and the pressure to use it for purposes other than those which it is best suited to increases proportionately. Comments from the likes of Vasters saying that remoting is only really recommended for cross app domain comunication only serve to reinforce that view - "Our guidance has been – for the last few years – that you use Web Services (ASM/WSE) by default for whenever you cross a network boundary". So it's all very well saying that if you want to move entities across the wire, then you should use remoting - at some point that may not be a practical choice.
Thread value: $1.02 (or less depending on your POV)
And a happy new year,
Jascha
Joined: 28-Oct-2005
Good post jaschag, I agree totally. In almost all MS resources or if you talk to MS people, they will tell you that you should use web services if you are making a distributed app. Like it or not, there are many people who listen to that talk.
Another matter is company/customer policies. If you are told that you have to use web services, even for those silly small applications, then what can you do.
Joined: 15-Jul-2005
caseyc69 wrote:
Or to put it in a shorter way ...
You are viewing a web service layer (or just a services layer) as an RPC call ... and that is where the problem lies.
A web service (or any service) should be a discrete piece of business functionality, not just a remote procedure call - if you see yourself using a web service (or remoting for that matter) as an RPC call - rethink your architecture, it plain sucks
This seems to be the mantra of the REST camp (as far as I can tell): http://home.ccil.org/~cowan/restws.pdf
I'm not sure I agree with everything these guys put forth, but I like the balance it brings to the discussion - i.e. that web services might not be the answer at all, and if they are, we might need to think about them very differently. I am definitely leaning towards your conclusion that the RPC style "service" is not really a service at all.
I have a lot of doubts about how we're all using webservices as well as the tools we use to create them, and maybe more importantly, consume them. Auto-generated proxy classes, such as the ones VS.NET creates when you add a web reference, bury their own copies of types defined in your WSDL because that's all the generator has to go by is the WSDL. Nevermind that the WSDL was created by looking at your method signatures which contain class/type definitions that have to be represented as XML. This is where things get really sticky with passing complex types around with web services. The type used to generate the WSDL isn't the same type that the generated proxy uses. There are ways around this of course but by default this is what you get, and a lot of people just think that's how it should be.
OK I've babbled enough. I just don't think anyone of us really has all the answers when it comes to this stuff, and in 10 years we'll probably laugh at how stupid some of our ideas were.
Joined: 28-Dec-2006
Chester wrote:
This seems to be the mantra of the REST camp (as far as I can tell): http://home.ccil.org/~cowan/restws.pdf
Have never heard of REST ... thx for the link.
Really final comment ... "When you only have a hammer, everything looks like a nail"
Joined: 28-Oct-2005
When I read Rockys article about soa and semantic coupling, I did remember this thread. He has put up his thought about the subject better than I can. This is good reading for everyone:
http://www.lhotka.net/weblog/SemanticCouplingTheElephantInTheSOARoom.aspx
A little quotation:
_
Why? How can this be, when we’re using all the blessed standards for SOA communication? Maybe we’re even using an Enterprise Service Bus, or Biztalk Server or whatever the latest cool technology might be. And yet this coupling occurs!
This is because I am describing semantic coupling. Yes, all the cool, whiz-bang SOA technologies help solve the syntactic coupling issues. But without a solution to the semantic, or behavioral, coupling it really doesn’t get us very far…
_
Joined: 17-Aug-2003
Yeah Rocky really loves SO
(I tend to agree with him on this) I don't really think webservices are really valuable as an RPC call receiver. A service should be standalone, well formed and has to offer a piece of functionality that doesn't depend on other services. Indeed more like REST.
From my visit to the software workshop at Arosa, webservices as RPC fanatics and REST fanatics aren't really erm.. friendly towards eachother hehe (they didn't kill eachother, but the discussions were pretty hostile)