umbraco/Umbraco-CMS — pull request #421 by zpqrtbnk (2014-06-28 18:39:49+00:00)
Title: U4-4973 - public "detached" PublishedProperty

See [U4-4973](http://issues.umbraco.org/issue/U4-4973) and [discussion on Our](http://our.umbraco.org/forum/umbraco-7/developing-umbraco-7-packages/49470-IPublishedProperty-has-no-context?p=1#comment179197) -- this PR makes the proposed solution public.

##### Changes
* Opens a constructor for `PublishedContentType` that enables the creation of published content types that are not linked to any actual content type, and constructors for `PublishedPropertyType` that enables the creation of published property types that are not linked to any actual content type.
* Adds methods on `PublishedPropertyType` that makes it possible to obtained a *detached* or *nested* copy of a property type.
* Adds the `GetDetached` static method on `PublishedProperty` that enables the creation of detached and nested properties.
* Adds the `DetachedContent` class which provides a very basic container for something have several detached properties.

##### Discussion
In some cases a property value converter wants to return something that is actually a composition of several elements, each being treated as a property ie having its value converted, using the registered converted, from the raw data.

Imagine a property editor that would allow users to pick multiple geographic locations, and for each location to attach a text string eg a legend. We want the property converter for that property editor to return an `IEnumerable` where `Place` has two properties, `Location` which is a geographic location, and `Legend` which is a text string. For the geographic location, the property editor embeds the Google Maps editor, and we don't want to re-create a value converter because that editor provides one, which returns a `GeoLocation` object. So we just want to reuse that converter.

So we basically want to indicate that what is returned by the property value converter actually is a composition of several elements, each being treated as a property ie having its value converted.

The converter would contain code looking like:

```csharp
public object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool isPreview)
{
var type = new PublishedPropertyType("location", "GoogleMapsEditor");
var nestedType = type.Nested(propertyType);
var locationProperty = PublishedProperty.GetDetached(nestedType, locationData, isPreview);
return new Place(locationProperty, legend);
}
```

And the `Place` class would look like:

```csharp
public class Place
{
private IPublishedProperty _locationProperty;
private string _legend;

public Place(IPublishedProperty locationProperty, string legend)
{
_locationProperty = locationProperty;
_legend = legend;
}

public GeoLocation Location { get { return _location.GetValue(); } }
public string Legend { get { return _legend; } }
}
```

Few more things: a *detached* property is a property that is not linked to any actual content, whereas a *nested* property is part of another, actual content, property. We need the difference because we need to manage the cache level of converted values.

Hopefully that all makes *some* sense. Questions?