Entities

Entities API reference and documentation (under construction)

The basics

The Entities part of the framework is to help modeling domain models where the term entities and repositories is some of the main parts of Domain Driven Design.
The help building repositories for handling persistence of entities the framework has two main parts that focus on these tasks, all inside the SPGenesis.Entities assembly:

- The entity mapper (SPGENEntityMap<TEntity> base class)
- The entity manager (SPGENEntityManager<TEntity>.Instance singleton class)

As for example, MS has created the Microsoft.Sharepoint.Linq namespace which targets the same areas but I find it rather difficult to build large and easy maintainable applications using that. It comes with a tool named SPMetal which generates entities out of lists and content types from a sharepoint site.

The SharePoint Genesis Framework for entities is more flexible and gives you more ways when building your entities and repositories.
First of all, an entity is a representation of a real world object; let’s take for example a car. It has certain properties like color, engine type, number of doors etc. If we were to represent this car in our application, let’s say we want to build an ordering application were you can build and buy your own car from a car reseller, we would start out designing the car object properties first.

    public class Car
    {
        public int CarId { get; set; }
        public string CarName { get; set; }
        public string Color { get; set; }
        public int Doors { get; set; }
        public EngineTypeEnum EngineType { get; set; }

        public enum EngineTypeEnum
        {
            NotSpecified,
            Gasoline,
            Diesel,
            Electric,
            Hybrid
        }
    }


This is an abstract representation of our car in our application. Now we need ways to store (persist) these properties in a database which will be a SharePoint list in our case, and give our application an API to store and retrieve all our different car models. This will be our repository which will handle all that. We would need basic functions as Create, Read, Update, and Delete. (CRUD). It could also have a Find-method so we can search in our car database.

The next step is to create the list to which we need to store our cars in. Here we can use whatever technique that suits our application like Genesis Framework, deploying XML-definition, using SP designer, SharePoint API etc. I will choose the first one to create our list and fields in. All this functionality is inside the Genesis Core Framework (SPGenesis.Core assembly) which is explained in the core documentation.

    [SPGENListInstance(WebRelURL = "Lists/Cars", Title = "Cars", TemplateType = (int)SPListTemplateType.GenericList)]
    public class CarsListInstance : SPGENListInstance<CarsListInstance>
    {
        protected override void InitializeDefinition(SPGENListInstanceProperties properties)
        {
            properties.Fields.Add<Color>(true, true);
            properties.Fields.Add<Doors>(true, true);
            properties.Fields.Add<EngineType>(true, true);

            properties.Fields[SPBuiltInFieldId.Title].DisplayName = "Car name";
            properties.Fields.Update(SPBuiltInFieldId.Title);
        }

        [SPGENField(ID = "{E7220810-A926-4E74-B0F7-75628016C71D}", DisplayName = "Color", Type = SPFieldType.Text, Required = true)]
        public class Color : SPGENField<Color, SPFieldText, string>
        {
        }

        [SPGENField(ID = "{7284B419-3D7F-411E-8487-5FA376AA15ED}", DisplayName = "Doors", Type = SPFieldType.Number, Required = true)]
        public class Doors : SPGENField<Doors, SPFieldNumber, int>
        {
        }

        [SPGENField(ID = "{EB6B7F2D-A2A9-4495-8FE3-8C5F6847C165}", DisplayName = "Engine type", Type = SPFieldType.Choice, Required = true)]
        public class EngineType : SPGENField<EngineType, SPFieldChoice, string>
        {
            protected override void InitializeDefinition(SPGENFieldProperties<SPFieldChoice> properties)
            {
                properties.Choices.Clear();
                properties.Choices.Add("Gasoline");
                properties.Choices.Add("Diesel");
                properties.Choices.Add("Electric");
                properties.Choices.Add("Hybrid");
            }
        }
    }



Let’s move over to the next step. Here we will create our entity mapper which maps our entity properties to the actual fields stored in our list instance. We do this with the SPGENEntityMap<TEntity> base class.

    public class CarMapper : SPGENEntityMap<Car>
    {
        protected override void InitializeMapper()
        {
            RegisterIdentifierProperty(car => car.CarId);

            MapField(car => car.CarName, SPBuiltInFieldId.Title);
            MapField(car => car.Color, CarsListInstance.Color.InternalName);
            MapField(car => car.Doors, CarsListInstance.Doors.InternalName);
            MapFieldToEnum(car => car.EngineType, CarsListInstance.EngineType.InternalName, SPGENEntityEnumMappingOptions.ChoiceText);
        }
    }


In this code block we map our entity properties with fields in our list instance.
• CarId is mapped to the list item ID in our list instance by the RegisterIdentifierProeprty method
• CarName is mapped to the title field (built-in list title field)
• Color is mapped to the color field
• Doors is mapped to the doors field
• EngineType is mapped to the choice field. We also declera what enum value to use if the field should not contain any or invalid values.


Now we have everything ready to start building our repository. We will make a simple CRUD class that can handle basic functions.
To create our car we create a "Create"-method inside our repository class and use the SPGENEntityManager<TEntity> singleton class to create a list item in our cars list instance.

    public class CarsRepository
    {
        public SPList List;

        //We need to supply a SPWeb instance to initialize this repository class so we can find our cars list instance.
        public CarsRepository(SPWeb web)
        {
            this.List = CarsListInstance.Instance.GetList(web);
        }

        public Car Create(string carName, string color, int doors, Car.EngineTypeEnum engineType)
        {
            //Create our car entity
            var carEntity = new Car()
            {
                CarName = carName,
                Color = color,
                Doors = doors,
                EngineType = engineType
            };

            //Create a list item in our list instance with our new car entity properties
            SPGENEntityManager<Car>.Instance.CreateNewListItem(carEntity, this.List);

            return carEntity;
        }
    }



To create a complete CRUD repository:

    public class CarsRepository
    {
        public SPList List;

        //We need to supply a SPWeb instance to initialize this repository class so we can find our cars list instance.
        public CarsRepository(SPWeb web)
        {
            this.List = CarsListInstance.Instance.GetList(web);
        }

        public Car GetById(int carId)
        {
            return SPGENEntityManager<Car>.Instance.GetEntity(this.List, carId);
        }

        public Car Create(string carName, string color, int doors, Car.EngineTypeEnum engineType)
        {
            //Create our car entity
            var carEntity = new Car()
            {
                CarName = carName,
                Color = color,
                Doors = doors,
                EngineType = engineType
            };

            //Create a list item in our list instance with our new car entity properties
            SPGENEntityManager<Car>.Instance.CreateNewListItem(carEntity, this.List);

            return carEntity;
        }

        public void Update(Car car)
        {
            SPGENEntityManager<Car>.Instance.UpdateListItem(car, this.List);
        }

        public void Delete(Car car)
        {
            SPGENEntityManager<Car>.Instance.DeleteListItem(car, this.List);
        }
    }



The CarDatabase windows forms project is downloadable in the downloads section (Code_examples.zip).

Last edited Feb 9, 2012 at 6:15 PM by tore7506, version 16

Comments

tedvanderveen Feb 20, 2013 at 12:38 PM 
Me too. Any code samples on lookup field usage would be great! Thanks

TrevorGermain May 14, 2012 at 2:56 PM 
Having trouble getting this to work on a list with a lookup field.