82 lines
3.1 KiB
C#
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;
|
|
}
|
|
|
|
}
|
|
|
|
} |