Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/articles/AbstractionLayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,29 @@ The constraint is also not based on an inherent property of the activity or reso

## Identity

[Identities](xref:Moryx.AbstractionLayer.Identity.IIdentity) are used to represent unique properties like serial numbers and MAC adresses for instances and material number for products. There is also the derived type [ProductIdentity](xref:Moryx.AbstractionLayer.ProductIdentity) that represents a products material number and revision. The static constructor `AsLatestRevision` also lets you refer to the latest revision for a certain material.
[Identities](../../src/Moryx.AbstractionLayer/Identity/IIdentity.cs) are used to represent unique properties like serial numbers and MAC adresses for instances and material number for products. There is also the derived type [ProductIdentity](../../src/Moryx.AbstractionLayer/Products/ProductIdentity.cs) that represents a products material number and revision. The static constructor `AsLatestRevision` also lets you refer to the latest revision for a certain material.

## Process

A [Process](Processing/Processes.md) consists of a series of activities.

## Products

A [ProductType](xref:Moryx.AbstractionLayer.Products.IProductType) or better a *product description* is used by a [ProductRecipe](xref:Moryx.AbstractionLayer.Recipes.ProductRecipe) to provide a basic structure to produce a [ProductInstance](xref:Moryx.AbstractionLayer.Products.ProductInstance)
A [ProductType](../../src/Moryx.AbstractionLayer/Products/IProductType.cs) or better a *product description* is used by a [ProductRecipe](../../src/Moryx.AbstractionLayer/Recipes/ProductRecipe.cs) to provide a basic structure to produce a [ProductInstance](../../src/Moryx.AbstractionLayer/Products/ProductInstance.cs)

## Recipes

A [Recipe](xref:Moryx.AbstractionLayer.Recipes.Recipe) is the base for all recipes which combines all needed data for a process.
A [Recipe](../../src/Moryx.AbstractionLayer/Recipes/Recipe.cs) is the base for all recipes which combines all needed data for a process.

A [ProductRecipe](xref:Moryx.AbstractionLayer.Recipes.ProductRecipe) provides a basic structure to use a product for production cases.
A [ProductRecipe](../../src/Moryx.AbstractionLayer/Recipes/ProductRecipe.cs) provides a basic structure to use a product for production cases.

A [WorkplanRecipe](xref:Moryx.AbstractionLayer.Recipes.WorkplanRecipe) provides a Workplan and a set of parameters to define all the [Activities](xref:Activities) needed for a Process.
A [WorkplanRecipe](../../src/Moryx.AbstractionLayer/Recipes/WorkplanRecipe.cs) provides a Workplan and a set of parameters to define all the [Activities](Processing/Activities.md) needed for a Process.

A [ProductionRecipe](xref:Moryx.AbstractionLayer.Recipes.ProductionRecipe) is the combination of a `ProductRecipe` and `WorkplanRecipe`.
A [ProductionRecipe](../../src/Moryx.AbstractionLayer/Recipes/ProductionRecipe.cs) is the combination of a `ProductRecipe` and `WorkplanRecipe`.

## Resources

The Resources package of the AbstrationLayer contains several basic classes to be used by the [Resources](xref:Moryx.AbstractionLayer.Resources.IResource) and the [ResourceManager](Resources/ResourceManagement.md)
The Resources package of the AbstrationLayer contains several basic classes to be used by the [Resources](../../src/Moryx.AbstractionLayer/Resources/IResource.cs) and the [ResourceManager](Resources/ResourceManagement.md)

## Tasks

Expand Down
26 changes: 13 additions & 13 deletions docs/articles/Core/Bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ uid: Bindings
---
# Bindings

The types of the `Moryx.Bindings`-namespace located in _Moryx_ offer the functionality to dynamically resolve or update properties of objects. An [IBindingResolver](xref:Moryx.Bindings.IBindingResolver) is created by an instance of [IBindingResolverFactory](xref:Moryx.Bindings.IBindingResolverFactory) from a string like `"Branch.Name"`. The resolver will then return the value of `Name` for each `object source` passed into the `Resolve(source)`-method.
The types of the `Moryx.Bindings`-namespace located in _Moryx_ offer the functionality to dynamically resolve or update properties of objects. An [IBindingResolver](../../../src/Moryx/Bindings/IBindingResolver.cs) is created by an instance of [IBindingResolverFactory](../../../src/Moryx/Bindings/IBindingResolverFactory.cs) from a string like `"Branch.Name"`. The resolver will then return the value of `Name` for each `object source` passed into the `Resolve(source)`-method.

It is also possible to set the value of the property by calling `Update(object, object)` on the resolver created by the factory.

Expand Down Expand Up @@ -44,15 +44,15 @@ resolver.Update(root, "Marie"); // Value of "root.Branch" = "Marie"

## IBindingResolver Chain

Implementations of [IBindingResolver](xref:Moryx.Bindings.IBindingResolver) are build as a recursive double-linked list using their extended [IBindingResolverChain](xref:Moryx.Bindings.IBindingResolver) interface. Each link of the chain resolves a fragment of the string using the source object and passes the result to the next link. When updating a value the resolver chain is executed up to the last link and instead of calling `Resolve` on the last link, `Update` is invoked.
Implementations of [IBindingResolver](../../../src/Moryx/Bindings/IBindingResolver.cs) are build as a recursive double-linked list using their extended [IBindingResolverChain](../../../src/Moryx/Bindings/IBindingResolver.cs) interface. Each link of the chain resolves a fragment of the string using the source object and passes the result to the next link. When updating a value the resolver chain is executed up to the last link and instead of calling `Resolve` on the last link, `Update` is invoked.

The chain of resolvers is built by the [IBindingResolverFactory](xref:Moryx.Bindings.IBindingResolverFactory) by parsing the string and creating links token by token. A token is text fragement between two dots or an index like __name__ in `Parameters[name]`. Unlike XAML-binding not all tokens directly represent a property. An implementation of [IBindingResolverFactory](xref:Moryx.Bindings.IBindingResolverFactory) might define special keys or short-cuts.
The chain of resolvers is built by the [IBindingResolverFactory](../../../src/Moryx/Bindings/IBindingResolverFactory.cs) by parsing the string and creating links token by token. A token is text fragement between two dots or an index like __name__ in `Parameters[name]`. Unlike XAML-binding not all tokens directly represent a property. An implementation of [IBindingResolverFactory](../../../src/Moryx/Bindings/IBindingResolverFactory.cs) might define special keys or short-cuts.

The platform provides a base class [BindingResolverBase](xref:Moryx.Bindings.BindingResolverBase) and four standard implementations of [IBindingResolver](xref:Moryx.Bindings.IBindingResolver).
The platform provides a base class [BindingResolverBase](../../../src/Moryx/Bindings/BindingResolverBase.cs) and four standard implementations of [IBindingResolver](../../../src/Moryx/Bindings/IBindingResolver.cs).

### BindingResolverBase

This base class implements the [IBindingResolverChain](xref:Moryx.Bindings.IBindingResolver) interface and should be used instead of implementing the interface manually. It provides an explicit `Resolve`-method that continues invocation on the recursive chain. If the object is `null` or this was the last link in the chain it returns the current value.
This base class implements the [IBindingResolverChain](../../../src/Moryx/Bindings/IBindingResolver.cs) interface and should be used instead of implementing the interface manually. It provides an explicit `Resolve`-method that continues invocation on the recursive chain. If the object is `null` or this was the last link in the chain it returns the current value.

A simple example for a custom resolver could resolve the type of an object.

Expand All @@ -75,7 +75,7 @@ public class TypeResolver : BindingResolverBase

### NullResolver

Following the [Null-Object pattern](https://en.wikipedia.org/wiki/Null_Object_pattern) this resolver can be used whenever an instance of [IBindingResolver](xref:Moryx.Bindings.IBindingResolver) is required but no operation should be performed. The [NullResolver](xref:Moryx.Bindings.NullResolver) simply continues the chain by calling proceed with the unmodified source object.
Following the [Null-Object pattern](https://en.wikipedia.org/wiki/Null_Object_pattern) this resolver can be used whenever an instance of [IBindingResolver](../../../src/Moryx/Bindings/IBindingResolver.cs) is required but no operation should be performed. The [NullResolver](../../../src/Moryx/Bindings/NullResolver.cs) simply continues the chain by calling proceed with the unmodified source object.

Example in code:

Expand All @@ -87,7 +87,7 @@ result = resolver.Resolve("Name"); // Value of result = "Name"

### ReflectionResolver

By using reflection [this resolver](xref:Moryx.Bindings.ReflectionResolver) tries to load the value of the property from the source object. The name of the property is usually parsed as the text between dots in the binding string. The example at the top creates two reflection resolvers - one for `"Branch"` and one for `"Name"`. Because this resolver uses reflection it is significantly slower than the others and should not be used to resolve values which could be accessed another way. The resolver also supports updating the value as long as the property `CanWrite`.
By using reflection [this resolver](../../../src/Moryx/Bindings/ReflectionResolver.cs) tries to load the value of the property from the source object. The name of the property is usually parsed as the text between dots in the binding string. The example at the top creates two reflection resolvers - one for `"Branch"` and one for `"Name"`. Because this resolver uses reflection it is significantly slower than the others and should not be used to resolve values which could be accessed another way. The resolver also supports updating the value as long as the property `CanWrite`.

Example in code:

Expand All @@ -111,7 +111,7 @@ resolver.Update(foo, "Bob");

### DelegateResolver

The [delegate resolver](xref:Moryx.Bindings.DelegateResolver) can be used to implement simple custom resolution rules without creating a new implementation of [IBindingResolver](xref:Moryx.Bindings.IBindingResolver). It is created from a delegate `Func<object, object>` and will call it for each call to `Resolve()`. The result of the callback is returned.
The [delegate resolver](../../../src/Moryx/Bindings/DelegateResolver.cs) can be used to implement simple custom resolution rules without creating a new implementation of [IBindingResolver](../../../src/Moryx/Bindings/IBindingResolver.cs). It is created from a delegate `Func<object, object>` and will call it for each call to `Resolve()`. The result of the callback is returned.

Using the DelegateResolver to provide the `GetType()` behavior:

Expand All @@ -131,7 +131,7 @@ resolver.Update(foo, "Bob");

### FormatBindingResolver

The [format resolver](xref:Moryx.Bindings.FormatBindingResolver) can create format strings for objects implementing `IFormattable`. It is used by the `TextBindingResolverFactory`, that is explained further down in this documentation.
The [format resolver](../../../src/Moryx/Bindings/FormatBindingResolver.cs) can create format strings for objects implementing `IFormattable`. It is used by the `TextBindingResolverFactory`, that is explained further down in this documentation.

An easy example using the resolver to format a string with fixed length:

Expand All @@ -142,7 +142,7 @@ var result = resolver.Resolve(3); // Value of result = "003"

### IndexResolver

The [index resolver](xref:Moryx.Bindings.IndexResolver) can extract values from collections and dictionaries. Given an index like `"Thomas"` or `10` it tries to interpret those values either as indexes in `IList` or as the key in a dictionary. Because the index resolver expects a collection as `source` object it usually needs to be preceded by another resolver that resolves the collection itself. This is done be the `BindingResolverFactory` that uses a Regex to combine a `ReflectionResolver` with an `IndexResolver` when it finds a string like `Collection[index]`. It also supports the `Update`-method to set values.
The [index resolver](../../../src/Moryx/Bindings/IndexResolver.cs) can extract values from collections and dictionaries. Given an index like `"Thomas"` or `10` it tries to interpret those values either as indexes in `IList` or as the key in a dictionary. Because the index resolver expects a collection as `source` object it usually needs to be preceded by another resolver that resolves the collection itself. This is done be the `BindingResolverFactory` that uses a Regex to combine a `ReflectionResolver` with an `IndexResolver` when it finds a string like `Collection[index]`. It also supports the `Update`-method to set values.

Using it stand-alone looks like this:

Expand All @@ -163,7 +163,7 @@ resolver.Update(dict, "OtherValue");

## IBindingResolverFactory

The resolver factory builds a recursive chain of `IBindingResolver` from a string like `"Root.Branch.Name"`. The default and base implementation is [BindingResolverFactory](xref:Moryx.Bindings.BindingResolverFactory). It is similar to the binding-engine in XAML with the addition that it supports collection resolution. Custom resolver factories are built by creating a type derived from `BindingResolverFactory`. Below is an example for a factory that supports loading the objects type. The example explains the two concepts base key and custom resolution rules.
The resolver factory builds a recursive chain of `IBindingResolver` from a string like `"Root.Branch.Name"`. The default and base implementation is [BindingResolverFactory](../../../src/Moryx/Bindings/BindingResolverFactory.cs). It is similar to the binding-engine in XAML with the addition that it supports collection resolution. Custom resolver factories are built by creating a type derived from `BindingResolverFactory`. Below is an example for a factory that supports loading the objects type. The example explains the two concepts base key and custom resolution rules.

````cs
public class TypeResolverFactory : BindingResolverFactory
Expand Down Expand Up @@ -253,9 +253,9 @@ Applying the previous sections to a few examples the factory and resolver chain

## Text Bindings

While there might be some use cases of those bindings by themselves, the more common use is to embed them into text. This is done by instances of [ITextBindingResolver](xref:Moryx.Bindings.ITextBindingResolver) created by the [TextBindingResolverFactory](xref:Moryx.Bindings.TextBindingResolverFactory). The text binding resolver factory is static and builds text resolvers using the given [IBindingResolverFactory](xref:Moryx.Bindings.IBindingResolverFactory). This means all custom bindings can be used within text without any additional effort.
While there might be some use cases of those bindings by themselves, the more common use is to embed them into text. This is done by instances of [ITextBindingResolver](../../../src/Moryx/Bindings/ITextBindingResolver.cs) created by the [TextBindingResolverFactory](../../../src/Moryx/Bindings/TextBindingResolverFactory.cs). The text binding resolver factory is static and builds text resolvers using the given [IBindingResolverFactory](../../../src/Moryx/Bindings/IBindingResolverFactory.cs). This means all custom bindings can be used within text without any additional effort.

The text resolution also supports formatting by appending `":<format>"` to the binding expression. It supports the default formats of the type it is applied to. This features is implemented by appending a [FormatBindingResolver](xref:Moryx.Bindings.FormatBindingResolver) to the end of the chain.
The text resolution also supports formatting by appending `":<format>"` to the binding expression. It supports the default formats of the type it is applied to. This features is implemented by appending a [FormatBindingResolver](../../../src/Moryx/Bindings/FormatBindingResolver.cs) to the end of the chain.

Using the previous examples using the text resolvers looks like this.

Expand Down
2 changes: 1 addition & 1 deletion docs/articles/Core/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class SubConfig
}
````

The basic structure of the configuration object including the [IConfig](xref:Moryx.Configuration.IConfig) implementation. The dummy properties and subclass can be renamed or deleted once you understand the structure of a configuration.
The basic structure of the configuration object including the [IConfig](../../../src/Moryx/Configuration/IConfig.cs) implementation. The dummy properties and subclass can be renamed or deleted once you understand the structure of a configuration.

## Conventions

Expand Down
6 changes: 3 additions & 3 deletions docs/articles/Core/DataModel/ModificationTracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ uid: Model.ModificationTracking

Sometimes developers want to keep track about modifications of a row in their table. MORYX framework has a built-in solution to keep track about creation, update and deletion time.

To make an entity trackable you just need to derive from [IModificationTrackedEntity](xref:Moryx.Model.IModificationTrackedEntity) or the corresponding base class [ModificationTrackedEntityBase](xref:Moryx.Model.ModificationTrackedEntityBase).
To make an entity trackable you just need to derive from [IModificationTrackedEntity](../../../../src/Moryx.Model/IEntity.cs) or the corresponding base class [ModificationTrackedEntityBase](../../../../src/Moryx.Model/ModificationTrackedEntityBase.cs).

````cs
public class PersonEntity : ModificationTrackedEntityBase
Expand All @@ -22,12 +22,12 @@ The example above defines four additional columns: Id (from `EntityBase`), Creat
- `Updated`: Shows when the row was updated
- `Deleted`: Is set when the row was deleted.

`Created` and `Updated` are automatically set by the db context base class [MoryxDbContext](xref:Moryx.Model.MoryxDbContext) whenever the entity was modified. Your context must derive from it. The `Deleted` flag is only automatically set, if the [UnitOfWork with Repositories](UnitOfWorkPattern.md) is used, otherwise if plain EntityFramework, the `DbSet`-extension `RemoveSoft` is the way to set the flag. The `RemoveSoft` extension only sets the `Deleted`-property on the entity to the current datetime. To synchronize the DateTimes, the `MoryxDbContext` will modify the `Deleted`-property again to match with the `Updated`-property.
`Created` and `Updated` are automatically set by the db context base class [MoryxDbContext](../../../../src/Moryx.Model/MoryxDbContext.cs) whenever the entity was modified. Your context must derive from it. The `Deleted` flag is only automatically set, if the [UnitOfWork with Repositories](UnitOfWorkPattern.md) is used, otherwise if plain EntityFramework, the `DbSet`-extension `RemoveSoft` is the way to set the flag. The `RemoveSoft` extension only sets the `Deleted`-property on the entity to the current datetime. To synchronize the DateTimes, the `MoryxDbContext` will modify the `Deleted`-property again to match with the `Updated`-property.

## Migrations

You do not need to treat modified trackable entities in another way. It will work with no further action.

## A last word

If you are interested how the modified trackable mechanism is implemented you'll find some deeper information in [Code First](xref:GettingsStarted.CodeFirst) article or the [EntityFramework Tutorial](https://www.entityframeworktutorial.net/faq/set-created-and-modified-date-in-efcore.aspx)
If you are interested how the modified trackable mechanism is implemented you'll find some deeper information in [Code First](../../../tutorials/DataModel/CodeFirst.md) article or the [EntityFramework Tutorial](https://www.entityframeworktutorial.net/faq/set-created-and-modified-date-in-efcore.aspx)
2 changes: 1 addition & 1 deletion docs/articles/Core/DataModel/MoryxDbContext.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The `MoryxDbContext` is an inhertied `DbContext` which brings a set of additiona

- [Modification Tracking](ModificationTracking.md)
- [Automatic DateTimeKind conversion](#DateTimeKind-conversion)
- Support of [`DefaultSchemaAttribute`](xref:Moryx.Model.DefaultSchemaAttribute)
- Support of [`DefaultSchemaAttribute`](../../../../src/Moryx.Model/Attributes/DefaultSchemaAttribute.cs)

## DateTimeKind conversion

Expand Down
Loading