Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage client context object in seperate class library?

I am trying to create a library(class library) for sharepoint which will have all sharepoint dll to interact with sharepoint server to upload files,documents and create document library and document set.

Now this library could be consumed by clients like web application(asp.net webform or mvc) or console application or web api/wcf services or windows form anything.

So here I am bit confused with creating repository patterna and unit of work layer in order to manage client context object.

I am not sure whether to allow creation of client context for each operation or whether to create client context once and reuse or whether to create clientcontext each time.

I have search alot but was unable to find any reference or article to create repository layer like the way it is created in case of Entity framework DbContext.

I am using Client-Side Object Model(CSOM library) and my library is all about content management system to manage files and meta data.

I will appreciate any help :)

Update : Sample code to upload file on sharepoint domain

ClientContext context = new ClientContext("http://SiteUrl"); // Starting with ClientContext, the constructor requires a URL to the server running SharePoint. 
context.Credentials = new SharePointOnlineCredentials(username, password);

// The SharePoint web at the URL.
Web myWeb = context.Web;

List myLibrary = myWeb.Lists.GetByTitle("MyProject"); //This is called document library so in sharepoint document Library is the root where we can create
                                                       //Document Set(Advance version of folder) or folder(Simple Folder) or upload files directly inside document library

FileCreationInformation info = new FileCreationInformation();
info.Url = "Sample.txt";
info.Overwrite = true;
info.Content = System.IO.File.ReadAllBytes("C://sample.txt"); //This will be user uploaded file that will be dynamic
myLibrary.RootFolder.Files.Add(info);
context.ExecuteQuery(); // Execute the query to the server.This is like EF SaveChanges method

Some References : https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff649690(v=pandp.10)

https://docs.microsoft.com/en-us/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-client-library-code

https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ee538685%28v%3doffice.14%29

https://sharepoint.stackexchange.com/questions/96180/sharepoint-2013-csom-is-it-better-to-pass-a-context-object-around-or-a-url

like image 693
ILoveStackoverflow Avatar asked Dec 22 '18 07:12

ILoveStackoverflow


People also ask

What is the use of CSOM in SharePoint?

You can use the SharePoint client object model (CSOM) to retrieve, update, and manage data in SharePoint. SharePoint makes the CSOM available in several forms: . NET Framework redistributable assemblies.

What is client side object model?

The client object model for SharePoint is a set of client-based libraries that represent the server object model. They are packaged in three different DLLs to accommodate a variety of development types. The client object model includes most of the major functions of the server API.

What is the SharePoint object model?

Server Object Model can be used if you are developing a client application such as console or Windows forms or a WPF app that will run on a SharePoint server. You cannot use the Server Object Model to connect remotely to a SharePoint Server. When you want to use the Server Object Model, you refer to the Microsoft.


1 Answers

Regarding your first question:

I am not sure whether to allow creation of client context for each operation or whether to create client context once and reuse or whether to create clientcontext each time.

Why not letting the developers using your library choose? i.e., you provide the context and they can initialize it and keep it in the scope they need.

For example, if you library is used in a Website, they may want to initialize it on each request but if your library is used in a desktop application, they may want to only initialize it once per window.

Regarding your second issue:

I have search a lot but was unable to find any reference or article to create repository layer like the way it is created in case of Entity framework DbContext.

The repository and unit of work patterns are just abstraction layers that you can apply to any context. A repository will implement a set of related operations for a given object or entity whereas a unit of work will implement a set of related operations for one or more entities within a given context (a database transaction, etc...).

IMHO a repository does not make much sense for what you are trying to do, you could however implement a unit of work wrapping a ClientContext instance.

First, start with an interface, defining the methods that you will expose, for example:

public interface IContentManagerUnitOfWork
{
    IEnumerable<List> GetLists();
    List CreateList(ListCreationInformation listCreationInformation);
    List GetListByTitle(string title);
    [...]
}

Then you implement it, here is an idea:

public class ContentManagerUnitOfWork : IContentManagerUnitOfWork, IDisposable
{
    private ClientContext clientContext;
    private Web web;

    public ContentManagerUnitOfWork(string url, username, password)
    {
        clientContext = new ClientContext(url);
        clientContext .Credentials = new SharePointOnlineCredentials(username, password);

        web = context.Web;
    }

    public IEnumerable<List> GetLists()
    {
        clientContext.Load(web.Lists);
        clientContext.ExecuteQuery(); 
        return web.Lists;
    }

    List CreateList(ListCreationInformation listCreationInformation)
    {
        List list = web.Lists.Add(listCreationInformation); 
        list.Update(); 
        clientContext.ExecuteQuery(); 
        return list;
    }

    List GetListByTitle(string title)
    {
        return web.Lists.GetByTitle("Announcements"); 
    }

    public void Dispose()
    {
        clientContext.Dispose();
    }
}

Then, any developer consuming your library can simply use the unit of work with the methods you provide:

using (var unitOfWork = new ContentManagerUnitOfWork("http://SiteUrl", username, password))
{
     var lists = unitOfWork.GetLists();
}

Of course, this is just a vary basic example, you should adapt it to your needs and make sure it is the right way to interact with Sharepoint. I hope it will get you going, though.

like image 82
Isma Avatar answered Oct 11 '22 21:10

Isma