Remoting & Seriralization future headaches?

Posts   
 
    
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 16-Mar-2004 08:40:40   

Hi

I'm currently have just began working on a project and I noticed something that I think might give me future headaches. I want to clarify it now, so if I have to switch directions then any code changes already done will be minimal. So you all can get an idea, I think I need to describe the design architure of the project:

There are 4 layers, each is own project: UI, Business layer, Data Acess layer (LLGen - Adapter - 2 projects), Data Store (SQL Server)

The UI (ASP.NET, Windows GUI App- 2 seperate projects) only have a reference to the Business layer. The Business Layer in turn references ORM Support Classes, Database General, Database Specific .dll's. The design goal of this approach is to only expose to the UI methods and properties that I expose in the BL and shields it from anything "uneeded". It also allows the BL to work both with the UI's of the ASP.Net app and Win App with ease. I only have to worry about UI differences (ex: web Form control behavior & properties vs GUI controls et..) The data driven objects needed by the ASP and Win Forms are derived from the BL and passed to the UI layer.

The BL is set up as follows. For each entity class generated into the Data generic project, there is a class that inherits from this object (BL is a seperate project). For example the generated class CompanyEntity has as corresponding class I call CompanyObject in the BL that inherits CompanyEntity. Any property or method I want to expose to the UI, I override or create in the CompanyObject class because the UI only refences the BL. A little extra work, yes, but I have comple control over what can be passes or exposed to the UI.

So far it's working like a charm. Once I do the extra work of coding the objects in the BL, I can use what I need in the two UI projects, & only have to worry about UI behavior differences in the 2.

So - this leads me to my doubt. The classes in by BL, for example 'CompanyObject' I want to treat as serializable objects, encapsulating both business logic & data acess (through the the adapter classes) which I will use for remoting. For this I need to declare and create a DataAccessAdapter to be able to retrieve things from the db via the LLGen data generic classes. I just noticed that the DataAdapter class is NOT serializable. If I'm not mistaken, to serialize an object, all it's referenced or exposed objects have to be serializable also. I'm afraid this will lead to problems later on when I set up remoting.

So? What's the opinion of the experts? Am I missing something? How can I get around this problem?

Thanks in advance..

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 16-Mar-2004 09:26:28   

The DataAccessAdapter class is not serializable because it acts as a service provider. It furthermore contains (can contain) an open database connection at given moments, something which is not transferable to another machine. The DataAccessAdapter class is offering a service which can be applied to entities or sets of entities, typed lists or typed views. So it's a separated object, providing a piece of functionality which can be applied to an object.

You should look at it this way: you have layer A on a machine and layer B on another. A is your DAL, B is your BL layer. A provides B with entity objects when B calls a method of A. A also persists / deletes entities for B if B calls another set of methods.

Then only the entity classes, typed lists and typed views are transported between the layers. You also have completely separated the data access centric layer from the data consumption layer: B doesn't know anything about databases, it asks A for objects and asks A to do something with the object. How A does that is not important for B.

This is also the reason why Adapter's entity objects do not have any persistence methods/logic. That logic is offered by a DataAccessAdapter object. When you need that functionality, you instantiate the object and call one of its methods.

Frans Bouma | Lead developer LLBLGen Pro
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 16-Mar-2004 13:40:07   

Thanks for your reply, Frans

Mmmm, let me expain a bit further my intentions. Like I said before I want to set up remoting. Here's the architecture I want set up via remoting:

Client code (UI - client machine) Business Object layer (BOL) (Application Server) Remoting web site (probably on application server) DAL (LLGen classes) layer (Data store server)

The client code requests a business object from the application server. The business object encapsulats business rules and retrieving data from DAL layer. A expample business object would might have something like this:

(Name is a property in base class derived from field in SQL)

<Serializable()> _ Public Class MyObject Inherits LGen.DAO.EntityClasses.MyObjectEntity 'Seperate assembly

Private m_adapter as New DataAdapter

Public Sub New() MyBase.New() End Sub

Public Sub New(ByVal Id As System.Int32)
    MyBase.New(Id)
End Sub

Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
    MyBase.New(info, context)
End Sub

' Do something Public Shared Function SaveObject (ByVal Name As String) As Boolean Me.Name = Name if Me.ValidateName then Return Me.m_adapter.SaveEntity(Me) End If End Function

'Simple validation for example purposes Private Function ValidateName(ByVal stName as String) as Boolean Return Not stName.Length.Eqauls(0) End Function

End class

Remember, the UI code only has a reference to the BOL, so the business object must call apropiate methods via the adapter. The BOL has necessary references to the LLGen classes.

So, the bottom line is - can the business object be unanchored even though the DataAdapter class in not serializable and be passed to the UI code via remoting?

I haven't attempted remoting with LLGen so I'm asking for expert opinion now before I beat my head against the wall before trying to do something that's impossible.

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 16-Mar-2004 18:19:11   

I think Frans is saying that your Business Entity Objects should be what is passed back and forth between your UI layer and your Business Process layer. Those business entity objects should only be fetched and persisted from that Business Process Layer located on the server side, thus you don't need to serialize the data adapter.

Client UI Layer -----> Makes Calls To -----> Business Layer via getEntity()

UI Layer <------ Fetches and Returns Entities <---- Business Layer calls Fetch()

UI Layer ------> Modifies and returns Entity -----> Business Layer calls Save()

note that the UI Layer never calls Fetch or Save, only the server. Thus, the dataadapter is not needed on the client side. In fact you should hide those properties in the extended entities you are creating.

Hope this helps.

Jeff...

<EDIT> Looks like the posting engine likes to play with whitespace, so I had to delete the "Server" label that was above the Business Layer side of the equation above. But, it should show that the UI Layer is located on the client and the Business layer is located on the server.

Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 16-Mar-2004 19:30:07   

Thanks Jeff for your reply

Well, then, I'm assuming that what I proposed should work. The (very basic) class I mentioned above then should work in a remoting scenario. If I understand your terminolgy then the following should work (MyObject class is mentioned above):

UI layer:

.....

Private Sub SaveTheUserInput() Dim myObject as New MyObject Dim InputString as String = txtUserName.Text If myObject.SaveObject(InputString) Then Messagebox.Show("Ok!") Else Messagebox.Show("Failed!") End If

.... rest of UI class

Am I correct?

UI---->requests business object from business layeron App server UI<--- returns business object from business layer on App server UI Modifies exposed properties UI calls exposed method in business object UI ----> returns business object to business layer ---> Modifies data via DAL UI <--- business layer returns value via business object

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 16-Mar-2004 20:07:52   

Stoop wrote:

Thanks Jeff for your reply

Well, then, I'm assuming that what I proposed should work. The (very basic) class I mentioned above then should work in a remoting scenario. If I understand your terminolgy then the following should work (MyObject class is mentioned above):

UI layer:

.....

Private Sub SaveTheUserInput() Dim myObject as New MyObject Dim InputString as String = txtUserName.Text If myObject.SaveObject(InputString) Then Messagebox.Show("Ok!") Else Messagebox.Show("Failed!") End If

.... rest of UI class

Am I correct?

myObject.SaveObject(InputString) will fail unless called from the server, thus it seems the routine SaveTheUserInput should be located on the server and called as a service from your UI via remoting/web services.

UI---->requests business object from business layeron App server UI<--- returns business object from business layer on App server UI Modifies exposed properties

UI calls exposed method in business object UI ----> returns business object to business layer ---> Modifies data via DAL UI <--- business layer returns value via business object

The bolded line above, if it refers to a Save method of any sort, again, will fail if called from the client/UI. The business layer must be the one to call Save(). In fact, you should remove the Save() method from your extended entities completely to prevent the UI from ever calling them, as it will always result in an exception.

Jeff...

Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 16-Mar-2004 21:41:13   

Jeff - again thx for your reply

I'm going to set up a remoting scenario & give it a go. I guess the only way to really get it straight is to see it in action. I'll post a reply if/when I get it up and running..

Stoop

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 16-Mar-2004 21:47:30   

I'll reply to this tomorrow. At first glance, Jeff has given you the right answer simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 17-Mar-2004 16:42:22   

This is indeed the desired setup:

UI---->requests business object from business layer on App server UI<--- returns business object from business layer on App server UI Modifies exposed properties

UI ----> returns business object to business layer via call of method ---> Modifies data via DAL UI <--- business layer returns value from method call

Frans Bouma | Lead developer LLBLGen Pro
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 17-Mar-2004 23:11:56   

Thanks guys for your input.

Like I said - I'm going to give this a go in a test project. If I run into problems I'll post them.......

Steve