This sample solution includes a set of projects that illustrate the use of EntitySpaces with Windows Communication Foundation (WCF), which is a technology featureset that arrived when Microsoft .NET 3.0 was released.
This demo is based on .NET 3.5 / Visual Studio 2008. It does not delve into WCF education or theory; it is only a "getting started" sample application that demonstrates how EntitySpaces objects can be used in a WCF architecture.
This is a lightweight sample that does not demonstrate more complex scenarios, such as working with data objects with one-to-many relationships.
This section is provided for those who just want to get the demo up and running and don't want to delve into the details.
To run the demo:
Check the References of each project. If any of the EntitySpaces assembly references are broken (i.e. showing the "missing" icon), you will need to re-reference them. They should be in: %ProgramFiles%\EntitySpaces 2009\Runtimes\.NET 3.5\ Make sure SQL Server Express is installed locally, and that you are a SQL Server admin. If the server is not running as ".\SQLExpress" you need to edit the app.config file in the ES2009WCF_Server project and rebuild the solution after reviewing #1 (above). In Visual Studio's Solution Explorer, right-click on the project called ES2009WCF_Server and choose Set as StartUp Project. Start Debugging. If you don't run into any errors and all is well, go ahead and shut it down (hit ENTER and let it quit). In Windows Explorer, track down the server's EXE file. It should be something like %DEMO%\ES2009WCF_Server\bin\Debug\ES2009WCF_Server.exe. Run it. In Visual Studio, for each of the client projects (each of the projects that are suffixed with "Client"), expand "Service References and right-click on the service reference item (should be something like "ESDemoService") and choose Update Service Reference. Stop the server process you started two steps previously (hit ENTER and let it shut down). Choose one of the client projects (any project suffixed with "Client") that you would like to run, right-click it, and select "Set as StartUp Project". Rebuild Solution. Start Debugging. The demo server will start automatically (after a prompt). Troubleshooting: If with any client project you get an exception saying something followed by ".. The client and service bindings may be mismatched," stop the debugger, keep the server running, and right-click the service reference item in the project (in Solution Explorer) and choose Update Service Reference. If after the server starts successfully you get a System.ServiceModel.EndpointNotFoundException with a message "Could not connect to http://localhost:8731/ESDemoService/Light/. TCP error code 10061: No connection could be made because the target machine actively refused it 127.0.0.1:8731," you will need to temporarily disable Windows Firewall or poke a hole on port 8731 and/or on behalf of all EXE's involved. Be sure to restart the demo server's .EXE (or just kill it and let the demo client start it) as it may get locked in a Faulted state if an exception occurrs.
Troubleshooting:
To create WCF projects:
This demo requires SQL Server 2005 (Express, Standard, or Enterprise edition) to be installed and running on the machine you are running the demo on. (You can get SQL Server Express edition for free at http://www.microsoft.com/express/sql/default.aspx.)
Your SQL Server instance needs to recognize you as an administrator, as the demo server will auto-create the database and database tables when it runs. You can remove this behavior and create the demo database and table(s) manually by opening the app.config file in the ES2009WCF_Server project and changing the appSettings values of createDatabase and resetTableData to false.
If you do decide to create the database and table manually, here is how it should be configured. The database name should be ES2009WCFDemo. You should have the following table structure(s):
USE [ES2009WCFDemo] /****** Object: Table [dbo].[Employee] Script Date: 01/21/2009 17:30:16 ******/ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON CREATE TABLE [dbo].[Employee]( [Id] [int] IDENTITY(1,1) NOT NULL, [FirstName] [nvarchar](50) NULL, [Age] [tinyint] NULL, [Salary] [money] NULL, CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
This is the same SQL script that is used automatically (if enabled) when the demo server is run .
You also need to validate the connection string in the app.config file under ES2009WCF_Server. By default it points to the server ".\SQLExpress".
The first thing that was done when creating this demo was the creation of an Employee database table and the EntitySpaces objects that work with it. The Employee schema is described previously (see Pre-Setup). The EntitySpaces objects were placed in a shared library that contains all business objects that can be used both on the server and in a full (EntitySpaces-referencing) client. This is database-secure because a client does not have a database connection string in the generated code nor in its config file, it only has WCF references if so architected.
To generate EntitySpaces objects,
When using lightweight proxies/stubs, will need to run the generator again for the client project to create special lightweight proxies/stubs. Remember that lightweight proxies/stubs are used primarily if your shared library, as well as EntitySpaces' runtime libraries, will not be referenced by the client application. So in this case, the client will need generated stubs.
So to create the lightweight proxies/stubs for the client, follow the same steps as for creating the "Classes Master" objects, except:
The WCF Server in this demo (project ES2009WCF_Server) is just a console application with ServiceHost. You can also host WCF services in IIS 7 or with WAS (Windows Activation Services) but that is beyond the scope of this demo; again, WCF education is not the intent with this demo but rather how EntitySpaces can work in a WCF architecture.
Before doing anything with EntitySpaces within a server application, an app.config file needs to be created.
After setting up the app.config file with EntitySpaces settings, the first thing our server app needs to do in order to work with EntitySpaces and with the database is initialize EntitySpaces with:
esProviderFactory.Factory = new EntitySpaces.LoaderMT.esDataProviderFactory();
Before moving on, it should be noted that there are a few scenarios where manual serialization must be used when working with EntitySpaces over WCF. While EntitySpaces business objects can be generated with WCF compliance, EntitySpaces was not built around WCF (WCF is a relatively young technology, and Visual Studio's and .NET SDK's generation of WCF stubs is not fully evolved to handle all scenarios). For example, the manual serialization is necessary to retain the behavioral functionality of the EntitySpaces objects such as change/dirtiness state on the client in the conformance pattern used by EntitySpaces.
Examples of manual serialization for WCF have been posted in the EntitySpaces forums and blog, namely
The samples provided prompted the creation of a pair of serialization wrappers that I, the creator of this demo, decided to produce both for this demo and for future use anywhere manual serialization/deserialization is needed.
I posted the wrappers and documented them on my own blog:
Jon Davis: XmlSerialized<T> and BinarySerialized<T>
These wrappers are used extensively throughout this demo, primarily:
To create a WCF service that exposes API points for clients, Visual Studio's WCF Service template items were used:
Some simple tests were added to the ES2009WCF_Server project while creating the server just to make sure things are working. This isn't a TDD implementation but basic invocation of some of the services' API is demonstrated.
This client app will automatically start the WCF Demo Service.
The first client that was created for this demo was the Console-Based Full Proxy Client. This is just a console application that invokes some of the WCF API points. It was created to test and make sure that the WCF services were working correctly. The net result is a demonstration of code that illustrates how EntitySpaces can interact with a WCF service using full proxies.
The verbiage of "full proxies" used here means that the client has EntitySpaces runtime libraries referenced, as well as a shared library that contains the business objects used on the server. The client sees these objects in the same way as the server sees these objects. The only difference is that the client cannot invoke the database directly through the EntitySpaces API. Instead, WCF must be used to explicitly manage all queries using the API points established by the server's WCF services.
Note that the "full proxy" implementation partially supports binary serialization of Query objects so that you can perform a filtered query from a client over WCF. This is partially demonstrated in the demo app by filtering on the Employee's FirstName property.
The Console-Based Lightweight Proxy Demo Client is a complete API demonstration of the WCF service that was exposed for lightweight proxies. It does not reference EntitySpaces runtime libraries nor any shared libraries except for core .NET libraries and the project that contains the Serialized utility classes discussed earlier.
Note that the special proxy/stub classes were generated for this client and added to the client project.
The WinForms-Based Full Proxy Demo Client is a rich GUI illustration of how WCF can be used in a client/server application. It automatically loads all employees, allows you to edit the details of an employee, allows you to delete an employee, and allows you to create an employee. It also demonstrates the use of a binary-serialized Query object by displaying a filter form with a name parameter and range parameters for Age and Salary.
We will be working on a WPF-based client that demonstrates the use of the lightweight proxy/stub classes to be released hopefully in the near future.
When EntitySpaces 2009 Q2 is released we will also have XML-serializable queries as well as a fresh new updated Silverlight demo that illustrates its use. This, too, will utilize the lightweight proxy/stub classes that unfortunately the ES 2008 Silverlight demo [1, 2] did not properly illustrate as the proxy/stub classes were not generated for it.
Hopefully this sample solution clearly demonstrates how EntitySpaces can work with WCF without any significant hassle.
Page rendered at Saturday, July 31, 2010 6:04:56 PM (Eastern Standard Time, UTC-05:00)
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.