Skip to content

Commit

Permalink
- refactor 1
Browse files Browse the repository at this point in the history
  • Loading branch information
NinjaRocks committed Nov 2, 2023
1 parent a228d4f commit 21ca6f5
Show file tree
Hide file tree
Showing 69 changed files with 600 additions and 242 deletions.
111 changes: 110 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,113 @@
[![NuGet version](https://badge.fury.io/nu/Schemio.Object.svg)](https://badge.fury.io/nu/Schemio.Object) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/NinjaRocks/Schemio.Object/blob/master/License.md) [![CI](https://github.com/NinjaRocks/Data2Xml/actions/workflows/CI.yml/badge.svg)](https://github.com/NinjaRocks/Data2Xml/actions/workflows/CI.yml) [![GitHub Release](https://img.shields.io/github/v/release/ninjarocks/Data2Xml?logo=github&sort=semver)](https://github.com/ninjarocks/Data2Xml/releases/latest)
[![CodeQL](https://github.com/NinjaRocks/Schemio.Object/actions/workflows/CodeQL.yml/badge.svg)](https://github.com/NinjaRocks/Schemio.Object/actions/workflows/CodeQL.yml) [![.Net Stardard](https://img.shields.io/badge/.Net%20Standard-2.1-blue)](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)
--
### .Net Standard 2.1 Library to map data to Entity using Schema Paths (Like XPath or JsonPath).
Schemio - is a .Net 6 utility to hydrate entities with data conditionally by given list of schema paths mapping to object graph. Support JsonPath and Xpath schema mappings.

## How to use Schemio?
> Step 1 - To mark the entity to hydrate data using schemio, derive the entity from `IEntity` interface. Bear in mind this is the root entity.
```
public class Customer : IEntity
{
public int CustomerId { get; set; }
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
public Communication Communication { get; set; }
public Order[] Orders { get; set; }
}
```
Above, Customer is the entity we want to hydrate with data conditionaly passing in schema paths mapping to object graph.

> Step 2 - Define schema configuration to map query/transformer pairs to schema paths mapping to the object graph.
Derive schema from `IEntitySchema<T>` where T is entity to hydrate. The query/transformer mappings can be nested to 5 levels down. You could map multiple schema paths to a given query/transformer pair.

```
internal class CustomerSchema : IEntitySchema<Customer>
{
private IEnumerable<Mapping<Customer, IQueryResult>> mappings;
private decimal version;
public IEnumerable<Mapping<Customer, IQueryResult>> Mappings => mappings;
public decimal Version => version;
public CustomerSchema()
{
version = 1;
// Create an object mapping graph of query and transformer pairs using xpaths.
mappings = CreateSchema.For<Customer>()
.Map<CustomerQuery, CustomerTransform>(For.Paths("customer/id", "customer/customercode", "customer/customername"),
customer => customer.Dependents
.Map<CustomerCommunicationQuery, CustomerCommunicationTransform>(For.Paths("customer/communication"))
.Map<CustomerOrdersQuery, CustomerOrdersTransform>(For.Paths("customer/orders"),
customerOrders => customerOrders.Dependents
.Map<CustomerOrderItemsQuery, CustomerOrderItemsTransform>(For.Paths("customer/orders/order/items")))
).Complete();
}
}
```

#### Query Class
The purpose of a query class is to execute to fetch data when mapped schema path is included in the context paramer of data provider.
- To define a query for a schema path, you need to implement the query by deriving from `BaseQuery<TQueryParameter, TQueryResult> : IQuery where TQueryParameter : IQueryParameter where TQueryResult : IQueryResult`
- You may want to run the query in parent or child mode and define the relevant overrides to resovle the query parameter accordingly.
- In `parent` mode the query parameter is resolved using `context` parameter passed to data provider class.
- In `child` mode, the query parameter is resolved using the `query result` of the `parent query` to which the current query is a child. You could have a maximum of `5` levels of children query nesting when defining the Entity schema.

> See example Customer query as parent below.
```
public class CustomerQuery : BaseQuery<CustomerParameter, CustomerResult>
{
public override void ResolveParameterInParentMode(IDataContext context)
{
// Executes as root or level 1 query.
var customer = (CustomerContext)context;
QueryParameter = new CustomerParameter
{
CustomerId = customer.CustomerId
};
}
public override void ResolveParameterInChildMode(IDataContext context, IQueryResult parentQueryResult)
{
// Does not execute as child to any query.
}
}
```
> see communication query as child to customer query below.
```
internal class CustomerCommunicationQuery : BaseQuery<CustomerParameter, CommunicationResult>
{
public override void ResolveParameterInParentMode(IDataContext context)
{
// Does not execute as root or level 1 queries.
}
public override void ResolveParameterInChildMode(IDataContext context, IQueryResult parentQueryResult)
{
// Execute as child to customer query.
var customer = (CustomerResult)parentQueryResult;
QueryParameter = new CustomerParameter
{
CustomerId = customer.Id
};
}
}
```
The parent/child relationship is achieved via entity schema configuration. see CustomerSchema above.
#### Tranformer Class
The purpose of the transformer is to map the data fetched by the linked query class to relevant schema section of the entity to be data hydrated.
- To define a transformer class for the schema path, you need to derive from `BaseTransformer<TD, T> : ITransformer
where T : IEntity
where TD : IQueryResult`
- The output of the linked query serves as input to the transformer to map data to configured section of the entity in context.

> Step 3 - Use the DataProvider class to get the entity with hydrated data based on configuration and passed in context paratemer with relevant schema paths.
```
var
```

## Extending Schemio
> coming soon
2 changes: 0 additions & 2 deletions src/Schemio.Object.SQL/ISQLQuery.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using Schemio.Object.Core;

namespace Schemio.Object.SQL
{
public interface ISQLQuery
Expand Down
2 changes: 0 additions & 2 deletions src/Schemio.Object.SQL/SQLEngine.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using Schemio.Object.Core;

namespace Schemio.Object.SQL
{
public interface SQLEngine
Expand Down
5 changes: 0 additions & 5 deletions src/Schemio.Object.SQL/SQLQuery.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using Schemio.Object.Core;

namespace Schemio.Object.SQL
{
//internal abstract class SQLQuery<T> : IQuery
Expand Down
4 changes: 0 additions & 4 deletions src/Schemio.Object.SQL/SQLQueryEngine.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data;
using System.Linq;
using Schemio.Object.Core;
using Dapper;

namespace Schemio.Object.SQL
Expand Down
2 changes: 0 additions & 2 deletions src/Schemio.Object/BaseEntity.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using Schemio.Object.Core;

namespace Schemio.Object
{
//public abstract class BaseEntity : IEntity
Expand Down
5 changes: 1 addition & 4 deletions src/Schemio.Object/BaseEntitySchema.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
/// <summary>
/// Implement to configure schema path mappings for an Entity.
Expand Down
5 changes: 1 addition & 4 deletions src/Schemio.Object/BaseQuery.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
/// <summary>
/// Implement this base class to create a data provider query.
Expand Down
6 changes: 2 additions & 4 deletions src/Schemio.Object/BaseTransformer.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
using Schemio.Object.Core;

namespace Schemio.Object
{
public abstract class BaseTransformer<TD, T> : ITransformer
where T : IEntity
where TD : IQueryResult
{
public IDataContext Context { get; private set; }

Check warning on line 7 in src/Schemio.Object/BaseTransformer.cs

View workflow job for this annotation

GitHub Actions / Build-Test

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public Type SupportedQueryResult => typeof(TD);

public void ResolveContext(IDataContext context) => Context = context;

public IEntity Run(IQueryResult queryResult, IEntity entity)
{
return queryResult.GetType() == typeof(TD) || queryResult is TD
? Transform((TD)queryResult, (T)entity) : entity;
return Transform((TD)queryResult, (T)entity);
}

public abstract T Transform(TD queryResult, T entity);
Expand Down
5 changes: 1 addition & 4 deletions src/Schemio.Object/ChildrenQueries.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
public class ChildrenQueries
{
Expand Down
7 changes: 1 addition & 6 deletions src/Schemio.Object/CreateSchema.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
#region Helpers

Expand Down Expand Up @@ -66,13 +63,11 @@ public IMapOrComplete<T, TD> Map<TQ, TR>(ISchemaPaths paths, Func<IWithDependent
};

if (dependents != null)
{
foreach (var dep in ((IMappings<T, TD>)dependents(mapping)).GetMappings)
{
dep.DependentOn ??= mapping.Query;
Add(dep);
}
}

Add(mapping);

Expand Down
15 changes: 13 additions & 2 deletions src/Schemio.Object/DataProvider.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
using Microsoft.Extensions.Logging;
using Schemio.Object.Impl;

namespace Schemio.Object.Core.Impl
namespace Schemio.Object
{
public class DataProvider<T> : IDataProvider<T> where T : IEntity
public class DataProvider<T> : IDataProvider<T> where T : IEntity, new()
{
private readonly ILogger<DataProvider<T>> logger;
private readonly IQueryExecutor queryExecutor;
private readonly IQueryBuilder<T> queryBuilder;
private readonly ITransformExecutor<T> transformExecutor;

public DataProvider(
ILogger<DataProvider<T>> logger,
IEntitySchema<T> entitySchema,
ISchemaPathMatcher schemaPathMatcher,
IQueryEngine[] queryEngines)
: this(logger, new QueryBuilder<T>(entitySchema, schemaPathMatcher),
new QueryExecutor(queryEngines), new TransformExecutor<T>(entitySchema))
{
}

public DataProvider(
ILogger<DataProvider<T>> logger,
IQueryBuilder<T> queryBuilder,
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/Helpers/ExtentionMethods.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core.Helpers
namespace Schemio.Object.Helpers
{
public static class ExtentionMethods
{
Expand Down
3 changes: 1 addition & 2 deletions src/Schemio.Object/Helpers/Xml/XDocumentExts.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Linq;
using System.Xml.Linq;

namespace Schemio.Object.Core.Helpers.Xml
namespace Schemio.Object.Helpers.Xml
{
public static class XDocumentExts
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/Helpers/Xml/XmlHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Xml;
using System.Xml.Serialization;

namespace Schemio.Object.Core.Helpers.Xml
namespace Schemio.Object.Helpers.Xml
{
public static class XmlHelper
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/Helpers/Xml/XmlSanitizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Text.RegularExpressions;
using System.Xml;

namespace Schemio.Object.Core.Helpers.Xml
namespace Schemio.Object.Helpers.Xml
{
public static class XmlSanitizer
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IDataContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IDataContext
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IDataContextValidator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IDataContextValidator
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IDataProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IDataProvider<T> where T : IEntity
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IEntity.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
/// <summary>
/// Implement Entity required to be hydrated (using query/transformer).
Expand Down
4 changes: 1 addition & 3 deletions src/Schemio.Object/IEntitySchema.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
/// <summary>
/// Implement to configure schema path mappings for an Entity.
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IPolymorphicQueryResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IPolymorphicQueryResult : IQueryResult
{
Expand Down
5 changes: 1 addition & 4 deletions src/Schemio.Object/IQuery.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
/// <summary>
/// Implement IQuery to fetch data using API or database.
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IQueryBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IQueryBuilder<T>
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IQueryEngine.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IQueryEngine
{
Expand Down
4 changes: 1 addition & 3 deletions src/Schemio.Object/IQueryExecutor.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IQueryExecutor
{
Expand Down
6 changes: 2 additions & 4 deletions src/Schemio.Object/IQueryList.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IQueryList
{
{

int QueryDependencyDepth { get; set; }
IEnumerable<IQuery> Queries { get; }
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IQueryParameter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IQueryParameter
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/IQueryResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface IQueryResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schemio.Object/ISchemaPathMatcher.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface ISchemaPathMatcher
{
Expand Down
4 changes: 1 addition & 3 deletions src/Schemio.Object/ITransformExecutor.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Generic;

namespace Schemio.Object.Core
namespace Schemio.Object
{
public interface ITransformExecutor<out TEntity> where TEntity : IEntity
{
Expand Down
Loading

0 comments on commit 21ca6f5

Please sign in to comment.