SPGenericRepository

If you're going to make your own Repository classes, you most likely want to extend the SPGenericRepository class and add some methods for your specific purposes because the SPGenericRepository class already implements the basic actions you want to perform on your datasource:

SPRepositoryCustom.png

 public class SPGenericRepository<TT, TD> : IRepository<TT, TD> 
                            where TT : IContentType<TD>, new()
                            where TD : class, IContentTypeDto
    {
        private readonly SPList _list;

        public SPGenericRepository(SPList list)
        {
            _list = list;
        } 

        public SPList List
        {
            get { return _list; }
        }

        public IEnumerable<TD> GetAll()
        {
            var contentTypeId = new TT().GetContentTypeIdDefinition();
            var filteredItems = List.Items.Cast<SPListItem>().Where(item => 
                 ContentTypeUtilities.IsContentTypeDirectParentOf(item.ContentType, contentTypeId));
            return DtoUtilities.ConvertToDto<TT, TD>(filteredItems);
        }

        public TD Get(int id)
        {
            var item = List.Items.GetItemById(id);
            return new TT().Get(item);
        }

        public void Update(TD dto)
        {
            var item = List.Items.GetItemById(dto.Id);
            Update(item, dto);
        }

        private static void Update(SPListItem item, TD dto)
        {
            new TT().Update(item, dto);
            item.Update();
        }

        public void Create(TD dto)
        {
            var contentTypeId = new TT().GetContentTypeIdDefinition();
            var item = List.Items.Add();
            item["ContentTypeId"] = contentTypeId;
            item.SystemUpdate();
            Update(item, dto);
        }

        public void Delete(TD dto)
        {
            List.Items.DeleteItemById(dto.Id);
        }

        public void Delete(int id)
        {
            List.Items.DeleteItemById(id);
        }
    }


As you can see, the implementation is pretty basic and we're using generics to allow this to work for any IContentType and IContentTypeDto implementations.

There is a call to DtoUtilies.ConvertToDto to abstract the linq expression used to convert each SPListItem to its IContentTypeDto implementation (by calling the IContentType implementation .Get() method each time).

Now you can just inherit from the SPGenericRepository class to add helper methods for retrieving data.

Implementing your own Repository is pretty easy:

    public class PosDocumentsRepository : SPGenericRepository<MyDocumentContentType,
                                                                                              MyDocumentDto>
    {
        public PosDocumentsRepository(SPList list) : base(list)
        { }

        public List<IncomingDocumentDto> GetAllFinanceDocuments()
        {
            var spQuery = new SPQuery();
             // Construct Caml to query the SPListItemCollection for documents of type Finance (MM term)
            var caml = ""; 
            spQuery.Caml = caml;

            var filteredItems = List.GetItems(query);
            return DtoUtilities.ConvertToDto<IncomingDocumentContentType, IncomingDocumentDto>
                                              (filteredItems);
        }
    }


Here we have implemented a Repository for our list containing MyDocument contenttypes and we already have our MyDocumentContentType and MyDocumentContentTypeDto's.

We have added a helpful method for returning all documents that have a 'Type' managed metadata field set to the Term 'Finance'. And we return the filtered list.

Don't forget to also filter on ContentType before quering ;). This is already covered in the GetAll() SPGenericRepository method.

Last edited Nov 1, 2013 at 11:46 AM by cverhelst, version 4