遵守SharePoint列表的存储库模式

时间:2016-06-25 16:59:02

标签: c# sharepoint sharepoint-2013 repository-pattern

我正在使用Repository Pattern for SharePoint列表创建一个类(而不是直接访问数据库中的实际表),列表项集合。我见过的Repository Pattern设计不断为每个单独的存储库创建一个新的上下文,但我想为每个可能存在的并发存储库(每个列表一个)使用相同的ClientContext对象。假设我不希望有人自己创建一个新的ClientContext实例,它将作为构造函数传递给SPRepository类,我还有什么其他选项可以保存在静态内存中?

参考文献:

https://msdn.microsoft.com/en-us/library/ff649690.aspx https://hendrikbulens.wordpress.com/2014/12/14/repository-pattern-sharepoint/(这个为每个列表使用单独的存储库,而我想创建一个更通用的存储库,在构造函数中接受列表名称)

1 个答案:

答案 0 :(得分:0)

这是比看起来更复杂的主题,因为有很多事情需要考虑。我见过的大多数解决方案(包括您的链接)都试图通过性能和资源消耗来实现代码通用性。没有一个通用的解决方案。

单一责任

您应该将ClientContext注入您的存储库,因为CSOM有许多不同的身份验证方案(NTLM,FBA,ADFS,具有用户身份的高信任应用程序,具有应用程序标识的高信任应用程序,仅举几例)。存储库不应该知道身份验证方法和创建上下文的方法。

资源

当您想要避免创建不必要的对象时,在简单的场景中共享多个存储库之间的ClientContext个实例可能是个好主意。它实现了IDisposable,我们应该假设有这样的理由。

ExecuteQuery()来电数

如果对多个存储库使用一个ClientContext实例,则可以安排多个操作,并通过一个SharePoint请求执行所有操作。

var result1 = repository1.ScheduleLoad();
var result2 = repository2.ScheduleLoad();
context.ExecuteQuery();

请记住,CSOM是远程API。调用的数量和检索的数据量将对性能产生重大影响。

从其他对象或线程

调用ExecuteQuery()

考虑一下:

var web = StaticClass.Context.Web;
var list = web.GetList('Lists/example');
var item = list.GetItemById(1);

item["Title"] = "Test";

var result = repository.GetItemsAndExecute();
//or some other thread calls StaticClass.Context.ExecuteQuery();

item.Update();
StaticClass.Context.ExecuteQuery();

结果会是什么? Title字段的值将保持为空。这就是原因:

  • 第一次调用按ID获取项目并设置字段值,但不会调用Update()
  • 第二次通话再次通过ID 获取该项目并调用Update(),但不会设置字段值。