Blogs

XPO

eXpress Persistent Objects

XPO – 11.1 Sneak Peek - WCF services for IObjectLayer

In the two previous blog posts, we already described how to provide the IDataStore and ICachedDataStore implementations, working via WCF Services. In this blog post, we will talk about implementing a distributed object layer service (IObjectLayer/ISerializableObjectLayer), working via WCF. Creating a WCF service for ISerializableObjectLayer is a bit more complex than for IDataStore and ICachedDataStore, but it is still very similar.

First, we will create a new Class Library project and add a Customer class via the Persistent Object item template to it (you can see the source code of this class in our first blog). Then, we will create a new WCF Service Application project and remove files with auto-generated interfaces for the service. Since our service needs to know about persistent classes, we will add a project reference to our class library and modify our service class as follows:

  1: using DevExpress.Xpo;
  2: using DevExpress.Xpo.DB;
  3: using DevExpress.Xpo.Metadata;
  4: using ClassLibrary1;
  5: ...
  6: public class Service1: SerializableObjectLayerService {
  7:     public Service1()
  8:         :base(new ObjectServiceProxy()){
  9:     } 
 10:     static Service1() {
 11:         string connectionString = MSSqlConnectionProvider.GetConnectionString("localhost", "ServiceDB");
 12:         IDataStore dataStore = XpoDefault.GetConnectionProvider(connectionString, AutoCreateOption.DatabaseAndSchema);
 13:         XPDictionary dictionary = new ReflectionDictionary();
 14:         dictionary.CollectClassInfos(typeof(Customer).Assembly);
 15:         XpoDefault.DataLayer = new ThreadSafeDataLayer(dictionary, dataStore);
 16:         XpoDefault.Session = null; 
 17:     }
 18: }
 19: public class ObjectServiceProxy : SerializableObjectLayerProxyBase {
 20:     protected override SerializableObjectLayer GetObjectLayer() {
 21:         return new SerializableObjectLayer(new UnitOfWork(), true);
 22:     }
 23: }
 24: 

To finish with the service, we will need to change some binding properties in its Web.config file:

  1: <system.serviceModel>
  2:  <services>
  3:    <service name="WcfService2.Service1" behaviorConfiguration="WcfService2.Service1Behavior">
  4:      <!-- Service Endpoints -->
  5:      <endpoint address="" binding="basicHttpBinding"
  6: contract="DevExpress.Xpo.DB.ISerializableObjectLayerService">
  7:        <identity>
  8:          <dns value="localhost"/>
  9:        </identity>
 10:      </endpoint>
 11:    </service>
 12:  </services>
 13:  <behaviors>
 14:    <serviceBehaviors>
 15:      <behavior name="WcfService2.Service1Behavior">
 16:        <serviceMetadata httpGetEnabled="true"/>
 17:        <serviceDebug includeExceptionDetailInFaults="false"/>
 18:      </behavior>
 19:    </serviceBehaviors>
 20:  </behaviors>
 21: </system.serviceModel>
 22: 

At this time, our service is ready to use and all that we need to do is to write the client part.

For the client, we will add a Console Application into our existing solution and add a project reference to the class library with our Customer persistent class. The Main() method should also be modified as follows:

  1: using DevExpress.Xpo;
  2: using DevExpress.Xpo.DB;
  3: using DevExpress.Xpo.Metadata;
  4: using ClassLibrary1;
  5: ...
  6: namespace ObjectWcfClient {
  7:     class Program {
  8:         static IObjectLayer ObjectLayer;
  9:         static void Main(string[] args) {
 10:             ISerializableObjectLayer serializableObjectLayer =  
 11:                 new SerializableObjectLayerServiceClient("BasicHttpBinding_ObjectLayer");
 12:             serializableObjectLayer.CanLoadCollectionObjects.ToString(); //Check connection
 13:             XpoDefault.DataLayer = null;
 14:             XpoDefault.Session = null;
 15:             ObjectLayer = new SerializableObjectLayerClient(serializableObjectLayer);
 16:  
 17:             using(UnitOfWork uow = new UnitOfWork(ObjectLayer)) {
 18:                 using(XPCollection<Customer> customers = new XPCollection<Customer>(uow)){
 19:                     foreach(Customer customer in customers) {
 20:                         Console.WriteLine("Company Name = {0}; ContactName = {1}", 
 21:                             customer.CompanyName, customer.ContactName);
 22:                     }
 23:                 }
 24:             } 
 25:             Console.WriteLine("Press any key...");
 26:             Console.ReadKey();
 27:         }
 28:     }
 29: }
 30: 

The final step will be adding the App.config file into the client project and modifying it as follows:

  1: <?xml version="1.0" encoding="utf-8" ?>
  2: <configuration>
  3:   <system.serviceModel>
  4:     <bindings>
  5:       <basicHttpBinding>
  6:         <binding name="BasicHttpBinding_ObjectLayer" maxBufferSize="2147483647"
  7:             maxReceivedMessageSize="2147483647">
  8:           <security mode="None" />
  9:         </binding>
 10:       </basicHttpBinding>
 11:     </bindings>
 12:     <client>
 13:       <endpoint address="http://localhost:64466/Service1.svc" binding="basicHttpBinding"
 14:           bindingConfiguration="BasicHttpBinding_ObjectLayer"
 15:           contract="DevExpress.Xpo.DB.ISerializableObjectLayerService" name="BasicHttpBinding_ObjectLayer" />
 16:     </client>
 17:   </system.serviceModel> 
 18: </configuration>
 19: 

Now if we run the service and client parts, we will see the following output:

Result
As you can see, our client connects to the service and loads serialized persistent objects from it, and not just plain statements (insert, update, delete, select). You can learn more on which capabilities it opens for XPO customers at the end of our introductory blog for the object layer.

Happy XPOing!Winking smile

Published May 17 2011, 06:10 PM by
Bookmark and Share

Comments

Nate Laff

Since the developer is not controlling the service implementation itself, what is the advantage to using this over the IDataStore method?

The IDataStore is just tunneling to the DB where this is actually processing server side, right?

May 17, 2011 10:04 PM

Nick Khorin

Nate, I think that SerializableObjectLayerService is included in XPO for the same reason as WebServiceDataStore: a ready-to-use implementation of a service. You, as a developer, can implement it in your own way, and the easiest approach to get started is to copy code from XPO to your project. Let's wait for v11.1. I'm also eager to see how guys implemented SerializableObjectLayerService.

May 18, 2011 12:31 AM

Steven Rasmussen

Hi Dennis - this is great stuff!  I'm still waiting for the big announcement regarding how this has paved the way for the new security system in XAF that will be released in 11.1 :)

May 18, 2011 9:12 AM

Robert Fuchs

@Steven ... why this has *not* paved the way for the new security system in XAF that will *not* be released in 11.1

;-)

AFAIK, Robert

May 18, 2011 9:48 AM

Steven Rasmussen

That's pretty disappointing :(

May 18, 2011 11:56 AM

Michael Proctor [DX-Squad]

As the ObjectLayer was only "mentioned" for 10.2 as a included but not documented feature, I didn't put it high on my priorities.

However the next iteration of my project, this is now planned to be implemented.

Currently my project uses WCF services using the IDatastore as my contract. This is working well especially with Noemax WCFX extensions (compression/fast xml writer/reader). However as realised by other XPO'ers, we are abstracting the raw datastore, therefore all security has to be on the client, which is not the ideal scenario.

The ObjectLayer to my understanding is allowing us to abstract at the DataLayer, meaning the Service will get a bunch of Objects that need to be saved or a bunch of objects it needs to send out. This allows us more control at the server to make decisions such as to confirm if the user saving is indeed allowed to modify this record, possibly only save particular fields of the object, which works the other way whereby when retrieving data we can clear fields out before sent over the wire (and ensure that the blank fields are saved back to the datastore)

Another feature I have planned using this is moving my auditing feature to the server. This is not only more secure, but also reduces the amount of data sent over the wire. Currently when a user performs a save I am sending both the object to be saved plus an additional audit object containing what fields changed. This effectively doubles my transfer on modificaiton of data. Moving this to the server immediately drops it.

Overall I am very excited to get my teeth stuck into this, (hopefully about 2 weeks) to which I will be blogging my results.

Great work guys.

May 18, 2011 5:42 PM

Slava D (DevExpress)

Thank you for the feedback, guys!

@Michael Proctor:

Yes, you are absolutely right. Your explanation is so complete that I even have nothing to add. Thank you. :D

May 19, 2011 3:25 AM

Robert Thomas

Is there an example on how to use this for XAF?

June 12, 2011 11:05 PM

Kobus Smit

Hi Michael

Did you progress with your IObjectLayer project? I'm really interested in that blog post :)

Do you perhaps have an XAF example using WCF services?

Currently my users are complaining about speed connecting the WinForms UI to a remote database. I hope that WCF + the Noemax compression might improve the performance...

Regards

Kobus

July 25, 2011 10:41 AM

Michael Proctor [DX-Squad]

Hi guys just a quick update to say I have started my blog posts

www.alfware.com.au/.../47-how-to-serialize-your-xpo

www.alfware.com.au/.../48-xpo-objectlayer-tutorial-breakdown

Hope these help a little

July 28, 2011 7:32 AM

Kobus Smit

Thanks Michael, will check it out!

August 2, 2011 4:44 PM

stefano del furia

Hi guys, i would like to know if some can point me to some examples of using WCF + the Noemax library and use it with XPO.

i has been able to work with IDataStore and WCF and i would like to use the Noemax library to improve performance.

Thanks

November 3, 2011 11:01 AM
LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, Silverlight, ASP.NET, WinForms, HTML5 or Windows 8, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2014 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners