This repository has been archived by the owner on Dec 13, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #166 from leekelleher/develop
Release 0.9.0-beta
- Loading branch information
Showing
121 changed files
with
3,757 additions
and
2,838 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
## Upgrading to v0.9.0 | ||
|
||
With Ditto v0.9.0 the introduction of Processors has made an overall breaking change for developers who have built custom TypeConverters or ValueResolvers with previous Ditto versions. The intention of Processors are to combine the power and flexibility of both TypeConverters and ValueResolvers together. | ||
|
||
### TypeConverters | ||
|
||
Here are some notes on how to refactor your custom TypeConverters to use the new Processors. | ||
|
||
#### Functional changes | ||
|
||
* Change the class inheritance from `DittoConverter` to `DittoProcessor` | ||
* _If applicable_, remove the `CanConvertFrom` method, (this is no longer relevant to the processor workflow) | ||
* Change the main `ConvertFrom` name and method signature from: | ||
|
||
```csharp | ||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) | ||
``` | ||
to | ||
|
||
```csharp | ||
public override object ProcessValue() | ||
``` | ||
|
||
* Change any variable references (inside the `ConvertFrom` method) to the new inherited properties: | ||
* (`ITypeDescriptorContext`) `context` is now `Context` (capitalized) | ||
* (`CultureInfo`) `culture` is now accessible via the `Context` object, e.g. `Context.Culture` | ||
* (`object`) `value` is now `Value` (capitalized) | ||
|
||
The rest of your old TypeConverter logic should remain the same. | ||
|
||
> If you do encounter any major issues in refactoring a TypeConverter, please do let us know. We would like these notes to cover as much as they can. | ||
|
||
#### Cosmetic changes | ||
|
||
* If your custom TypeConverter class name has a "Converter" suffix, consider changing this to use the "Processor" suffix. This makes no change in how Ditto uses the class, it is purely for cosmetic and conventional reasons. | ||
|
||
|
||
### ValueResolvers | ||
|
||
Here are some notes on how to refactor your custom ValueResolvers to use the new Processors. | ||
|
||
* Change the class inheritance from `DittoValueResolver` to `DittoProcessor` | ||
* Change the main `ResolveValue` name and method signature from: | ||
|
||
```csharp | ||
public override object ResolveValue() | ||
``` | ||
|
||
to | ||
|
||
```csharp | ||
public override object ProcessValue() | ||
``` | ||
|
||
The rest of your old ValueResolver logic should remain the same. | ||
|
||
> If you do encounter any major issues in refactoring a ValueResolver, please do let us know. We would like these notes to cover as much as they can. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
## Processors | ||
|
||
The key feature of Ditto is the ability to process a value (typically from an `IPublishedContent` property) and set it to the property of the target view-model. To do this we use a Processor (or a combination of Processors). | ||
|
||
While Ditto covers the most common types of processing, (via the use of [attributes](usage-advanced-attributes), there may be scenarios where you may need a little help in processing custom (or complex) values. | ||
|
||
Traditionally any custom processor logic would be typically done within an MVC controller. However, if the logic is only relevant to the mapping operation, then it may clutter your controller code and be better suited as a custom `Processor`. | ||
|
||
For example, let's look at having a calculated value during mapping, say that you wanted to display the number of days since a piece of content was last updated: | ||
|
||
```csharp | ||
public class MyModel | ||
{ | ||
[MyCustomProcessor] | ||
public int DaysSinceUpdated { get; set; } | ||
} | ||
|
||
public class MyCustomProcessor : DittoProcessorAttribute | ||
{ | ||
public override object ProcessValue() | ||
{ | ||
var content = Value as IPublishedContent; | ||
if (content == null) return null; | ||
|
||
return (DateTime.UtcNow - content.UpdateDate).Days; | ||
} | ||
} | ||
``` | ||
|
||
Once mapped, the value of `DaysSinceUpdated` would contain the number of days difference between the content item's last update date and today's date (UTC now). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,7 @@ | ||
## Type Converters | ||
|
||
Sooner or later you'll reach a point where you will want to map a DocumentType property with a complex .NET type (either from within the .NET Framework, or custom). To map these types with Ditto, you can use a standard .NET `TypeConverter`. | ||
As of Ditto v0.9.0 TypeConverters have been deprecated and replaced with [Processors][usage-advanced-processors]. | ||
|
||
> If you are not familiar with .NET TypeConverters, please read Scott Hanselman's blog post: [TypeConverters: There's not enough TypeDescripter.GetConverter in the world](http://www.hanselman.com/blog/TypeConvertersTheresNotEnoughTypeDescripterGetConverterInTheWorld.aspx). This gives a good 'real-world' understanding of their purpose. | ||
> | ||
> Then from there, refer to the MSDN documentation on [How to: Implement a Type Converter](http://msdn.microsoft.com/en-gb/library/ayybcxe5.aspx) | ||
If you have developed a custom TypeConverters against a previous version of Ditto, then [please refer to this migration guide](upgrade-090). | ||
|
||
Now with our example, let's say that you wanted the `BodyText` property to be of type `HtmlString` (rather than a basic `string`). You can reference a custom `TypeConverter` by adding the following attribute to the POCO property: | ||
|
||
```csharp | ||
[TypeConverter(typeof(MyCustomConverter))] | ||
public HtmlString BodyText { get; set; } | ||
``` | ||
|
||
Then when the POCO property is populated the (raw) value (from `IPublishedContent`) will be processed through the custom `TypeConverter` and converted to the desired .NET type. | ||
|
||
Here is the example code for the `MyCustomConverter`, that converts a `string` to a `HtmlString` object: | ||
|
||
```csharp | ||
public class MyCustomConverter : TypeConverter | ||
{ | ||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) | ||
{ | ||
if (sourceType == typeof(string)) | ||
return true; | ||
|
||
return base.CanConvertFrom(context, sourceType); | ||
} | ||
|
||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) | ||
{ | ||
if (value is string) | ||
return new System.Web.HtmlString((string)value); | ||
|
||
return base.ConvertFrom(context, culture, value); | ||
} | ||
} | ||
``` | ||
> **Note:** It is important to note that when getting a property-value from Umbraco, any associated TypeConverters (for the target value-type) will still be called. In a nutshell, this means that you can use TypeConverters with Umbraco, but not Ditto. |
Oops, something went wrong.