.. | ||
ByteArrayBinaryContent.cs | ||
EntityBinaryContentExtensions.cs | ||
EntityContentExtensions.cs | ||
EntityTextContentExtensions.cs | ||
FileBinaryContent.cs | ||
FileTextContent.cs | ||
IBinaryContent.cs | ||
IBinaryContentConvertable.cs | ||
IContent.cs | ||
ITextContent.cs | ||
ITextContentConvertable.cs | ||
README.md | ||
StringTextContent.cs | ||
TextContentExtensions.cs |
Contents
The contents of a file may be stored as a component, however this increases the
memory pressure when Nitride works with hundreds or thousands of files. To
reduce this, memory is loaded on demand through an abstracted components such
as IBinaryContent
and ITextContent
.
Exclusivity
The content interfaces are treated as mutually exclusive with each other by
extending the IContent
interface. The intended reason for this is to have a
single source of data that doesn't go out of sync. Adding or setting
a IBinaryContent
will remove the other content components in the entity, even
ones that are defined in other classes. In effect, all IContent
will be removed to ensure that. This is implemented via a number of extension
operations.
Entity entity;
IBinaryContent binaryContent;
ITextContent textContent;
entity.Add(binaryContent);
Assert.Equal(1, entity.Count);
Assert.True(entity.Has<IBinaryContent>());
Assert.True(entity.HasBinaryContent());
Assert.True(entity.HasContent());
entity.SetContent(textContent);
Assert.Equal(1, entity.Count);
Assert.False(entity.Has<IBinaryContent>());
Assert.False(entity.HasBinaryContent());
Assert.True(entity.Has<ITextContent>());
Assert.True(entity.HasTextContent());
Assert.True(entity.HasContent());
entity.RemoveContent();
Assert.Equal(0, entity.Count);
Assert.False(entity.Has<IBinaryContent>());
Assert.False(entity.HasBinaryContent());
Assert.False(entity.Has<ITextContent>());
Assert.False(entity.HasTextContent());
Assert.False(entity.HasContent());
This exclusivity can be ignored by using direct Add<>
, Set<>
, and
Remove<>
methods on the entity. That would allow multiple content to be added
and removed at the same time.
Entity entity;
IBinaryContent binaryContent = entity.Get<IBinaryContent>();
using Stream binaryStream = binaryContent.GetStream();
using StreamReader binaryReader = new StreamReader(binaryStream);
var text = binaryReader.ReadToEnd();
var textContent = new StringTextContent(text);
var switchedEntity = entity
.Set<ITextContent>(textContent)
.Remove<IBinaryContent>();
Assert.Equal(1, switchedEntity.Count);
Assert.True(switchedEntity.Has<ITextContent>());
Assert.False(switchedEntity.Has<ITextContent>());
var mergedEntity = entity
.Set<ITextContent>(textContent);
Assert.Equal(2, switchedEntity.Count);
Assert.True(switchedEntity.Has<ITextContent>());
Assert.True(switchedEntity.Has<ITextContent>());
Implementing this with a parent interface (IContent
) allows future content
providers, such as IXmlContent
or other future content sources.
IBinaryComponent
Most files start as only having access to binary content.
Entity entity;
IBinaryContent content = entity.Get<IBinaryContent>();
using Stream stream = content.GetStream();
There is no guarantee that the data behind the stream is loaded into memory or even available on disk. Instead, the stream is good until it goes out of scope.
IBinaryContentConvertable
There is an additional interface that allows a content to be converted into
an IBinaryContent).
FileTextContent textContent;
IBinaryContent binaryContent = textContent.ToBinaryContent();
Extension Methods
There are some convenience methods for working with entity components and content since they are frequently used.
IBinaryContent content = entity.GetBinaryContent();
bool has = entity.HasBinaryContent();
// Internally, this uses `SetContent` above with some additonal type safety.
entity = entity.SetBinaryContent(content);
ByteArrayBinaryComponent
The ByteArrayBinaryComponent
is a component that contains the entire binary
data in memory and returns it via System.IO.MemoryStream
objects.
byte[] bytes;
var content = new ByteArrayBinaryComponent(bytes);
FileBinaryContent
The TextBinaryContent
takes a path or FileInfo object as the parameter and
will produce a stream directly from the file without loading the file into
memory.
FileInfo file;
new FileBinaryContent(@"C:\Temp\Bob.txt");
new FileBinaryContent(file);
ITextContent
Text content allows for retrieving the contents via TextReader
instead of a
stream.
ITextContent content;
using TextReader reader = content.GetReader();
ITextContentConvertable
There is an additional interface that allows a content to be converted into
an ITextContent).
FileBinaryContent binaryContent;
ITextContent textContent = binaryContent.ToTextContent();
Extension Methods
Like the binary, there are some convenience methods for working with entity components.
ITextContent content = entity.GetTextContent();
bool has = entity.HasTextContent();
entity = entity.SetTextContent(content);
StringTextContent
A simple, in-memory string text content takes a string as the parameter.
string input;
ITextContent content = new StringTextContent(input);
FileTextContent
The TextFileContent
takes a path or FileInfo object as the parameter and will
produce a reader directly from the file without loading the file into memory.
FileInfo file;
new FileTextContent(@"C:\Temp\Bob.txt");
new FileTextContent(file);