I'm using the latest Umbraco and Models Builder, and I'm creating custom property value converter in order to extend Models Builder generator to recognise data types like RadioButton, Dropdown, Tags etc.
Here I will stick to the DropdownConverter implementation. The problem I want to solve is using DI (Autofac) in places other that controllers where it works fine.
This is my implementation of the Dropdown Converter
public class DropdownConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
private readonly UmbracoHelper _umbracoHelper;
public DropdownConverter(UmbracoHelper umbracoHelper)
{
_umbracoHelper = umbracoHelper;
}
public override bool IsConverter(PublishedPropertyType propertyType)
{
return "Umbraco.DropDown".InvariantEquals(propertyType.PropertyEditorAlias);
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
return source != null ? _umbracoHelper.GetPreValueAsString((int)source) : string.Empty;
}
public Type GetPropertyValueType(PublishedPropertyType propertyType)
{
return typeof(string);
}
public PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType, PropertyCacheValue cacheValue)
{
return PropertyCacheLevel.Content;
}
}
Generated property type
///<summary>
/// Category: Set blog category
///</summary>
[ImplementPropertyType("category")]
public object Category
{
get { return this.GetPropertyValue("category"); }
}
Here you can see that I'm using constructor injection for one dependency that I need to use in my converter (UmbracoHelper).
When I leave converter like this, MB won't recognise property value type and will generate 'object' as a previous default value. But if you ask for the result of this property somewhere in the code, you will get proper string value because converter works as expected and DI works also.
Otherwise, If I write the code with another empty constructor, MB will successfully recognise return type, but now DI won't work and my UmbracoHelper will be null (CastException is thrown).
public class DropdownConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
private readonly UmbracoHelper _umbracoHelper;
public DropdownConverter()
{
}
public DropdownConverter(UmbracoHelper umbracoHelper)
{
_umbracoHelper = umbracoHelper;
}
public override bool IsConverter(PublishedPropertyType propertyType)
{
return "Umbraco.DropDown".InvariantEquals(propertyType.PropertyEditorAlias);
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
return source != null ? _umbracoHelper.GetPreValueAsString((int)source) : string.Empty;
}
public Type GetPropertyValueType(PublishedPropertyType propertyType)
{
return typeof(string);
}
public PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType, PropertyCacheValue cacheValue)
{
return PropertyCacheLevel.Content;
}
}
Generated property type
///<summary>
/// Category: Set blog category
///</summary>
[ImplementPropertyType("category")]
public string Category
{
get { return this.GetPropertyValue<string>("category"); }
}
It seems that MB needs an empty constructor in a property converter.
My question is, given that I want to use DI all over the project, how I can do it in this place and is it possible anyway? I also tried property injection principle but still no luck.
The bigger question I'm not sure of, do property converters have a single instance in the application. If so, you'll want to refactor the implementation to not assign in the constructor as the context would be stale after first request.
Custom umbraco property converter for Models Builder - dependency injection issue (DI)
Hi guys,
I'm using the latest Umbraco and Models Builder, and I'm creating custom property value converter in order to extend Models Builder generator to recognise data types like RadioButton, Dropdown, Tags etc.
Here I will stick to the DropdownConverter implementation. The problem I want to solve is using DI (Autofac) in places other that controllers where it works fine.
This is my implementation of the Dropdown Converter
Generated property type
Here you can see that I'm using constructor injection for one dependency that I need to use in my converter (UmbracoHelper).
When I leave converter like this, MB won't recognise property value type and will generate 'object' as a previous default value. But if you ask for the result of this property somewhere in the code, you will get proper string value because converter works as expected and DI works also.
Otherwise, If I write the code with another empty constructor, MB will successfully recognise return type, but now DI won't work and my UmbracoHelper will be null (CastException is thrown).
Generated property type
It seems that MB needs an empty constructor in a property converter. My question is, given that I want to use DI all over the project, how I can do it in this place and is it possible anyway? I also tried property injection principle but still no luck.
Thanks, Bojan
And, did you manage to find a solution to this? Running into this too...
Hi Bojan,
The simplest solution would be to create a
then assign the GetUmbracoHelper to a static function that creates UmbracoHelper instances with no function arguments in an ApplicationEventHandler.
Then in your constructor you can fallback to it with something like
The bigger question I'm not sure of, do property converters have a single instance in the application. If so, you'll want to refactor the implementation to not assign in the constructor as the context would be stale after first request.
Hope this helps,
Brad
Also, if you like using DI in Umbraco, you should look into a NuGet package I made called Renderings, noted here.
is working on a reply...