How to manage client context object in seperate class library?

守給你的承諾、 提交于 2019-12-08 16:44:00

问题


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


回答1:


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.




回答2:


I think you need to create a Authentication service in WCF service like below which will take care of all user who are logged in When ever any new request come in you to get details of that user if is genuine user or not then perform accordingly

    [ServiceContract]
    public interface IAuthenticationService
    {
       [OperationContract]
       ClientInfo ChangeSessionUser(User user);
       [OperationContract]
       ClientInfo GetSessionUserInfo();
       [FaultContract(typeof(ServiceFault))]
       [OperationContract]
       ClientInfo Login(LoginCredentials credentials);
       [OperationContract]
       void Logout(string id);
       [FaultContract(typeof(ServiceFault))]
       [OperationContract]
       void RemoveInvalidUserLogins();
       [OperationContract]
       void RemoveSesseionFromCache(string id);
       [FaultContract(typeof(ServiceFault))]
       [OperationContract]
       bool ValidateUser(LoginCredentials credentials);
    }


来源:https://stackoverflow.com/questions/53893774/how-to-manage-client-context-object-in-seperate-class-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!