Files
Umbraco-CMS/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs
T

82 lines
3.1 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Persistence.Mappers
{
internal class MappingResolver : LazyManyObjectsResolverBase<MappingResolver, BaseMapper>
{
/// <summary>
/// Constructor accepting a list of BaseMapper types that are attributed with the MapperFor attribute
/// </summary>
/// <param name="serviceProvider"></param>
/// <param name="logger"></param>
/// <param name="assignedMapperTypes"></param>
public MappingResolver(IServiceProvider serviceProvider, ILogger logger, Func<IEnumerable<Type>> assignedMapperTypes)
: base(serviceProvider, logger, assignedMapperTypes)
{
}
/// <summary>
/// Caches the type -> mapper so that we don't have to type check each time we want one or lookup the attribute
/// </summary>
private readonly ConcurrentDictionary<Type, BaseMapper> _mapperCache = new ConcurrentDictionary<Type, BaseMapper>();
/// <summary>
/// Return a mapper by type
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public virtual BaseMapper ResolveMapperByType(Type type)
{
return _mapperCache.GetOrAdd(type, type1 =>
{
//first check if we can resolve it by attribute
var byAttribute = TryGetMapperByAttribute(type);
if (byAttribute.Success)
{
return byAttribute.Result;
}
throw new Exception("Invalid Type: A Mapper could not be resolved based on the passed in Type " + type);
});
}
/// <summary>
/// Check the entity type to see if it has a mapper attribute assigned and try to instantiate it
/// </summary>
/// <param name="entityType"></param>
/// <returns></returns>
private Attempt<BaseMapper> TryGetMapperByAttribute(Type entityType)
{
//check if any of the mappers are assigned to this type
var mapper = Values.FirstOrDefault(
x => x.GetType().GetCustomAttributes<MapperForAttribute>(false)
.Any(m => m.EntityType == entityType));
if (mapper == null)
{
return Attempt<BaseMapper>.Fail();
}
return Attempt<BaseMapper>.Succeed(mapper);
}
public virtual string GetMapping(Type type, string propertyName)
{
var mapper = ResolveMapperByType(type);
var result = mapper.Map(propertyName);
if(string.IsNullOrEmpty(result))
throw new Exception("Invalid mapping: The passed in property name could not be mapped using the passed in type");
return result;
}
}
}