Here you can find the transcript of Episode #145 of PiaSys TechBites.
Welcome back to PiaSys TechBites. Today, I’m really happy and proud to introduce you to the new PnP Core SDK library. The PnP Core SDK library is the library for SharePoint Online in Microsoft 365 developers, which supports the NET standard 2.0 and the NET 5.0. It is a cross-platform library, so you can use it in Windows, Linux and MacOS.
It has been built with Microsoft Graph in mind. In fact, the first choice of the library is always to use Microsoft Graph for you, or to fall-back on the SharePoint Online REST APIs, whenever we need to do something, which is not yet available in Microsoft Graph.
Ideally, as a developer, you can simply rely on the PnP Core SDK library, and under the cover, the PnP Core SDK library will make the right choice for you, whether using Microsoft Graph as the first choice or the SharePoint REST API, if it is really needed. From a targeting point of view, with the Core SDK, we target SharePoint Online and Microsoft Teams nowadays.
From an architectural point of view, the PnP Core SDK has been built with a modern architecture based on Dependency Injection, asynchronous code, Fluent APIs, and the availability of a LINQ, Language Integrated Query provider, built internally of the library to query the domain model of the library itself.
It is based on a community effort, so it is under the umbrella of the Microsoft 365 PnP community project and it is open source indeed. You can find on this slide, the URL of the detailed report where you can find both the source code and the documentation of the library. Last but not least, it is the successor of PnP Site Core. On a long term, it will also be the successor of the PnP Framework library.
Let me move to the DEMO environment. Let me show you how to start working and playing with the PnP Core SDK library. So, let’s start playing with the PnP Core SDK within a fresh new console application for NET Core, which I just created. First of all, I want to make the console application asynchronous, So I will convert the main method to an async method and the return value will be a Task instead of void.
Then, we can go to dependencies and we can manage the NuGet packages and here we can add the PnP Core SDK package. Actually, I am going to add the PnP.Core.Auth package because this one is the one that including as a dependency, the actual PnP Core SDK component, and this one provides all the authentication logic. In fact, from an architectural point of view, the authentication logic of the PnP Core SDK is based on an open interface, which has been implemented in these additional package if you want to use the one that we provide out of the box, but it is up to you to build your own out integration logic, if you like.
Let me install this package. It will take a while and I will get that PnP Core SDK, as well as the PnP Core SDK authentication library. Moreover, we need to add another package, which is the Microsoft.Extensions.Hosting one, because we want to use the Dependency Injection and the hosting model inside our console application. Let me install this one as well, accept, and here we are ready to develop our solution. I can start creating my host through a HostBuilder, so I can simply replace the console right line with the create of default builder method of the host type. In order to do that, I need some usings in my code.
Let me do that here. We can add that using Dependency Injection and then hosting them, through the fluent API of the Microsoft.Extensions.Hosting, we can easily configure, for example, the logging of our solution. Here I can say that I want to configure logging in the Event Source Logger and in the console, and I want to configure a set of services with the Dependency Injection. Inside this ConfigureServices method we can easily define the Dependency Injection services that we want to use from a PnP Core SDK point of view. For example, we can add to the collection of services, the PnP Core service, as well as the PnP Core Authentication service, which will provide respectively the basic infrastructure of PnP Core and the authentication extensions of PnP Core. We can also configure these services with some external configuration based on a JSON file.
We can add the configure method called providing the PnP Core options to these configure method reading from the JSON configuration file in a section called PnPCore. We can do the same for the authentication model. Here we can say, ConfigurePnPCoreAuthenticationOptions, and still reading the configuration from PnP Core, which means that in our application, we can add a new file, which will be a JSOM file. Let me search for JSON here, and we can add this one, the appsettings.json file to our sample solution. This will be file that we want to copy to the output in order to have it available in our solution. Just for the sake of simplicity, let me copy an already defined one and let me comment it out. While we have a PnPCore section, we have a bunch of settings which are optional, so not mandatory, but I want to show you what you can configure in PnP Core SDK.
You have options to configure the behavior while consuming SharePoint REST, options while consuming, Microsoft graph, how to behave in the context. As you can see, the default behavior is to have Graph as the first choice, to support the beta endpoint if it is needed, we can even force to use always the beta endpoint, if you like. Then we can define a section of credentials and this one is the one provided to the authentication component of PnP Core, and here I am configuring the credential manager authentication with the credential manager item called PiaSysDev-Paolo, which is the one I’m using in my tenant. I’m also providing a client ID, the tenant ID of an application that I already registered in my tenant. If you don’t want to use this one, you can even completely remove it and you can rely on an already pre-registered application that we registered with PnP PowerShell, if you use it, and that you can reuse right here.
I can also configure what the target sites are. Here I have a site which is this one and under my tenant which I will access with the credential manager authentication that I configure just here. Once I’ve done that, I can save my file and I can proceed defining my host. I can, for example, say that before closing this fluent syntax, I want to use the console lifetime, and I want to build my host. Once I’ve done that I can actually start the hosts so host.StartAsync and then I can create the scope in which I will use my host and the services provided in my host to use the PnP Core SDK. The idea of the PnP Core SDK is to work with a set of PnPContext objects. Using a PnPContextFactory service that we have, and I need to add using for this interface. We can use the PnPContextFactory to create a new PnPContext for a target site, team or the group.
It is an IDisposable object I can do using var context as like, as we are used to do, when we use CSOM and asynchronously, we can await for the PnPContextFactory object, and we can create asynchronously a new context for either the ID of a group in Microsoft 365, the name of a configuration, the URL of a site, so up to you. Here, I want to target my demo site, the one that I configured here in the collection of sitez in the settings file. Let’s do that and inside these using block, I can play with the PnPContext object that I’ve just got through the PnPContextFactory. How can we use it?
Well, we can do stuff like, for example, let’s declare a web variable and let’s use the context asynchronously to get the web object under the cover of the site in which I am. For which I have the PnPContext, I can get asynchronously the web object. For example, using some Lambda expressions, I can load some of the properties of my site, like the title, the collection of lists that I have in my site and again, just for the sake of completeness, I want to get the master page URL of my site. By invoking this method, which is an asynchronous one as you can see, we will simply trigger the request to download from either Microsoft Graph or the REST IPIs of SharePoint these properties of the current web object and here, because we are accessing the master URL, we are going through the REST APIs of SharePoint Online because the master URL is not available in Microsoft Graph, but you don’t need to think about that. You simply declare what you want to have and the PnP Core SDK will do the right request for you under the cover. We can show easily the output of the console, the information about our site. We can also do more. We can play for example, with the team, which is backing our modern team site that we are consuming through the demo site configuration. So context.team, instead of web GetAsync and we get a team object that you can use. Again, here we get it with the default properties because we don’t specify any specific property here. We can still show in the console window, as the output, a list of the properties of the currently retrieved team object.
As I said, we can also play with language integrated query. We can do stuff like, for example, making a LINQ query against the collection of lists in the web object. In order to do that, we need to add some additional usings. Specifically, let me go at the top of this file and we need to add the using for these namespaces of PnP Core SDK as well as for Language Integrated Query.
Once we have done that, that we can easily define a language integrated query here to get from the collection of lists, just the ID, the title, and the description of every released. We want to order all of the lists by title descending and we want to get the lists as the output. This will be just the LINQ query. We will not execute the actual request under the cover, but we will do the actual query when we will say, for example, ToList or ToArray targeting this IQueryable object. Here we can see the output in the console window again, and whenever we will resolve this query into an actual collection of items, we will re-execute the query onto the target environment. Now I have defined my sample solution. Let me build. It is building.
I can run the solution, let me show you how it behaves. Let me put some breakpoints here. For example, one here, one here, and one here, and let me start the application. It will be a console application, as I said, here is the console window. Now, we will be able to see in the debugger that we have access to the web object, to the team object and to the collection of lists ordered by title descending. Here we are, the application is running. It is consuming the settings that we defined and pretty soon we will see the breakpoint triggered. Here we are here, we have the request for the web object. Let me continue, here we have the web object retrieved, and we can see through the debugger that we have some properties which have been downloaded and some others, which are not available.
If I go to my console application, we can see the title and the number of lists and the master page URL. I can continue the execution and we can now see the properties of the team backing the website. You see that in the first scenario we made a REST request to the REST APIs of SharePoint. While in the second scenario, we used Microsoft Graph because in order to access Teams, so we need to use the Microsoft Graph APIs, and then we can make a LINQ query.
Let me put a breakpoint here as well. Let me continue again. You can see, we have done another request, which will be the request to retrieve all of the lists and the items of the collection of lists. Here we can see the list ordered descending by title of all of the lists that I have in my target site. Simple as that, you use Dependency Injection, you create the PnPContextFactory, you create a context and you use it. Of course you are not always forced to use the Dependency Injection, but it is the modern approach that we suggest you to use together with the asynchronous programming model.
Like always, thank you for watching this video. I hope you found it interesting and I am really looking forward to seeing you next week, and remember to subscribe to this channel. Thank you.