+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

Sitefinity Streaming API: Changes to Existing API

by Dilyan Rusev
This is a part of the blog post series that explain the new streaming API for Sitefinity 3.7 SP3. You can view the TOC in the first blog post.

So far, I've explained the why we needed streaming API and its limitations, and then I covered quickly on the new classes and interfaces. Now, I'm going to talk about changes to the existing API.

Since in my previous blog post I started with the data layer, I will go on with it. As I said, streaming is available for all generic-content based modules - that is - Generic Content, Blogs, Events, Libraries (images and documents) and News. 

ContentProviderBase (in Telerik.Cms.Engine, Telerik.Cms.Engine.dll) has a few new members:
  • public virtual bool StreamingIsEnabled { get; set; }
    Indicates whether streaming capabilities are enabled.

    StreamingProvider will return null if this property is set to false.

    This will be typically be overriden in your own provider to load this value from the module's configuration. Overriding is necessary, because we use the same streaming provider with all content providers. So a streaming provider can access a module's configuration through this property. Overriding is done for the default content providers.
  • public virtual IStreamingContentProvider StreamingProvider { get; set; }
    Returns an instance of the default streaming provider.

    If you override this property, you should make sure that it will always return null if StreamingIsEnabled is false.

    If you need to use a specific provider, use AvailableStreamingProviders directly.
  • public virtual IDictionary<string, IStreamingContentProvider> AvailableStreamingProviders { get; }
    Collection of available streaming providers.

    This is, basically, a name/value collection of available providers. Again, you could override this on a content-provider basis to load settings for a specific module. The Nolics streaming provider is hard-coded as an available streaming provider in the default implementation of the generic content provider. It is used in other generic-content based providers, and therefore is available for all generic-content based modules. The Files streaming provider is available for the Libraries module only.
  • public virtual string DefaultStreamingProvider { get; }
    Default streaming provider name. 

    This is configurable on a per-module basis. Again, you should override this in your own provider to load the configuration.
    The name in this property will determine the provider returned by StreamingProvider .
  • public virtual long StreamingChunkSize { get; set; }
    When using the Nolics streaming provider, this will be the db chunk size

    This doesn't strictly apply only to the Nolics streaming provider, but to any provider that implements IChunkContentProvider. The property value is loaded from a module's configuration, and it's up to the streaming provider to use it.
Here probably arises the question: how do I make sure streaming is not used in my provider?
The answer is twofold:
  • If you inherit from ContentProviderBase directly, you needn't worry yourself. Default values are chosen so that streaming is disabled by default.
  • If you inherit from the default implementation of an existing provider (in one of the *.Data.dll assemblies), you will still be safe, as streaming is disabled by default. However, it can be enabled through configuration (explained later, perhaps in another blog post). If you want to make sure you don't use streaming, simply overload AvailableStreamingProviders and always return an empty collection. An application restart might be necessary. 
Although the default streaming provider names are "Nolics" (default and available for all content-based modules) and "Files" (for Libraries only), you shouldn't hard-code them. They are defined as constants as Telerik.Cms.Engine.ContentManager.NolicsStreamingProviderName and Telerik.Libraries.LibraryManager.FileStreamingProviderName, respectively.

As I mentioned the ContentManager-er, it, too, has new members. They are the same as those of ContentProviderBase and just call the provider's implementation.

LibraryManager (in Telerik.Libraries, Telerik.Libraries.dll) has a two overrides for uploading content as stream:
  • public IContent UploadFile(Stream data, string fileName, string fileExtension, string mimeType, ILibrary library, bool overwrite)
    Upload binary content via streaming and create a library item associated with the data.
    data is the stream to upload
    fileName is the file name to set as a meta field to the newly created IContent
    fileExtension is the file extension to set as a meta field to the newly created IContent
    mimeType is the mime type of data, and will be set to the newly created IContent
    library is the library in which the IContent should be uploaded to
    override indicates whether to delete a content with the same file name and extension in the same library

    This works the same as the older overloads that take a byte[] instead of a Stream. The new approach makes sure that uploading is and that at no time the content is loaded into memory.
  • public IContent UploadFile(Stream data, string fileName, string fileExtension, string mimeType, ILibrary library)
    Same as above, but assumes that override is true
And then, some parts of the API and public controls have changed, so that the new API is taken in consideration. While changes to internal implementation are rarely documented, I believe it will be helpful for the users that have heavily modified Sitefinity. Since uploading was discussed last, I will begin with it.

Uploading in Sitefinity usually takes place in two public controls, LibraryItemUpload and ImageEditorDialog (both in Telerik.Libraries.WebControls, Telerik.Libraries.dll). Therefore, their behaviour had to be changed.
The condition for uploading is that the default provider for libraries to return a non-null value for StreamingProvider. If it is null, file is uploaded as byte[].

Downloading in Sitefinity is managed by http handlers. For generic-content based modules, we have the ContentHttpHandler in Telerik.Cms.Engine, Telerik.Cms.Engine.dll. For an item to be downloaded via streaming, StreamHelper.IsStreamingCapable must return true for either respectSettings=true or false.

The last significant internal change is that Amazon and Viddler providers now inherit from the internal DefaultNonStreamingProvider, instead of just DefaultProvider.

I have mentioned several times so far about configuration. Every content module has its ConfigHelper though which its SectionHandler can be retrieved. For all generic-content based modules (Generic Content, Blogs, Events, Libraries, News), the SectionHandler-s contain these members:
  • public string StreamingProviderName { get; set;}
    Default streaming provider name for the current module.

    This is not a required element and by default it resolves to ContentManager.NolicsStreamingProviderName. In web.config, use "streamingProviderName" as an attribute to the module's configuration element.
  • public bool StreamingIsEnabled { get; set;}
    Indicates whether streaming capabilities are enabled.

    This is not a required element and by default it resolves to false. In web.config, use "streamingIsEnabled" as an attribute to the module's configuration element.
  • public long StreamingChunkSize { get; set;}
    When using the Nolics streaming provider, this will be the db chunk size

    This is not a required element and by default it resolves to 52428800. In web.config, use "streamingChunkSize" as an attribute to the module's configuration element. The minimum value you can set is 1, and the maximun - long.MaxValue.
With this blog post I have covered the changes to the existing API that we had to make in order to enable streaming. My next blog post will be more task-oriented and will show some examples of how the API could be used.

Leave a comment