Is UI code REALLY independant of Data Portal configurations?

Is UI code REALLY independant of Data Portal configurations?

Old forum URL: forums.lhotka.net/forums/t/432.aspx


brettswift posted on Wednesday, June 21, 2006

http://forums.lhotka.net/forums/thread/1965.aspx

That link is a reference to the "Online / Offline Smart Client " thread started by kdubious.

I have questions that will serve some of the comments on there, and my post on that thread.

 

In the book it says you're supposed to be able to switch from a local datasource to a remote datasource via the config file, (sounds great for a smart client) but when I look at the code samples in the book I don't see how this can be done....

I have a method that I'm trying to convert from
1) a Local datasource where the Win Forms will connect with the database directly, and load up values in a TreeView control,
to....
2) loading them from my Web Service.

1) dealing with AnimalInfo objects that are loaded into the AnimalList
2) if proxy classes are developed as in the PT sample app, I'd be dealing with AnimalData objects in an array.

So, question being - how do I write UI code so that it is independant of the Data Portal ?  (2 parts)
a) How do I make this line:
              i)AnimalList aList = Animal.GetAnimalList();  // from AnimalTracker.Library;
      compatible with this line: 
              ii)AnimalData[] aList = svc.GetAnimalList(); // using web service reference.

Maybe - these ReadOnlyList bases (AnimalInfo) are ok to use instead of the proxy classes?

I'm obviously still new to this and hoping that someone can help me out here, because I'm thinking its not a simple explanation. Or maybe I'm just missing something obvious?  Is there a smart client version of the PT app out there that someone has played around with ?

 

ajj3085 replied on Wednesday, June 21, 2006

brettswift:
In the book it says you're supposed to be able to switch from a local datasource to a remote datasource via the config file, (sounds great for a smart client) but when I look at the code samples in the book I don't see how this can be done....

I have a method that I'm trying to convert from
1) a Local datasource where the Win Forms will connect with the database directly, and load up values in a TreeView control,
to....
2) loading them from my Web Service.

Here is your first problem; your Winform app is trying to talk to the database directly.  Your Winforms app should be communicating with a BO, which will handle the data access.  Your data access code should only be in the DataPortal_XXX methods.

There's another problem as well; the DataPortal isn't meant to allow you to switch the type of datasource.  So if you're BO uses SqlClient, it will always use SqlClient (the difference is that your BO's DataPortal code can run locally, which means the client computer will connect directly to the database OR on a remote server (such as one inside a firewall), which means that your BO will move from the client workstation to an IIS server, and the IIS server will connect to the database.

To allow a switch from SqlServer to a web service would be tricky; you would need some kind of data access layer which hides the specifics of communicating with your datastore.  For example, I wrote a custom one, where each class represents a row from a table or view.  I have Insert, Update, Delete and Load methods.  I designed it in such a way that I can switch between Sql server or Oracle, and not have to change my business code at all.  I admit though, a WebService provider could be difficult, but it may be something I could create for my DAL.

brettswift:
1) dealing with AnimalInfo objects that are loaded into the AnimalList

2) if proxy classes are developed as in the PT sample app, I'd be dealing with AnimalData objects in an array.

So, question being - how do I write UI code so that it is independant of the Data Portal ?  (2 parts)
a) How do I make this line:
              i)AnimalList aList = Animal.GetAnimalList();  // from AnimalTracker.Library;
      compatible with this line: 
              ii)AnimalData[] aList = svc.GetAnimalList(); // using web service reference.

I'm assuming that Animial is a business object.  GetAnimialList shouldl look something like this:

/// <remarks>EmptyCriteria inherits from CriteriaBase, and is a private class embedded in your AnimalList class</remarks>

public static AnimalList GetAnimalList() {

     return DataPortal.Fetch<AnimalList>( new EmptyCriteria() );

}

private void DataPortal_Fetch( EmptyCriteria crit ) {

// This is where your data access would go, and here's where you'd need to interface with a DAL of  your choosing.

}

On more thing; GetAnimalList should be defined in your AnimialList class, not your Animal class.

brettswift:
Maybe - these ReadOnlyList bases (AnimalInfo) are ok to use instead of the proxy classes?

AnimalInfo would likely just be a readonly object used for display purposes only.  You'd likely have a seperate class Animal which would allow a single animal to be modified in your application.

brettswift:
I'm obviously still new to this and hoping that someone can help me out here, because I'm thinking its not a simple explanation. Or maybe I'm just missing something obvious?  Is there a smart client version of the PT app out there that someone has played around with ?

Rocky built a smart client PT app already, it is in the same download as the PT sample.  The project is called PTWin I believe... so if you have the PT sample, you should have both the web and win forms sample. 

Do you happen to have a copy of the book?  If not, I suggest you get one.  Reading it has greatly helped me understand OOD better, and why its good to have distinct editable and readonly objects.. sometimes even more than 2 objects, depending on your use cases.

HTH

Andy

brettswift replied on Wednesday, June 21, 2006

Sorry Andy, I guess I whipped out that post a little too fast.

I wrote that code in this form so GetAnimalList() does actually come from the AnimalList  BO. The client that is in the sample code from the download is called PTClientService and I have looked at it a little bit.

By my Win Forms contacting the DB directly, I really meant through the local data portal, so its accessing the Busines Objects directly, then the database.  

Because you can't expose the BO's to the Web Service,  there needs to be some kind of intermediate step, so that you can TRULY switch data portals (local and remote) at runtime without changing UI code.

Something like this:

SQL Servier
        |
       V
   CSLA
        |
       V
    Proxy Classes (that reference the BO library, and is referenced by the UI code, and can switch portals.)
       |
      V
 Smart Client UI.

So - because of this proxy - we lose the BO features - such as IsValid, IsDirty, and other features that is used by WinForms to make the interface very interactive. 

I guess we could have the UI cast / convert the proxy AnimalData class back into an Animal class - but then we'd have to do proxyClass.Save(animal); and proxy would convert that back to the AnimalData class (and could probably cast AnimalData to Animal when it grabs the AnimalData proxy class from the dataportal.

This is already getting ugly and confusing.. haha.  

Surely there's got to be a way of doing  animal.Save(); and have the DataPortal know to parse that and pass it through to the web service..   When I was initially getting into CSLA - this is what I thought could be done, but I guess not.

I just found a .NET starter kit with an online/offline Smart Client.  It looks like it doesn't switch to a local database but will grab objects (at the users request) and copy them locally - kind of like signing it out off the server, and when you go back online it will sync it up.

Maybe for a new CSLA guy this is a lot to chew!

 

ajj3085 replied on Wednesday, June 21, 2006

brettswift:
I wrote that code in this form so GetAnimalList() does actually come from the AnimalList  BO. The client that is in the sample code from the download is called PTClientService and I have looked at it a little bit.


I see.  I've been known to do that quite a bit as well.

brettswift:
By my Win Forms contacting the DB directly, I really meant through the local data portal, so its accessing the Busines Objects directly, then the database. 

Ok, so far, so good then.

brettswift:
Because you can't expose the BO's to the Web Service,  there needs to be some kind of intermediate step, so that you can TRULY switch data portals (local and remote) at runtime without changing UI code.

Something like this:

SQL Servier
        |
       V
   CSLA
        |
       V
    Proxy Classes (that reference the BO library, and is referenced by the UI code, and can switch portals.)
       |
      V
 Smart Client UI.

So - because of this proxy - we lose the BO features - such as IsValid, IsDirty, and other features that is used by WinForms to make the interface very interactive.

I'm not sure I follow here; I would think your BOs would be distributed with the smart client application.  Why do you want to put a web service between the UI and the Business layer (or am I misunderstanding again)?  The only reason I could think of to do that is if you are not the one writing the UI... but then you would design a web service which uses your business layer, but the web service would be more of a facade layer.  Anyone that creates a UI which interacts with your web service facade wouldn't have the rich experience that you could create if you tied directly to the BO.. but thats just the price paid for writing an application to a web service.

I guess I'm just not following what it is you want.

brettswift:
I just found a .NET starter kit with an online/offline Smart Client.  It looks like it doesn't switch to a local database but will grab objects (at the users request) and copy them locally - kind of like signing it out off the server, and when you go back online it will sync it up.

There's many ways to do the online / offline application.  I would think that your BO would handle this in your data portal methods, by having some means of knowing the application is offline (if the user can specify online or offline, you will probably need a BO the UI can use to set the current state).  Possibly this may even be taken care of by your DAL layer; at least that's the method I'm going to pursue when I need to make my application 'offlineable'.  The DAL will determine if the master server is available or not, and hide this from my business / UI layers.  How well it will work remains to be seen though. :-)

HTH

Andy

brettswift replied on Wednesday, June 21, 2006

Ok Andy, from what I'm getting from your post... create the facade later (which I've been calling proxy classes) and deal with those... 

So, to answer my question from the post a minute ago, with web services or remoting, you can't interact with the BO's - you can only interact with the facade / proxy classes.

Am I right?

 

If I am right, the whole notion of "UI not caring about the dataportal" is still mis-guided, and the root of all my confusion on this - because yes.. the UI does care in a web service environment because it has to deal with only the proxy / facade classes.

Am I right here?  What does Rocky mean on page 579 of the C# 2005 book, in the last sentence of the 2nd paragraph at the top of the page:

"The most important thing to realize about the site configuration is that the data portal can be changed from local to remote (using any of the network channels) with no need to change any UI or business object code."

 

Vadiraja replied on Wednesday, April 23, 2008

ajj3085:
brettswift:
In the book it says you're supposed to be able to switch from a local datasource to a remote datasource via the config file, (sounds great for a smart client) but when I look at the code samples in the book I don't see how this can be done....

I have a method that I'm trying to convert from
1) a Local datasource where the Win Forms will connect with the database directly, and load up values in a TreeView control,
to....
2) loading them from my Web Service.

Here is your first problem; your Winform app is trying to talk to the database directly.  Your Winforms app should be communicating with a BO, which will handle the data access.  Your data access code should only be in the DataPortal_XXX methods.

There's another problem as well; the DataPortal isn't meant to allow you to switch the type of datasource.  So if you're BO uses SqlClient, it will always use SqlClient (the difference is that your BO's DataPortal code can run locally, which means the client computer will connect directly to the database OR on a remote server (such as one inside a firewall), which means that your BO will move from the client workstation to an IIS server, and the IIS server will connect to the database.

To allow a switch from SqlServer to a web service would be tricky; you would need some kind of data access layer which hides the specifics of communicating with your datastore.  For example, I wrote a custom one, where each class represents a row from a table or view.  I have Insert, Update, Delete and Load methods.  I designed it in such a way that I can switch between Sql server or Oracle, and not have to change my business code at all.  I admit though, a WebService provider could be difficult, but it may be something I could create for my DAL.

brettswift:
1) dealing with AnimalInfo objects that are loaded into the AnimalList

2) if proxy classes are developed as in the PT sample app, I'd be dealing with AnimalData objects in an array.

So, question being - how do I write UI code so that it is independant of the Data Portal ?  (2 parts)
a) How do I make this line:
              i)AnimalList aList = Animal.GetAnimalList();  // from AnimalTracker.Library;
      compatible with this line: 
              ii)AnimalData[] aList = svc.GetAnimalList(); // using web service reference.

I'm assuming that Animial is a business object.  GetAnimialList shouldl look something like this:

/// <remarks>EmptyCriteria inherits from CriteriaBase, and is a private class embedded in your AnimalList class</remarks>

public static AnimalList GetAnimalList() {

     return DataPortal.Fetch<AnimalList>( new EmptyCriteria() );

}

private void DataPortal_Fetch( EmptyCriteria crit ) {

// This is where your data access would go, and here's where you'd need to interface with a DAL of  your choosing.

}

On more thing; GetAnimalList should be defined in your AnimialList class, not your Animal class.

brettswift:
Maybe - these ReadOnlyList bases (AnimalInfo) are ok to use instead of the proxy classes?

AnimalInfo would likely just be a readonly object used for display purposes only.  You'd likely have a seperate class Animal which would allow a single animal to be modified in your application.

brettswift:
I'm obviously still new to this and hoping that someone can help me out here, because I'm thinking its not a simple explanation. Or maybe I'm just missing something obvious?  Is there a smart client version of the PT app out there that someone has played around with ?

Rocky built a smart client PT app already, it is in the same download as the PT sample.  The project is called PTWin I believe... so if you have the PT sample, you should have both the web and win forms sample. 

Do you happen to have a copy of the book?  If not, I suggest you get one.  Reading it has greatly helped me understand OOD better, and why its good to have distinct editable and readonly objects.. sometimes even more than 2 objects, depending on your use cases.

HTH

Andy

DansDreams replied on Wednesday, June 21, 2006

Brett, I'm not really seeing the problem either as I'd also suggest you shouldn't be trying to accomplish what you are.

Maybe if you gave some additional background... do you already have some pre-CSLA web services in place that provide data?

DansDreams replied on Wednesday, June 21, 2006

The UI would never know or care whether remoting was used or not... that's a business layer option.  I'm not getting on the same page as you.

brettswift replied on Wednesday, June 21, 2006

Well I'm definately lost somewhere  ... because I seem to be getting 2 conflicting answers.  The book says create a proxy class and get the ProjectList by calling  webservice.getProxyObject();  From what I'm getting from this post is that the UI shouldn't care about the data portal. - Until I learn more from you guys, the UI DOES care, because in one instance it calls the web service directly and in the other it can use the BO's directly.

IE:   WebService.GetProxyObject     vs   BOLibrary.GetCSLAObject();

those are 2 distinct UI calls.  - I don't see the reasoning for saying the UI doesn't care about the data portal - because these are  2 dataportals with their own specific UI code.  

 I guess I'm missing how this would all work then - maybe the sample code in the book confused me because its referencing the web service (which I don't see how this could work without - you say the UI shouldn't care, but if thats the case, why is Rocky creating these ProjectData proxy classes in his web service?  My perspective is, say if I had a remote dataportal ona web service, and I wanted to one day change it to a local dataportal - supposedly what you're both telling me is that the UI code shouldn't care - so maybe explain how?  Remote Web Service as a portal uses svc.getList.  If I take the remote portal away and set it to a local data portal, svs.WebService will fail..  this is where I'm really confused.).

My HorseTracker.Library IS distributed to the client, but if I my UI doesn't care about the portal, it should be able to make the following call right?

Animal animal = Animal.GetAnimal(id);

//change it

animal.Save();

?

  From the book's sample code it seems like the only option is to create proxy classes...   I'm lost here somewhere... maybe my understanding of "the UI doesn't care about the data portal" means something else than what I'm interpreting it as.

I guess I'm pretty new to this to make a lot of sense from the book.  

Maybe the best way to make progress on this question is to ask - what would my UI code look like, for me to be able to go and one day 2 months from now change the Data Portal from a Local DataPortal to a Remote Portal using Web Services - without changing UI code  ?

ajj3085 replied on Wednesday, June 21, 2006

Ok, I think the confusing is coming from the fact that the book tells you

1) How to create a web service (which fucntions as a UI layer, in a manner) to allow outside people to call services on your server which performs tasks.  These tasks still need to follow business rules, so the web service uses your BOs to carry out the services offered.  This has nothing to do with the data portal at all.  The web service you build here will interact exactly like a Web or Win client would interact with your Business layer.  This is a UI <--> Business layer communcation.

2) The data portal can use web services to access the dastabase, instead of using remoting or running locally.  I can't speak as to why you'd use this data portal over remoting + IIS (haven't gotten that far in the book yet), but its just another transport to allow the Business layer to communicate with the Data layer..  Data Portal is only used for Business layer <----> Data layer communciation.  It specifies if the client talks to the db (the client being the WinForms, WebForms, or Web service UI ) or if it happens on a server (the BO 'leaves' the client and moves to another computer, where the data code runs.  When the data code is done running, the BO 'leaves' that other computer and goes back to the client).

To answer your last question, you have to realize that you're only changing how the business layer and the data layer communicate.   So if you want data access code to run on a server instead of a client, you just change the .config file for your application (Web.Config for a Web Service  or WebForms app, App.config for a WinForms app).  Your code does not change at all; the only change is that your BO will physically leave the client and move to the server to execute dataportal_XX methods.  Does that clear things up at all?  You only create a proxy class if you are doing #1... exposing services which need to follow rules to the internet.

brettswift replied on Wednesday, June 21, 2006

Ok, thanks Andy. 

I think this setup is clear now, and what I was hoping to be able to do would require another  BO<-->UI  Data Portal type scenario, maybe call it a UI portal or something...which I have no idea how you'd create in order to get your BO's across the internet.

I live in oil country, so I'm thinking along the lines of a possible remote disconnected smart client application.  Say an engineer takes his laptop out to well sites, uses a win forms client, in a disconnected setting to enter data on each well.  He then goes back to the office, plugs in, and via web services syncs up the data with the main server in another city.  I was thinking of having SQL Express on the laptop (or SQL Everywhere) that would replicate via some web service calls to the main server.   The reason I wanted to figure out this post was that I wanted the database to be able to be copied onto the laptop, and when not connected to the internet, change to a local connection and manipulate data  without the win forms UI really acting too differently, except for not being able to pull new data off the server.  

 

Ambitious thought I guess.  For now I will continue my AnimalTracker using web services as the UI layer, and a WinForms  click once deployment as my presentation Layer.

Phew!   I think I must have injected some Red Bull into my veins today!

Thanks guys, that was a confusing post for you to understand given what I thought might have been possible with the existing framework.  If anyone is interested in developing a management utility that could get the BO's across the internet in a secure fashion - I'd be interested in helping out.   Maybe this will be a future addition to the framework so we can have a smart client as rich in features as a local Win Forms client!

 

ajj3085 replied on Wednesday, June 21, 2006

Glad to help get things clearer.

Disconnecting doesn't mean you need to use web services at all.  You could have the app connect to a local database, and use straight replication to managed syncing of data.  If you do have the Sql server sync to another sql server, you can have them do so over web services, but again this wouldn't affect yoru application at all; you could also roll your own data syncing routine, but again, I think that would be seperate from yoru application and may not even use your busniess layer.

As far as your AnimalTracker application, if you're going to use ClickOnce to deploy the software, I'm not really sure if you need to include web services at all; your business layer assembly could be distributed with the UI application.  Just to clearify, a web service isn't a UI layer at all... I simply meant that it would act as a UI layer in that it would consume your BOs the same way your Win application would.  Sorry if I added in some confusion by doing that.  At any rate, if you do decide to have your Win app talk to a web service which talks to your BOs on the UI's behalf, you can go that route, but as you noted you'll lose all the neat databinding and IsDirty IsNew stuff.

Andy

brettswift replied on Wednesday, June 21, 2006

Ok, well one more question then.  If I deploy using ClickOnce, and deploy the BO assembly (HorseTracker.Library), I still need some way of communicating over the internet (to the database on my machine) OR deploying a full database for a fully disconnected environment.

And - if I'm using my Smart Client distributed with Click Once - over the internet - there is no need to have the HorseTracker.Library referenced on the Smart Client, because it will only be using the facade layer anyway... (given it will never be run offline to a local database).

Still on the same page?

ajj3085 replied on Wednesday, June 21, 2006

brettswift:
Ok, well one more question then.  If I deploy using ClickOnce, and deploy the BO assembly (HorseTracker.Library), I still need some way of communicating over the internet (to the database on my machine) OR deploying a full database for a fully disconnected environment.


Correct, you'll need to have the app talk to the database over the internet (directly or indirectly) OR you will have to go with some kind of disconnected mode.

I doubt you want to open port 1433 for sql server to the internet, so this is where the Remote data portal or web services data portal will come in handy.  Here's a pretty secure setup...

The client, which includes your UI and your business layer, updates deployed via ClickOnce.  The configuration file specifies to use remoting to an IIS server.

Your web servicer, which is acting as an application host.  This server is likely on a DMZ and only has port 80 open (assuming you're remoting host is IIS).

Your database server, which is behind the firewall.  The web server can reach the database through the firewall through port 1433. 

When your BO needs to save, it moves itself (the data portal actually does this, but its hidden from your objects) from the client to the web server.  Code in the DataPortal_XXX routines run on the webserver, and can access the database server.  Once the data code is done running, the newly updated BO moves back to the client, and your code picks up there.

brettswift:
And - if I'm using my Smart Client distributed with Click Once - over the internet - there is no need to have the HorseTracker.Library referenced on the Smart Client, because it will only be using the facade layer anyway... (given it will never be run offline to a local database).

I would think you need the HorseTracker.Library, since your UI would be directly consuming your business layer; I don't see a need for a facade layer or web services with anything you've wanted to do so far.  Everything I've said so far assumes an Online only mode application.

If you go the disconnected route, you'll likely use the Local data portal, which talks to a local database.  I would probably say it should ONLY talk to the local database, and when the client computer is back on the corp. network, the databases can sync.

From what you've described, I wouldn't try to do both options though.  Unless you have clients which are never in the office and usually have an internet connection, but MUST be able to live without an internet connection... but that is pretty complicated setup.

HTH
Andy

brettswift replied on Wednesday, June 21, 2006

Okey dokey this is sinking in now.  (I think).

Ok, so I think this is what I was getting at originally.   I sorta understood that the Data Portal moved objects from client to server. (or handled them locally).  Hence the [RunLocal] attribute you can put on DataPortal_Create()  methods. 

The setup you just suggested, using a Remoting as the host to the Server Portal, can pass BO's across the internet, to which Web Services can't - because with web service calls you'd be needing a method call essentially, external to the BO.

I would think this to be not as secure as using a Web Service with WSE's to encrypt data going across, because with a Remoting server, data is transfered in plain text no ?

Ok, I'm on track here I think.


cmellon replied on Thursday, June 22, 2006

Hi Brett,

The remoting server can be as secure as you can make any website if its hosted in IIS.  For example you could run the dataportal using remoting and then set your IIS to use SSL, which means all data will be encrypted.

Basically by hosting the remoting server in IIS you get the full functionality of IIS at your disposal, same as you would a webservice.

I'm not too up on WSE so not sure what advantages WSE gives you, but if you looking to just encrypt the data between you client and server, I would opt for SSL.  You don;t need to change anything in your code just enable SSL on your server.

Hope this helps

Craig

ajj3085 replied on Thursday, June 22, 2006

Craig is correct; you should be able to use SSL and remoting together.

I believe the objects serialize to binary however, so its not plain text, but it could still be easily reconstructed by a 3rd party (especially if they can get the business library).

Now, not to add more confusion when we've got things clear, but you CAN use the web service data portal to transfer your BO from client to server and back again.  But functionally it makes no difference, its doing the exact same thing as remoting would...which is simply serializing your BO, sending it across the wire, and the server deserializes it and runs the DataPortal_XX code.  (And the server reverses this to send the modified BO back to the client). 

So think of the DataPoratl as something whcih just moves the BO back and forth; the remoting BO uses one technology to do this, the web services uses another.  When WCF comes out, there will be a data portal for that as well... but its purpose is the same... just a way to move BOs across the wire.

HTH
Andy

Copyright (c) Marimer LLC