Refactor more mappers
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -11,7 +12,8 @@ namespace Umbraco.Core.Mapping
|
||||
|
||||
public class Mapper
|
||||
{
|
||||
private readonly Dictionary<Type, Dictionary<Type, Func<object, object>>> _maps = new Dictionary<Type, Dictionary<Type, Func<object, object>>>();
|
||||
private readonly Dictionary<Type, Dictionary<Type, Func<object, object>>> _ctors = new Dictionary<Type, Dictionary<Type, Func<object, object>>>();
|
||||
private readonly Dictionary<Type, Dictionary<Type, Action<object, object>>> _maps = new Dictionary<Type, Dictionary<Type, Action<object, object>>>();
|
||||
|
||||
public Mapper(MapperProfileCollection profiles)
|
||||
{
|
||||
@@ -19,15 +21,29 @@ namespace Umbraco.Core.Mapping
|
||||
profile.SetMaps(this);
|
||||
}
|
||||
|
||||
public void SetMap<TSource, TTarget>(Func<TSource, TTarget> map)
|
||||
public void SetMap<TSource, TTarget>()
|
||||
=> SetMap<TSource, TTarget>((source, target) => { });
|
||||
|
||||
public void SetMap<TSource, TTarget>(Action<TSource, TTarget> map)
|
||||
=> SetMap(source => throw new NotSupportedException($"Don't know how to create {typeof(TTarget)} instances."), map);
|
||||
|
||||
public void SetMap<TSource, TTarget>(Func<TSource, TTarget> ctor)
|
||||
=> SetMap(ctor, (source, target) => { });
|
||||
|
||||
public void SetMap<TSource, TTarget>(Func<TSource, TTarget> ctor, Action<TSource, TTarget> map)
|
||||
{
|
||||
var sourceType = typeof(TSource);
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
if (!_maps.TryGetValue(sourceType, out var sourceMap))
|
||||
sourceMap = _maps[sourceType] = new Dictionary<Type, Func<object, object>>();
|
||||
if (!_ctors.TryGetValue(sourceType, out var sourceCtor))
|
||||
sourceCtor = _ctors[sourceType] = new Dictionary<Type, Func<object, object>>();
|
||||
|
||||
sourceMap[targetType] = o => map((TSource)o);
|
||||
sourceCtor[targetType] = source => ctor((TSource) source);
|
||||
|
||||
if (!_maps.TryGetValue(sourceType, out var sourceMap))
|
||||
sourceMap = _maps[sourceType] = new Dictionary<Type, Action<object, object>>();
|
||||
|
||||
sourceMap[targetType] = (source, target) => map((TSource) source, (TTarget) target);
|
||||
}
|
||||
|
||||
public TTarget Map<TTarget>(object source)
|
||||
@@ -35,18 +51,161 @@ namespace Umbraco.Core.Mapping
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
|
||||
var sourceType = source.GetType();
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
var ctor = GetCtor(sourceType, typeof(TTarget));
|
||||
var map = GetMap(sourceType, typeof(TTarget));
|
||||
if (ctor != null && map != null)
|
||||
{
|
||||
var target = ctor(source);
|
||||
map(source, target);
|
||||
return (TTarget)target;
|
||||
}
|
||||
|
||||
bool IsOk(Type type)
|
||||
{
|
||||
// note: we're not going to work with just plain enumerables of anything,
|
||||
// only on arrays or anything that is generic and implements IEnumerable<>
|
||||
|
||||
if (type.IsArray && type.GetArrayRank() == 1) return true;
|
||||
if (type.IsGenericType && type.GenericTypeArguments.Length == 1) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Type GetGenericArg(Type type)
|
||||
{
|
||||
if (type.IsArray) return type.GetElementType();
|
||||
if (type.IsGenericType) return type.GenericTypeArguments[0];
|
||||
throw new Exception("panic");
|
||||
}
|
||||
|
||||
if (IsOk(sourceType) && IsOk(targetType))
|
||||
{
|
||||
var sourceGenericArg = GetGenericArg(sourceType);
|
||||
var targetGenericArg = GetGenericArg(targetType);
|
||||
|
||||
var sourceEnumerableType = typeof(IEnumerable<>).MakeGenericType(sourceGenericArg);
|
||||
var targetEnumerableType = typeof(IEnumerable<>).MakeGenericType(targetGenericArg);
|
||||
|
||||
if (sourceEnumerableType.IsAssignableFrom(sourceType) && targetEnumerableType.IsAssignableFrom(targetType))
|
||||
{
|
||||
ctor = GetCtor(sourceGenericArg, targetGenericArg);
|
||||
map = GetMap(sourceGenericArg, targetGenericArg);
|
||||
|
||||
if (ctor != null && map != null)
|
||||
{
|
||||
var sourceEnumerable = (IEnumerable)source;
|
||||
var targetEnumerable = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(targetGenericArg));
|
||||
|
||||
foreach (var sourceItem in sourceEnumerable)
|
||||
{
|
||||
var targetItem = ctor(sourceItem);
|
||||
map(sourceItem, targetItem);
|
||||
targetEnumerable.Add(targetItem);
|
||||
}
|
||||
|
||||
return (TTarget)targetEnumerable;
|
||||
}
|
||||
|
||||
// fixme - temp
|
||||
return AutoMapper.Mapper.Map<TTarget>(source);
|
||||
}
|
||||
}
|
||||
|
||||
// fixme this is temp
|
||||
//throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}.");
|
||||
return AutoMapper.Mapper.Map<TTarget>(source);
|
||||
}
|
||||
|
||||
// TODO: when AutoMapper is completely gone these two methods can merge
|
||||
|
||||
public TTarget Map<TSource, TTarget>(TSource source)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
|
||||
var sourceType = typeof(TSource);
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
var ctor = GetCtor(sourceType, typeof(TTarget));
|
||||
var map = GetMap(sourceType, targetType);
|
||||
if (ctor != null && map != null)
|
||||
{
|
||||
var target = ctor(source);
|
||||
map(source, target);
|
||||
return (TTarget) target;
|
||||
}
|
||||
|
||||
if (sourceType.IsGenericType && targetType.IsGenericType)
|
||||
{
|
||||
var sourceGeneric = sourceType.GetGenericTypeDefinition();
|
||||
var targetGeneric = targetType.GetGenericTypeDefinition();
|
||||
var ienumerable = typeof(IEnumerable<>);
|
||||
|
||||
if (sourceGeneric == ienumerable && targetGeneric == ienumerable)
|
||||
{
|
||||
var sourceGenericType = sourceType.GenericTypeArguments[0];
|
||||
var targetGenericType = targetType.GenericTypeArguments[0];
|
||||
|
||||
ctor = GetCtor(sourceGenericType, targetGenericType);
|
||||
map = GetMap(sourceGenericType, targetGenericType);
|
||||
|
||||
if (ctor != null && map != null)
|
||||
{
|
||||
var sourceEnumerable = (IEnumerable)source;
|
||||
var targetEnumerable = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(targetGenericType));
|
||||
|
||||
foreach (var sourceItem in sourceEnumerable)
|
||||
{
|
||||
var targetItem = ctor(sourceItem);
|
||||
map(sourceItem, targetItem);
|
||||
targetEnumerable.Add(targetItem);
|
||||
}
|
||||
|
||||
return (TTarget)targetEnumerable;
|
||||
}
|
||||
|
||||
// fixme - temp
|
||||
return AutoMapper.Mapper.Map<TSource, TTarget>(source);
|
||||
}
|
||||
}
|
||||
|
||||
// fixme this is temp
|
||||
//throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}.");
|
||||
return AutoMapper.Mapper.Map<TSource, TTarget>(source);
|
||||
}
|
||||
|
||||
public TTarget Map<TSource, TTarget>(TSource source, TTarget target)
|
||||
{
|
||||
// fixme should we deal with enumerables?
|
||||
|
||||
var map = GetMap(source.GetType(), typeof(TTarget));
|
||||
if (map == null)
|
||||
{
|
||||
// fixme this is temp
|
||||
//throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}.");
|
||||
return AutoMapper.Mapper.Map<TTarget>(source);
|
||||
return AutoMapper.Mapper.Map(source, target);
|
||||
}
|
||||
|
||||
return (TTarget) map(source);
|
||||
map(source, target);
|
||||
return target;
|
||||
}
|
||||
|
||||
private Func<object, object> GetMap(Type sourceType, Type targetType)
|
||||
private Func<object, object> GetCtor(Type sourceType, Type targetType)
|
||||
{
|
||||
if (!_ctors.TryGetValue(sourceType, out var sourceCtor))
|
||||
{
|
||||
var type = _maps.Keys.FirstOrDefault(x => x.IsAssignableFrom(sourceType));
|
||||
if (type == null)
|
||||
return null;
|
||||
sourceCtor = _ctors[sourceType] = _ctors[type];
|
||||
}
|
||||
|
||||
return sourceCtor.TryGetValue(targetType, out var ctor) ? ctor : null;
|
||||
}
|
||||
|
||||
private Action<object, object> GetMap(Type sourceType, Type targetType)
|
||||
{
|
||||
if (!_maps.TryGetValue(sourceType, out var sourceMap))
|
||||
{
|
||||
@@ -58,41 +217,5 @@ namespace Umbraco.Core.Mapping
|
||||
|
||||
return sourceMap.TryGetValue(targetType, out var map) ? map : null;
|
||||
}
|
||||
|
||||
public TTarget Map<TSource, TTarget>(TSource source)
|
||||
{
|
||||
return AutoMapper.Mapper.Map<TSource, TTarget>(source);
|
||||
|
||||
var sourceType = typeof(TSource);
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
var map = GetMap(sourceType, targetType);
|
||||
if (map != null)
|
||||
return (TTarget) map(source);
|
||||
|
||||
if (sourceType.IsGenericType && targetType.IsGenericType)
|
||||
{
|
||||
var sourceGeneric = sourceType.GetGenericTypeDefinition();
|
||||
var targetGeneric = targetType.GetGenericTypeDefinition();
|
||||
var ienumerable = typeof(IEnumerable<>);
|
||||
|
||||
if (sourceGeneric == ienumerable && targetGeneric == ienumerable)
|
||||
{
|
||||
var sourceGenericType = sourceGeneric.GetGenericArguments()[0];
|
||||
var targetGenericType = targetGeneric.GetGenericArguments()[0];
|
||||
map = GetMap(sourceGenericType, targetGenericType);
|
||||
// fixme - how can we enumerate, generically?
|
||||
}
|
||||
}
|
||||
|
||||
// fixme this is temp
|
||||
//throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}.");
|
||||
return AutoMapper.Mapper.Map<TSource, TTarget>(source);
|
||||
}
|
||||
|
||||
public TTarget Map<TSource, TTarget>(TSource source, TTarget target)
|
||||
{
|
||||
return AutoMapper.Mapper.Map(source, target); // fixme what does this do exactly?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,18 +21,19 @@ namespace Umbraco.Core.Models.Identity
|
||||
|
||||
public void SetMaps(Mapper mapper)
|
||||
{
|
||||
mapper.SetMap<IUser, BackOfficeIdentityUser>(Map);
|
||||
}
|
||||
|
||||
public BackOfficeIdentityUser Map(IUser source)
|
||||
{
|
||||
var target = new BackOfficeIdentityUser(source.Id, source.Groups);
|
||||
target.DisableChangeTracking();
|
||||
Map(source, target);
|
||||
target.ResetDirtyProperties(true);
|
||||
target.EnableChangeTracking();
|
||||
|
||||
return target;
|
||||
mapper.SetMap<IUser, BackOfficeIdentityUser>(
|
||||
source =>
|
||||
{
|
||||
var target = new BackOfficeIdentityUser(source.Id, source.Groups);
|
||||
target.DisableChangeTracking();
|
||||
return target;
|
||||
},
|
||||
(source, target) =>
|
||||
{
|
||||
Map(source, target);
|
||||
target.ResetDirtyProperties(true);
|
||||
target.EnableChangeTracking();
|
||||
});
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -Id -Groups -LockoutEnabled -PhoneNumber -PhoneNumberConfirmed -TwoFactorEnabled
|
||||
|
||||
92
src/Umbraco.Tests/Mapping/MappingTests.cs
Normal file
92
src/Umbraco.Tests/Mapping/MappingTests.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Mapping;
|
||||
|
||||
namespace Umbraco.Tests.Mapping
|
||||
{
|
||||
[TestFixture]
|
||||
public class MappingTests
|
||||
{
|
||||
[Test]
|
||||
public void SimpleMap()
|
||||
{
|
||||
var profiles = new MapperProfileCollection(new IMapperProfile[]
|
||||
{
|
||||
new Profile1(),
|
||||
});
|
||||
var mapper = new Mapper(profiles);
|
||||
|
||||
var thing1 = new Thing1 { Value = "value" };
|
||||
var thing2 = mapper.Map<Thing1, Thing2>(thing1);
|
||||
|
||||
Assert.IsNotNull(thing2);
|
||||
Assert.AreEqual("value", thing2.Value);
|
||||
|
||||
thing2 = mapper.Map<Thing2>(thing1);
|
||||
|
||||
Assert.IsNotNull(thing2);
|
||||
Assert.AreEqual("value", thing2.Value);
|
||||
|
||||
thing2 = new Thing2();
|
||||
mapper.Map(thing1, thing2);
|
||||
Assert.AreEqual("value", thing2.Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnumerableMap()
|
||||
{
|
||||
var profiles = new MapperProfileCollection(new IMapperProfile[]
|
||||
{
|
||||
new Profile1(),
|
||||
});
|
||||
var mapper = new Mapper(profiles);
|
||||
|
||||
var thing1A = new Thing1 { Value = "valueA" };
|
||||
var thing1B = new Thing1 { Value = "valueB" };
|
||||
var thing1 = new[] { thing1A, thing1B };
|
||||
var thing2 = mapper.Map<IEnumerable<Thing1>, IEnumerable<Thing2>>(thing1).ToList();
|
||||
|
||||
Assert.IsNotNull(thing2);
|
||||
Assert.AreEqual(2, thing2.Count);
|
||||
Assert.AreEqual("valueA", thing2[0].Value);
|
||||
Assert.AreEqual("valueB", thing2[1].Value);
|
||||
|
||||
thing2 = mapper.Map<IEnumerable<Thing2>>(thing1).ToList();
|
||||
|
||||
Assert.IsNotNull(thing2);
|
||||
Assert.AreEqual(2, thing2.Count);
|
||||
Assert.AreEqual("valueA", thing2[0].Value);
|
||||
Assert.AreEqual("valueB", thing2[1].Value);
|
||||
|
||||
// fixme is this a thing?
|
||||
//thing2 = new List<Thing2>();
|
||||
//mapper.Map(thing1, thing2);
|
||||
//Assert.AreEqual("value", thing2.Value);
|
||||
}
|
||||
|
||||
private class Thing1
|
||||
{
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
private class Thing2
|
||||
{
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
private class Profile1 : IMapperProfile
|
||||
{
|
||||
public void SetMaps(Mapper mapper)
|
||||
{
|
||||
mapper.SetMap<Thing1, Thing2>(source => new Thing2(), (source, target) => Map(source, target));
|
||||
}
|
||||
|
||||
private Thing2 Map(Thing1 source, Thing2 target)
|
||||
{
|
||||
target.Value = source.Value;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,6 +131,7 @@
|
||||
<Compile Include="LegacyXmlPublishedCache\PreviewXmlDto.cs" />
|
||||
<Compile Include="Logging\LogviewerTests.cs" />
|
||||
<Compile Include="Manifest\ManifestContentAppTests.cs" />
|
||||
<Compile Include="Mapping\MappingTests.cs" />
|
||||
<Compile Include="Migrations\MigrationPlanTests.cs" />
|
||||
<Compile Include="Migrations\MigrationTests.cs" />
|
||||
<Compile Include="Models\ContentScheduleTests.cs" />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Mapping;
|
||||
@@ -12,8 +13,14 @@ namespace Umbraco.Web.Composing.CompositionExtensions
|
||||
{
|
||||
public static Composition ComposeWebMappingProfiles(this Composition composition)
|
||||
{
|
||||
// register the profiles
|
||||
composition.WithCollectionBuilder<MapperProfileCollectionBuilder>()
|
||||
.Append<AuditMapperProfile>()
|
||||
.Append<SectionMapperProfile>()
|
||||
.Append<TagMapperProfile>();
|
||||
|
||||
//register the profiles
|
||||
composition.Register<Profile, AuditMapperProfile>();
|
||||
//composition.Register<Profile, AuditMapperProfile>();
|
||||
composition.Register<Profile, CodeFileMapperProfile>();
|
||||
composition.Register<Profile, ContentMapperProfile>();
|
||||
composition.Register<Profile, ContentPropertyMapperProfile>();
|
||||
@@ -26,8 +33,8 @@ namespace Umbraco.Web.Composing.CompositionExtensions
|
||||
composition.Register<Profile, MemberMapperProfile>();
|
||||
composition.Register<Profile, RedirectUrlMapperProfile>();
|
||||
composition.Register<Profile, RelationMapperProfile>();
|
||||
composition.Register<Profile, SectionMapperProfile>();
|
||||
composition.Register<Profile, TagMapperProfile>();
|
||||
//composition.Register<Profile, SectionMapperProfile>();
|
||||
//composition.Register<Profile, TagMapperProfile>();
|
||||
composition.Register<Profile, TemplateMapperProfile>();
|
||||
composition.Register<Profile, UserMapperProfile>();
|
||||
composition.Register<Profile, LanguageMapperProfile>();
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
internal class AuditMapperProfile : Profile
|
||||
internal class AuditMapperProfile : IMapperProfile
|
||||
{
|
||||
public AuditMapperProfile()
|
||||
public void SetMaps(Mapper mapper)
|
||||
{
|
||||
CreateMap<IAuditItem, AuditLog>()
|
||||
.ForMember(log => log.UserAvatars, expression => expression.Ignore())
|
||||
.ForMember(log => log.UserName, expression => expression.Ignore())
|
||||
.ForMember(log => log.NodeId, expression => expression.MapFrom(item => item.Id))
|
||||
.ForMember(log => log.Timestamp, expression => expression.MapFrom(item => item.CreateDate))
|
||||
.ForMember(log => log.LogType, expression => expression.MapFrom(item => item.AuditType));
|
||||
mapper.SetMap<IAuditItem, AuditLog>(source => new AuditLog(), (source, target) => Map(source, target));
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -UserAvatars -UserName
|
||||
private AuditLog Map(IAuditItem source, AuditLog target)
|
||||
{
|
||||
target.UserId = source.UserId;
|
||||
target.NodeId = source.Id;
|
||||
target.Timestamp = source.CreateDate;
|
||||
target.LogType = source.AuditType.ToString();
|
||||
target.EntityType = source.EntityType;
|
||||
target.Comment = source.Comment;
|
||||
target.Parameters = source.Parameters;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using AutoMapper;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models.Sections;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Sections;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
internal class SectionMapperProfile : Profile
|
||||
internal class SectionMapperProfile : IMapperProfile
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
public SectionMapperProfile(ILocalizedTextService textService)
|
||||
{
|
||||
CreateMap<ISection, Section>()
|
||||
.ForMember(dest => dest.RoutePath, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => textService.Localize("sections/" + src.Alias, (IDictionary<string, string>)null)))
|
||||
.ReverseMap(); //backwards too!
|
||||
_textService = textService;
|
||||
}
|
||||
|
||||
public void SetMaps(Mapper mapper)
|
||||
{
|
||||
mapper.SetMap<ISection, Section>(source => new Section(), Map);
|
||||
|
||||
// this is for AutoMapper ReverseMap - but really?
|
||||
mapper.SetMap<Section, ContentSection>();
|
||||
mapper.SetMap<Section, ContentSection>();
|
||||
mapper.SetMap<Section, ManifestSection>(Map);
|
||||
mapper.SetMap<Section, MediaSection>();
|
||||
mapper.SetMap<Section, MembersSection>();
|
||||
mapper.SetMap<Section, PackagesSection>();
|
||||
mapper.SetMap<Section, SettingsSection>();
|
||||
mapper.SetMap<Section, TranslationSection>();
|
||||
mapper.SetMap<Section, UsersSection>();
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -RoutePath
|
||||
private void Map(ISection source, Section target)
|
||||
{
|
||||
target.Alias = source.Alias;
|
||||
target.Name = _textService.Localize("sections/" + source.Alias);
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll
|
||||
private void Map(Section source, ManifestSection target)
|
||||
{
|
||||
target.Alias = source.Alias;
|
||||
target.Name = source.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
using AutoMapper;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
internal class TagMapperProfile : Profile
|
||||
internal class TagMapperProfile : IMapperProfile
|
||||
{
|
||||
public TagMapperProfile()
|
||||
public void SetMaps(Mapper mapper)
|
||||
{
|
||||
CreateMap<ITag, TagModel>();
|
||||
mapper.SetMap<ITag, TagModel>(source => new TagModel(), Map);
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll
|
||||
private void Map(ITag source, TagModel target)
|
||||
{
|
||||
target.Id = source.Id;
|
||||
target.Text = source.Text;
|
||||
target.Group = source.Group;
|
||||
target.NodeCount = source.NodeCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,9 @@
|
||||
<PackageReference Include="NPoco" Version="3.9.4" />
|
||||
<PackageReference Include="Semver" Version="2.0.4" />
|
||||
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.9.0" />
|
||||
<PackageReference Include="Umbraco.Code">
|
||||
<Version>1.0.0</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
|
||||
|
||||
Reference in New Issue
Block a user