This answer only has one tiny section (IDisposable
) that I feel is an appropriate kind of answer for Code Review. The rest is more suitable as a StackOverflow answer (since it dives into the specifics of the DocumentClient
class). I apologize in advance, and if I should move my answer or edit it in anyway, please feel free to advise me in the comments section.
The DocumentClient
class is already thread-safe.
From what I can gather reading the latest documentation on the DocumentClient
class, is that it is already inherently thread-safe. Provided that this remains true, your class wrapper is obsolete.
It seems that this confusion was also asked as a question over at StackOverflow
Microsoft's recommendation of using DocumentClient
as a singleton
If you can draw a parallel to how Microsoft recommends usage of the HttpClient
then you might have a better idea of what I mean from this point onwards.
Microsoft recommends that you use a single instance* per application. (again, think of HttpClient
)
In the case of a web application using ASP.NET this usually comes in the form of dependency injection via declaring the lifetime of the class to Singleton
.
// dependency injection for ASP.NET
services.AddSingleton(myDocumentClientInstance);
This might be the root cause of your misunderstanding. The use of the word "singleton" from the article you probably read, is actually an ASP.NET convention for specifying a lifetime of the instance and also ensuring that only a single (shared) instance is used across your entire web application.
This doesn't mean that implementing the DocumentClient
as a singleton class is wrong.
In such a case, a static instance (like you have done) could be the answer. But you're going to get a group of developers that will throw fists in the air at you for making the code difficult-to-impossible to unit test if you do so... You have been warned!
The DocumentClient
class implements IDisposable
.
Based on your code it will become quite a complex task of making sure that the instance is properly disposed.
The recommended way to handle an object that implements the IDisposable
interface is by using the the using
block.
using (IDocumentClient client = new DocumentClient(new Uri("endpoint"), "authKey"))
{
...
}
Special cases
To summarize with a special case, which could hopefully shine some additional light why your implementation will be troublesome as a true singleton.
There are some special cases for using more than one instance. In particular, if you have multiple CosmosDb accounts, then you should actually use one instance for each account. You can read about that here.
Note: The parallel to HttpClient
does not work here, since we are creating multiple instances on purpose.
Your particular implementation will fall short when you have a scenario with multiple CosmosDb accounts. So please keep that in mind.