This topic provides a sample application demonstrating a way to architect a Middle Tier using WCF and Telerik OpenAccess ORM. The goal is to try the right mix that allows you to build modular code that is maintainable and flexible. The data provider tier consists of two projects - the DAL (containing the OpenAccess persistent classes) and the Business logic (used for executing queries with objects and retrieving data). The goal is to use the the objects only in these two projects because they depend on the OpenAccess libraries. To pass the data to the upper layers, it is wrapped up in business objects that do not depend on OpenAccess. This is how the OpenAccess specific code is separated from the rest of the application. The full source code is available for download from our Code Library.
The application works against the Northwind database. However, it requires some slight modifications to the database. Please run the following SQL script, it will create an additional OrderStatus table and add an OrderStatusId field to the Orders table.
CREATE TABLE [dbo].[OrderStatus](
[OrderStatusId] [SMALLINT] IDENTITY(1,1) NOT NULL,
[OrderStatusValue] [varchar](30) NOT NULL,
CONSTRAINT [PK_OrderStatus] PRIMARY KEY CLUSTERED
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[OrderStatus](OrderStatusValue) VALUES ('Submitted');
INSERT INTO [dbo].[OrderStatus](OrderStatusValue) VALUES ('Verified');
INSERT INTO [dbo].[OrderStatus](OrderStatusValue) VALUES ('Charged');
INSERT INTO [dbo].[OrderStatus](OrderStatusValue) VALUES ('Packaging');
INSERT INTO [dbo].[OrderStatus](OrderStatusValue) VALUES ('Shipped');
INSERT INTO [dbo].[OrderStatus](OrderStatusValue) VALUES ('Void');
ALTER TABLE [dbo].Orders ADD [OrderStatusId] [SMALLINT] NOT NULL DEFAULT 5;
ALTER TABLE [dbo].[Orders] WITH CHECK ADD CONSTRAINT [FK_Orders_OrderStatus]
FOREIGN KEY (OrderStatusId)
REFERENCES [dbo].[OrderStatus] ([OrderStatusId])
ALTER TABLE [dbo].[Orders] CHECK CONSTRAINT [FK_Orders_OrderStatus]
There is a web site in the solution named NSVWeb which consumes the WCF service and demonstrates its functionality. Before running the web site, please make sure the service is running. You can do that by selecting “View in Browser” option from the Service’s project context menu.
WCF Service assemblies:
* ServiceContracts - Following the WCF practices there is an assembly which contains the service Contract INorthwindService. This is the contract that contains the endpoints for the service.
* ServiceImplementation - This assembly contains the NorthwindService class which implements the INorthwindService interface.
* ProviderContracts - The goal here is to loose couple the Service Implementation level from the BLL. To do this, we have a ProviderContracts assembly which contains a ProviderFactory. In doing so, using reflection, the BBL is loaded by simply stating the assembly name and class of the BLL provider to load which contains the endpoints which service the Service Implementation. The data provider assembly and class names are specified in the Web.config file of the service. This design allows us to have many data providers that can rely on completely different technologies but managing the same data. Nevertheless, only one provider can be used at the same time.
<-- Telerik Open Access Provider -->
<add key="NWProviderAssembly" value="NSV.NW.OABLL"/>
<add key="NWProviderClass" value="NSV.NW.OABLL.OADataProvider"/>
The ProviderContracts assembly also contains a Contract for the BLL to implement.
* DataContracts - In keeping the layers separated and also to have our own objects to pass through the service, we have a DataContract assembly. The data contracts contain the same fields as the database. There are different ways to do this but here we have assemblers that convert the DB objects to the data contracts. These assemblers take place in the BBL assembly as it is the highest level that manages the database objects.
Web UI assemblies:
* Proxy - Contains the UIHelper class which is connected to the specified server endpoint and manages data transmitting through the service.