Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork1
Metadata model for parsing, processing and reporting data
License
micro-elements/MicroElements.Metadata
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Provides metadata model, parsing and reporting.
dotnet add package MicroElements.Metadata
Windows: Runbuild.ps1
Linux: Runbuild.sh
This project is licensed under the MIT license. See theLICENSE file for more info.
Represents property for describing metadata model.There are two main interfaces: untypedIProperty
and genericIProperty<T>
.
IProperty
providesName
andType
and optionalDescription
andAlias
.
IProperty<T>
extendsIProperty
withDefaultValue
,Calculator
andExamples
Source:IProperty.cs
Represents property and its value.
Has untyped form:IPropertyValue
and strong typed:IPropertyValue<T>
.
Source:IPropertyValue.cs
PropertyContainer represents collection that contains properties and values for these properties.IPropertyContainer
is an immutable collection ofIPropertyValue
IPropertyContainer
providesProperties
,ParentSource
andSearchOptions
IMutablePropertyContainer
extendsIPropertyContainer
with Add* and Set* methods.
publicclassPropertyContainerUsage{publicclassEntityMeta{publicstaticreadonlyIProperty<DateTime>CreatedAt=newProperty<DateTime>("CreatedAt");publicstaticreadonlyIProperty<string>Description=newProperty<string>("Description");}[Fact]publicvoidsimple_set_and_get_value(){IPropertyContainerpropertyContainer=newMutablePropertyContainer().WithValue(EntityMeta.CreatedAt,DateTime.Today).WithValue(EntityMeta.Description,"description");propertyContainer.GetValue(EntityMeta.CreatedAt).Should().Be(DateTime.Today);propertyContainer.GetValue(EntityMeta.Description).Should().Be("description");}[Fact]publicvoidget_property_value(){IPropertyContainerpropertyContainer=newMutablePropertyContainer().WithValue(EntityMeta.CreatedAt,DateTime.Today).WithValue(EntityMeta.Description,"description");IPropertyValue<string>?propertyValue=propertyContainer.GetPropertyValue(EntityMeta.Description);propertyValue.Should().NotBeNull();propertyValue.Property.Should().BeSameAs(EntityMeta.Description);propertyValue.Value.Should().Be("description");propertyValue.Source.Should().Be(ValueSource.Defined);}}
IMetadataProvider
represents object that has metadata where Metadata isIPropertyContainer
.
MetadataProvider allows to extend any object with additional properties.IMetadataProvider
default implementation usesMetadataGlobalCache.GetInstanceMetadata
that createsMutablePropertyContainer
. If you want mutable metadata - implement Metadata with IMutablePropertyContainer.
Metadata default search mode: ByTypeAndName
/// <summary>/// Gets metadata of required type./// </summary>/// <typeparam name="TMetadata">Metadata type.</typeparam>/// <param name="metadataProvider">Metadata provider.</param>/// <param name="metadataName">Optional metadata name.</param>/// <param name="defaultValue">Default value to return if not metadata found.</param>/// <returns>Metadata or default value if not found.</returns>[return:MaybeNull]publicstaticTMetadataGetMetadata<TMetadata>(thisIMetadataProvidermetadataProvider,string?metadataName=null,[AllowNull]TMetadatadefaultValue=default)/// <summary>/// Sets metadata for target object and returns the same metadataProvider for chaining./// </summary>/// <typeparam name="TMetadataProvider">Metadata provider type.</typeparam>/// <typeparam name="TMetadata">Metadata type.</typeparam>/// <param name="metadataProvider">Target metadata provider.</param>/// <param name="metadataName">Metadata name.</param>/// <param name="data">Metadata to set.</param>/// <returns>The same metadataProvider.</returns>publicstaticTMetadataProviderSetMetadata<TMetadataProvider,TMetadata>(thisTMetadataProvidermetadataProvider,string?metadataName,TMetadatadata)whereTMetadataProvider:IMetadataProvider/// <summary>/// Configures metadata with action. Can be called many times./// If metadata is not exists then it creates with default constructor./// </summary>/// <typeparam name="TMetadataProvider">Metadata provider type.</typeparam>/// <typeparam name="TMetadata">Metadata type.</typeparam>/// <param name="metadataProvider">Target metadata provider.</param>/// <param name="configureMetadata">Configure action.</param>/// <param name="metadataName">Optional metadata name.</param>/// <returns>The same metadataProvider.</returns>publicstaticTMetadataProviderConfigureMetadata<TMetadataProvider,TMetadata>(thisTMetadataProvidermetadataProvider,Action<TMetadata>configureMetadata,string?metadataName=null)whereTMetadataProvider:IMetadataProviderwhereTMetadata:new()
other methods can be found inMetadataProviderExtensions
Searching is one of the important concept of working with metadata. Most search methods acceptsSearchOptions
Property | DefaultValue | Description |
---|---|---|
PropertyComparer | ByTypeAndNameEqualityComparer | Equality comparer for comparing properties. |
SearchInParent | true | Do search in parent if no PropertyValue was found. |
CalculateValue | true | Calculate value if value was not found. |
UseDefaultValue | true | Use default value from property is property value was not found. |
ReturnNotDefined | true | Return fake PropertyValue with and Value set to default if no PropertyValue was found. Returns null if ReturnNotDefined is false. |
- Main search methods provided by
ISearchAlgorithm
- Main search algorithm can be get or set in
Search.Algorithm
- All search methods from
SearchExtensions
useSearch.Algorithm
SearchOptions
can be composed bySearch
class
/// <summary>/// Represents search algorithm./// </summary>publicinterfaceISearchAlgorithm{/// <summary>/// Searches <see cref="IPropertyValue{T}"/> by <see cref="IProperty{T}"/> and <see cref="SearchOptions"/>./// </summary>/// <param name="propertyContainer">Property container.</param>/// <param name="property">Property to search.</param>/// <param name="searchOptions">Search options.</param>/// <returns><see cref="IPropertyValue"/> or null.</returns>IPropertyValue?SearchPropertyValueUntyped(IPropertyContainerpropertyContainer,IPropertyproperty,SearchOptions?searchOptions=default);/// <summary>/// Gets <see cref="IPropertyValue{T}"/> by <see cref="IProperty{T}"/> and <see cref="SearchOptions"/>./// </summary>/// <typeparam name="T">Property type.</typeparam>/// <param name="propertyContainer">Property container.</param>/// <param name="property">Property to search.</param>/// <param name="searchOptions">Search options.</param>/// <returns><see cref="IPropertyValue"/> or null.</returns>IPropertyValue<T>?GetPropertyValue<T>(IPropertyContainerpropertyContainer,IProperty<T>property,SearchOptions?searchOptions=null);}
Method | Description |
---|---|
GetPropertyValue | Gets or calculates typed property and value for property using search conditions. It's a full search that uses all search options:SearchOptions.SearchInParent ,SearchOptions.CalculateValue ,SearchOptions.UseDefaultValue ,SearchOptions.ReturnNotDefined . |
SearchPropertyValueUntyped | Searches property and value for untyped property using search conditions. Search does not useSearchOptions.UseDefaultValue andSearchOptions.CalculateValue . Search uses onlySearchOptions.SearchInParent andSearchOptions.ReturnNotDefined . |
GetPropertyValueUntyped | Gets property and value for untyped property using search conditions. Uses simple untyped searchSearchPropertyValueUntyped if CanUseSimpleUntypedSearch orproperty has typeSearch.UntypedSearch . Uses fullGetPropertyValue{T} based on property.Type in other cases. |
GetValue | Gets or calculates value for property. |
GetValueAsOption | Gets or calculates optional not null value. |
GetValueUntyped | Gets or calculates untyped value for property. |
GetValueByName | Gets or calculates value by name. |
Source:EntityParseValidateReport.cs
usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingDocumentFormat.OpenXml.Packaging;usingFluentAssertions;usingMicroElements.Functional;usingMicroElements.Parsing;usingMicroElements.Reporting.Excel;usingMicroElements.Validation;usingMicroElements.Validation.Rules;usingXunit;namespaceMicroElements.Metadata.Tests.examples{publicclassEntityParseValidateReport{publicclassEntity{publicDateTimeCreatedAt{get;}publicstringName{get;}publicEntity(DateTimecreatedAt,stringname){CreatedAt=createdAt;Name=name;}}publicclassEntityMeta:IPropertySet,IPropertyContainerMapper<Entity>{publicstaticreadonlyEntityMetaInstance=newEntityMeta();publicstaticreadonlyIProperty<DateTime>CreatedAt=newProperty<DateTime>("CreatedAt");publicstaticreadonlyIProperty<string>Name=newProperty<string>("Name");/// <inheritdoc />publicIEnumerable<IProperty>GetProperties(){yieldreturnCreatedAt;yieldreturnName;}/// <inheritdoc />publicIPropertyContainerToContainer(Entitymodel){returnnewMutablePropertyContainer().WithValue(CreatedAt,model.CreatedAt).WithValue(Name,model.Name);}/// <inheritdoc />publicEntityToModel(IPropertyContainercontainer){returnnewEntity(createdAt:container.GetValue(CreatedAt),name:container.GetValue(Name));}}publicclassEntityParser:ParserProvider{protectedOption<DateTime>ParseDate(stringvalue)=>Prelude.ParseDateTime(value);/// <inheritdoc />publicEntityParser(){Source("CreatedAt",ParseDate).Target(EntityMeta.CreatedAt);Source("Name").Target(EntityMeta.Name);}}publicclassEntityValidator:IValidator{/// <inheritdoc />publicIEnumerable<IValidationRule>GetRules(){yieldreturnEntityMeta.CreatedAt.NotDefault();yieldreturnEntityMeta.Name.Required();}}publicclassEntityReport:ReportProvider{publicEntityReport(stringreportName="Entities"):base(reportName){Add(EntityMeta.CreatedAt);Add(EntityMeta.Name);}}publicStreamReportToExcel(Entity[]entities){varreportRows=entities.Select(entity=>EntityMeta.Instance.ToContainer(entity));varexcelStream=newMemoryStream();ExcelReportBuilder.Create(excelStream).AddReportSheet(newEntityReport("Entities"),reportRows).SaveAndClose();returnexcelStream;}publicEntity[]ParseExcel(Streamstream){vardocument=SpreadsheetDocument.Open(stream,false);varmessages=newList<Message>();varentities=document.GetSheet("Entities").GetRowsAs(newEntityParser(), list=>newPropertyContainer(list)).ValidateAndFilter(newEntityValidator(), result=>messages.AddRange(result.ValidationMessages)).Select(container=>EntityMeta.Instance.ToModel(container)).ToArray();returnentities;}[Fact]publicvoidUseCase(){// Trim DateTime to milliseconds because default DateTime render trimmed to millisecondsDateTimeNowTrimmed(){DateTimenow=DateTime.Now;returnnow.AddTicks(-(now.Ticks%TimeSpan.TicksPerMillisecond));}Entity[]entities={newEntity(NowTrimmed(),"Name1"),newEntity(NowTrimmed(),"Name2"),newEntity(NowTrimmed(),"Name3"),};StreamexcelStream=ReportToExcel(entities);Entity[]fromExcel=ParseExcel(excelStream);fromExcel.Should().HaveCount(3);fromExcel.Should().BeEquivalentTo(entities);}}}
- IPropertySet
- IPropertyContainerMapper
IPropertyContainer
can be casted todynamic
object withAsDynamic
extension.
[Fact]publicvoidDynamicContainer(){varpropertyContainer=newMutablePropertyContainer();propertyContainer.SetValue("PropertyA","ValueA");propertyContainer.SetValue(newProperty<int>("PropertyB"),42);dynamicdynamicContainer=propertyContainer.AsDynamic();objectvalueA=dynamicContainer.PropertyA;valueA.Should().Be("ValueA");objectvalueB=dynamicContainer.PropertyB;valueB.Should().Be(42);objectnotFoundProperty=dynamicContainer.NotFoundProperty;notFoundProperty.Should().BeNull();}
See:EntityParseValidateReport example
See:EntityParseValidateReport example
See:EntityParseValidateReport example
- ReportProvider
- Renderer
- IPropertyParser
About
Metadata model for parsing, processing and reporting data
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.