• Lexical
Show / Hide Table of Contents
  • Lexical.FileSystem
    • Introduction
    • Abstractions
      • IFileSystem
        • IFileSystem
        • IFileSystemBrowse
        • IFileSystemCreateDirectory
        • IFileSystemDelete
        • IFileSystemFileAttribute
        • IFileSystemMount
        • IFileSystemMove
        • IFileSystemObserve
        • IFileSystemOpen
      • IEvent
      • IEntry
      • IOption
      • IToken
    • FileSystem
    • VirtualFileSystem
    • MemoryFileSystem
    • EmbeddedFileSystem
    • HttpFileSystem
    • Decoration
    • IFileProvider
    • Utility
      • DisposeList
      • FileScanner
      • VisitTree
      • File Operation
  • Lexical.FileProvider
    • Introduction
    • Package
    • Package.Abstractions
    • Root
    • Zip
    • Dll
    • SharpCompress
    • SharpZipLib
    • FileScanner
    • Utils
  • Lexical.Localization
    • Introduction
    • Tutorial
    • Asset
      • IAsset
      • IStringAsset
    • Line
      • ILine
      • ILineFactory
      • ILineRoot
      • ILineFormat
      • ILineLogger
      • LineComparer
    • File
      • ILineReader
      • ILineWriter
      • Ini
      • Json
      • Xml
      • Resx
      • Resources
    • Miscellaneous
      • Plurality
      • ICulturePolicy
      • IStringFormat
      • Dependency Injection
    • Practices
      • Class Library
      • Class Library DI
      • Class Library DI opt.
  • Lexical.Utilities
    • Introduction
    • UnicodeString
    • FileScanner
    • Permutation
    • Tuples
    • StructList

IAsset

Asset is a class that manages localization sources. Sources are typically files, embedded resources, and plain code.

// Language string source
Dictionary<string, string> src = new Dictionary<string, string> { { "en:hello", "Hello World!" } };
// Create Asset
IAsset asset = new StringAsset(src, LineParameterPrinter.Default);

IAsset is the root interface for assets. It serves as a signal that the implementing class has further asset features. There are more specific interfaces such as IStringAsset and IBinaryAsset which retrieve language strings and binary resources.

Asset interfaces are not called directly but used instead by calling extension methods of IAsset.

// Create key
ILine key = new LineRoot().Key("hello").Culture("en");
// Resolve string - Call to StringAssetExtensions.GetString()
IString str = asset.GetLine(key).GetString();

Asset Composition

AssetComposition is the default class. It unifies a group of assets into one asset, typically so that they can be assigned to ILineRoot.

// Create individual assets
IAsset asset_1 = new StringAsset(new Dictionary<string, string> { { "Culture:en:Key:hello", "Hello World!" } }, LineFormat.Parameters);
IAsset asset_2 = new ResourceStringDictionary(new Dictionary<string, byte[]> { { "Culture:en:Key:Hello.Icon", new byte[] { 1, 2, 3 } } }, LineFormat.Parameters);

// Create composition asset
IAssetComposition asset_composition = new AssetComposition(asset_1, asset_2);

// Assign the composition to root
ILineRoot root = new LineRoot(asset_composition, new CulturePolicy());
IAssetComposition is the interface for classes that composes IAsset components.
/// <summary>
/// Composition of <see cref="IAsset"/> components.
/// </summary>
public interface IAssetComposition : IAsset, IList<IAsset>
{
    /// <summary>
    /// Set to new content.
    /// </summary>
    /// <param name="newContent"></param>
    /// <exception cref="InvalidOperationException">If compostion is readonly</exception>
    void CopyFrom(IEnumerable<IAsset> newContent);

    /// <summary>
    /// Get component assets that implement T. 
    /// </summary>
    /// <param name="recursive">if true, visits children recursively</param>
    /// <typeparam name="T"></typeparam>
    /// <returns>enumerable or null</returns>
    IEnumerable<T> GetComponents<T>(bool recursive) where T : IAsset;
}

Asset Builder

AssetBuilder is a factory class that constructs new instances of IAsset. Asset builder is populated with IAssetSources which participate to the build process.

This example shows how to create asset builder, add asset sources, and then to build an asset.

// Create dictionary of strings
Dictionary<string, string> strings = new Dictionary<string, string> { { "en:hello", "Hello World!" } };

// Create IAssetSource that adds cache 
IAssetSource assetSource_0 = new AssetCacheSource(c => c.AddResourceCache().AddStringsCache().AddCulturesCache());
// Create IAssetSource that static reference of IAsset (string dictionary)
IAssetSource assetSource_1 = new AssetFactory(new StringAsset(strings, LineParameterPrinter.Default) );

// Create AssetBuilder
IAssetBuilder builder = new AssetBuilder(assetSource_0, assetSource_1);
// Instantiate IAsset
IAsset asset = builder.Build();

// Create string key
ILine key = new LineRoot().Key("hello").Culture("en");
// Request value
IString value = asset.GetLine( key ).GetString();
// Print result
Console.WriteLine(value);

There are extension methods for convenience.

// Create AssetBuilder
IAssetBuilder builder = new AssetBuilder();
// Add IAssetSource that adds cache 
builder.AddCache();
// Add IAssetSource that adds strings
builder.AddStrings(strings, LineParameterPrinter.Default);

Asset builders and asset sources are used with Dependency Injection. Asset sources are added to IServiceCollection to participate in constructing in new assets. Asset builder makes the new asset when requested by ServiceProvider. The calling assembly must have nuget dependency to Microsoft.Extensions.DependencyInjection.Abstractions.

// Initialize service collection
IServiceCollection serviceCollection = new ServiceCollection();

// Add IAssetBuilder, an instruction to construct one later
serviceCollection.AddSingleton<IAssetBuilder, AssetBuilder>();
// Add IAssetSource, that will construct cache cache
serviceCollection.AddSingleton<IAssetSource>(new AssetCacheSource(o => o.AddResourceCache().AddStringsCache().AddCulturesCache()));
// Add IAssetSource, that adds strings
Dictionary<string, string> strings = new Dictionary<string, string> { { "en:hello", "Hello World!" } };
serviceCollection.AddSingleton<IAssetSource>(new AssetFactory(new StringAsset(strings, LineParameterPrinter.Default)));

// Add delegate to forward IAsset request to IAssetBuilder
serviceCollection.AddSingleton<IAsset>(s => s.GetService<IAssetBuilder>().Build());

// Create service scope
using (ServiceProvider serviceScope = serviceCollection.BuildServiceProvider())
{
    // Construct new asset
    IAsset asset = serviceScope.GetService<IAsset>();

    // Create string key
    ILine key = new LineRoot().Key("hello").Culture("en");
    // Request string
    IString value = asset.GetLine(key).GetString();
    // Print result
    Console.WriteLine(value);
}

Extension method AddLexicalLocalization() adds IAsset, ILineRoot, ICultureProvider and IAssetBuilder services to IServiceCollection.

// Initialize service collection
IServiceCollection serviceCollection = new ServiceCollection();

// Add IAssetBuilder, ILineRoot and ICulturePolicy to service collection
serviceCollection.AddLexicalLocalization(
    addStringLocalizerService: false, 
    addCulturePolicyService: false, 
    useGlobalInstance: false,
    addCache: true);

// Add dictionary of strings
Dictionary<string, string> strings = new Dictionary<string, string> { { "en:hello", "Hello World!" } };
serviceCollection.AddSingleton<IAssetSource>(new AssetFactory(new StringAsset(strings, LineParameterPrinter.Default)));

// Create service scope
using (ServiceProvider serviceScope = serviceCollection.BuildServiceProvider())
{
    // Construct new asset
    IAsset asset = serviceScope.GetService<IAsset>();

    // Create string key
    ILine key = new LineRoot().Key("hello").Culture("en");
    // Request string
    IString value = asset.GetLine(key).GetString();
    // Print result
    Console.WriteLine(value);
}
IAssetBuilder is the interface for factory class(es) that instantiate IAssets.
/// <summary>
/// Builder that can create <see cref="IAsset"/> instance(s).
/// 
/// For dependency injection.
/// </summary>
public interface IAssetBuilder
{
    /// <summary>
    /// List of asset sources that can construct assets.
    /// </summary>
    IList<IAssetSource> Sources { get; }

    /// <summary>
    /// Build language strings.
    /// </summary>
    /// <returns></returns>
    IAsset Build();
}
IAssetSource is the interface for sources that contribute asset(s) to the built result.
/// <summary>
/// Source of assets. Adds resources to builder's list.
/// </summary>
public interface IAssetSource
{
    /// <summary>
    /// Source adds its <see cref="IAsset"/>s to list.
    /// </summary>
    /// <param name="list">list to add provider(s) to</param>
    /// <returns>self</returns>
    void Build(IList<IAsset> list);

    /// <summary>
    /// Allows source to do post build action and to decorate already built asset.
    /// 
    /// This allows a source to provide decoration such as cache.
    /// </summary>
    /// <param name="asset"></param>
    /// <returns>asset or component</returns>
    IAsset PostBuild(IAsset asset);
}

Asset Cache

AssetCache is used for caching the requests in cases where asset implementation needs better performance. Asset cache works as a decorator layer that forwards requests to its source and then stores the results.

Asset cache needs to be populated with IAssetCacheParts which each handle caching for a specific interface.

// Create asset
var source = new Dictionary<string, string> { { "Culture:en:Key:hello", "Hello World!" } };
IAsset asset = new StringAsset(source, LineFormat.Parameters);

// Create cache
IAssetCache asset_cached = new AssetCache(asset);
// Adds feature to cache IBinaryAsset specific requests
asset_cached.Add(new AssetCachePartResources(asset_cached.Source, asset_cached.Options));
// Adds feature to cache IStringAsset specific requests
asset_cached.Add(new AssetCachePartStrings(asset_cached.Source, asset_cached.Options));
// Adds feature to cache IAssetCultureEnumerable specific requests
asset_cached.Add(new AssetCachePartCultures(asset_cached.Source, asset_cached.Options));

// Assign the cached asset
LineRoot.Global.Asset = asset_cached;


There are extension methods for convenience.

// Create cache decorator
IAssetCache asset_cached = new AssetCache(asset).AddResourceCache().AddStringsCache().AddCulturesCache();


And then there is one extension method CreateCache() that wraps the asset into a cache and adds the default cache parts.

// Decorate with cache
IAssetCache asset_cached = asset.CreateCache();

IAssetCache is the interface for cache implementatations. It is a composition of cache parts.

/// <summary>
/// Asset cache is decorator that caches requests of source object.
/// 
/// The interface is used as signal for extension methods.
/// </summary>
public interface IAssetCache : IAssetComposition
{
    /// <summary>
    /// Source asset.
    /// </summary>
    IAsset Source { get; }

    /// <summary>
    /// Cache options.
    /// </summary>
    AssetCacheOptions Options { get; }
}

/// <summary>
/// Part that addresses a feature (an interface) to cache.
/// </summary>
public interface IAssetCachePart : IAsset
{
}

Caching options

AssetCacheOptions carries a key-value map of caching parameters.

// Create asset
var source = new Dictionary<string, string> { { "Culture:en:Key:hello", "Hello World!" } };
IAsset asset = new StringAsset(source, LineFormat.Parameters);

// Create cache
IAssetCache asset_cached = asset.CreateCache();

// Configure options
asset_cached.Options.SetCloneKeys(true);
asset_cached.Options.SetCacheStreams(true);
asset_cached.Options.SetMaxResourceCount(1024);
asset_cached.Options.SetMaxResourceSize(1024 * 1024);
asset_cached.Options.SetMaxResourceTotalSize(1024 * 1024 * 1024);

// Assign the asset with cache decoration
LineRoot.Global.Asset = asset_cached;


Table of Asset cache option's keys

Key Method Default Description
CloneKeys .SetCloneKeys(bool) true Should cache create clones of keys, or should it use the keys that come from requests in its cache structures.
CacheStreams .SetCacheStreams(bool) true Should IBinaryAsset#OpenStream requests be cached.
MaxResourceCount .SetMaxResourceCount(int) 2147483647 Maximum number of resources to cache.
MaxResourceSize .SetMaxResourceSize(int) 4096 Maximum size of a resource.
MaxResourceTotalSize .SetMaxResourceTotalSize(int) 1048576 Maximum total number of bytes to reserve for all cached resources.


Note

It is implementation specific whether option is supported or not. Some cache options may not be used.

Clearing Cache

IAsset.Reload() clears caches and reloads assets from their configured sources.

// Create asset
var source = new Dictionary<string, string> { { "Culture:en:Key:hello", "Hello World!" } };
IAsset asset = new StringAsset(source, LineFormat.Parameters);

// Cache it
asset = asset.CreateCache();

// Issue a request which will be cached.
ILine key = new LineRoot().Key("hello");
IString value = asset.GetLine( key.Culture("en") ).GetString();
Console.WriteLine(value);

// Clear cache
asset.Reload();

Links

  • IAssetComposition
  • AssetComposition
  • IAssetBuilder
  • IAssetSource
  • AssetBuilder
  • AssetSource Passes IAsset to to builder.
  • AssetCacheSource Adds cache to the built asset.
  • ResourceManagerStringLocalizerAsset Adapts location of .resources file to IAsset.
  • ResourceManagerStringLocalizerAssetSource Adapts location of .resources file to IAssetSource.
  • IAssetCache
  • AssetCache
Back to top Copyright © 2015-2020 Toni Kalajainen