To start things off, I thought of writing about something I've done very recently. Have you ever used csla's remoting portal over a slow network? Internet anyone? Not everybody has a super fast connection and even people that do have days where it seems like they're on 56k dialup...
I have a 1Mbps connection and even though it's pretty fast for download, it's upload speed sucks , so hosting a remoting portal here can get irritating!! (For the ones on the other side at least).
Yes, there's a performance hit because it adds more processing to the overall process, but the size of the transfers are dramatically reduced so that makes up for the processing time. Another thing to take into account is that you don't _have_ to use this dataportal OR the other. You can create both portals in one site and use one or the other depending on your needs, you just need to change your app config, or you could change the url in code on the fly.
So, let's dive into it.
First, for the anxious, how to use it. Assuming you compiled it, added the appropriate dlls to the web site's bin folder, here's the configuration:
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall" objectUri="RemotingPortal.rem" type="Csla.Server.Hosts.RemotingPortal, Csla"/>
<wellknown mode="SingleCall" objectUri="RemotingPortalCompressed.rem" type="Csla.DataPortal.Compressed.Server.RemotingPortalCompressed, Csla.DataPortal.Compressed"/>
</service>
<channels>
<channel ref="http">
<serverProviders>
<provider ref="wsdl"/>
<formatter ref="soap" typeFilterLevel="Full"/>
<formatter ref="binary" typeFilterLevel="Full"/>
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
There isn't a single change from the regular config, other than the fact that I have 2 services a standard portal and a compressed one. You don't need both, so you can remove the first one if you don't plan to actually use it...
Now to the client's app.config:
<appSettings>
<add key="CslaDataPortalProxy"
value="
Csla.DataPortalCompressed.CustomDataPortalRemotingProxy, Csla.DataPortal.Compressed"/>
<add key="CslaAuthentication" value="Csla" />
<add key="CslaDataPortalUrl"
value="
http://<portal's url>/RemotingPortalCompressed.rem"/>
</appSettings>
Simple uh? For those used to setting up a remoting portal, I highlighted the differences with what you'd normally do.
With these simple changes, I have been able to use the portal succesfully in an application that's been working for a long time. No code changes were needed (only config files), just add a reference in the main app to the compressed dataportal and that's it.
Now, how does it work?
The dataportal has a server side object (the portal itself) and a client side proxy. The server side component is simply an object with 4 functions: Create, Fetch, Update and Delete. They all return a DataPortalResult object.
If you look at the remoting portal in rocky's code, all these methods do is redirect those calls to a simple dataportal. My implementation does this exact same thing, although it alters the resulting DataPortalResult in order to compress the object being transported. Here's the Fetch method to give you an idea:
Public Function Fetch(ByVal objectType As System.Type, _
ByVal criteria As Object, ByVal context As DataPortalContext) _
As DataPortalResult Implements IDataPortalServer.Fetch
Dim dp As New Csla.Server.DataPortal
Return Compression.GetCompressedResult( _
dp.Fetch(objectType, criteria, context))
End Function
As you can see, the only thing that changes here from the default implementation is that I call a function that gets a new compressed dataportal result.
The same process is used for create and update. Delete doesn't need it, since there is no object going back to the server.
Update has one more difference, since it's the only instance where you send an object to the dataportal, the client compresses the object before sending it, so it needs to be decompressed before calling dp.Update.
The client proxy behaves similarly, with the difference that it needs to get an uncompressed result:
Public Function Fetch(ByVal objectType As System.Type, _
ByVal criteria As Object, _
ByVal context As Csla.Server.DataPortalContext) _
As Csla.Server.DataPortalResult _
Implements Csla.Server.IDataPortalServer.Fetch
Return Compression.GetUncompressedResult(GetProxy().Fetch( _
objectType, criteria, context))
End Function
GetProxy only get's a cached instance of the proxy to be used.
You'll notice one more thing here. This proxy has a feature that let's you swap proxies on the fly.
You don't need to use it or even be aware that it exists. But if you're in a situation where you need to swap between a simple portal and a remoting portal on the fly, all you need to do is call:
Csla.DataPortalCompressed.CustomDataPortalRemotingProxy.DataPortalType = _
Csla.DataPortalCompressed.DataPortalTypes.SimplePortal
This allows you to switch back and forth between remoting and simple dataportal (and even enterprise services) in case you ever need to.
The portal uses BZip2 compression provided by icsharpcode's #ziplib (it's opensource). You can get that here:
http://www.icsharpcode.com/OpenSource/SharpZipLib/Default.aspx
Well, I hope you enjoyed my first article and that you find it useful.
You can get the code for this article here.
Update:
The Code for this article has been updated. Take a look at
this post.
Andrés
posted @ Tuesday, April 03, 2007 1:22 PM