Tuesday, January 5, 2010

Project Server entity mapping: Introduction

Enterprise solutions development usually means a next level of business logic implementation complexity. One of the keys to success and maintainability is unit testing which introduces some requirements for the source. Each platform has specific features and data containers. Project Server uses DataSet-based protocol for PSI web services, which is good for large data structures transmission, but forces us to copy source parts between methods and after several months maintenance becomes a real nightmare. In order to avoid extra complexity it is convenient to separate DataSets and PSI calls to services layer and concentrate on business rules.

Let’s say we need to work with base project data (ID and Name) and one custom field “Sample Assumptions”. The base project data is stored in “Project” table and custom fields are in “ProjectCustomFields”. To load project with our custom field we need to search for data in two tables and handle all necessary data type conversion. Let’s imagine that we have number of different custom fields. Every new custom field will increase number of lines in your project and make you to write additional source at least in two places: load and update project data.

To handle all this stuff we implemented services which use entity metadata to map data from DataSets to our custom entity. Entity class for our example will look like:
public class Project
[PSEntityUidField(ColumnName = ProjectCustomFieldsColumnNames.PROJ_UID)]
public Guid Uid { get; set; }

[PSNativeField(ColumnName = ProjectCustomFieldsColumnNames.PROJ_NAME)]
public string Name { get; set; }

[PSCustomField("{381b5bb4-2e88-4f73-86e7-f6ffb5e58958}", FieldName = "Sample Assumptions")]
public string SampleAssumptions { get; set; }
Now, having all needed mapping data, we can work with project data in the following manner:

This feature brings us a more clean, reusable and testable code which is highly important for big projects and support stuff. Every time you need to get some other project’s data you’ll just add a new property with mapping info attribute.

Next time we’ll talk about PSProjectService implementation.