fixed more injection issues

This commit is contained in:
kay.one 2013-05-31 21:59:54 -07:00
parent e5cc0c1a93
commit 0d7326c798
2 changed files with 82 additions and 21 deletions

View File

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Marr.Data; using Marr.Data;
using NUnit.Framework; using NUnit.Framework;
@ -19,6 +21,7 @@ using NzbDrone.Core.Qualities;
using NzbDrone.Core.RootFolders; using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Update; using NzbDrone.Core.Update;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
using System.Linq;
namespace NzbDrone.Api.Test.MappingTests namespace NzbDrone.Api.Test.MappingTests
{ {
@ -72,6 +75,44 @@ namespace NzbDrone.Api.Test.MappingTests
modelWithLazy.Guid.IsLoaded.Should().BeTrue(); modelWithLazy.Guid.IsLoaded.Should().BeTrue();
} }
[Test]
public void should_be_able_to_map_lists()
{
var modelList = Builder<TestModel>.CreateListOfSize(10).Build();
var resourceList = modelList.InjectTo<List<TestResource>>();
resourceList.Should().HaveSameCount(modelList);
}
[Test]
public void should_map_wrapped_models()
{
var modelList = Builder<TestModel>.CreateListOfSize(10).Build().ToList();
var wrapper = new TestModelWrapper
{
TestlList = modelList
};
wrapper.InjectTo<TestResourceWrapper>();
}
[Test]
public void should_map_qualityprofile()
{
var profileResource = new QualityProfileResource
{
Allowed = Builder<QualityResource>.CreateListOfSize(1).Build().ToList(),
};
profileResource.InjectTo<QualityProfile>();
}
} }
public class ModelWithLazy public class ModelWithLazy
@ -86,14 +127,32 @@ namespace NzbDrone.Api.Test.MappingTests
public class TestLazyLoaded<T> : LazyLoaded<T> public class TestLazyLoaded<T> : LazyLoaded<T>
{ {
public TestLazyLoaded()
{
}
public override void Prepare(Func<IDataMapper> dataMapperFactory, object parent) public override void Prepare(Func<IDataMapper> dataMapperFactory, object parent)
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
} }
public class TestModelWrapper
{
public List<TestModel> TestlList { get; set; }
}
public class TestResourceWrapper
{
public List<TestResource> TestList { get; set; }
}
public class TestModel
{
public string Field1 { get; set; }
public string Field2 { get; set; }
}
public class TestResource
{
public string Field1 { get; set; }
public string Field2 { get; set; }
}
} }

View File

@ -17,11 +17,9 @@ namespace NzbDrone.Api.Mapping
protected override object SetValue(ConventionInfo conventionInfo) protected override object SetValue(ConventionInfo conventionInfo)
{ {
//for value types and string just return the value as is
if (conventionInfo.SourceProp.Type.IsValueType || conventionInfo.SourceProp.Type == typeof(string)) if (conventionInfo.SourceProp.Type.IsValueType || conventionInfo.SourceProp.Type == typeof(string))
return conventionInfo.SourceProp.Value; return conventionInfo.SourceProp.Value;
//handle arrays
if (conventionInfo.SourceProp.Type.IsArray) if (conventionInfo.SourceProp.Type.IsArray)
{ {
var array = (Array)conventionInfo.SourceProp.Value; var array = (Array)conventionInfo.SourceProp.Value;
@ -39,11 +37,9 @@ namespace NzbDrone.Api.Mapping
return clone; return clone;
} }
if (conventionInfo.SourceProp.Type.IsGenericType) if (conventionInfo.SourceProp.Type.IsGenericType)
{ {
var genericInterfaces = conventionInfo.SourceProp.Type.GetGenericTypeDefinition().GetInterfaces(); var genericInterfaces = conventionInfo.SourceProp.Type.GetGenericTypeDefinition().GetInterfaces();
//handle IEnumerable<> also ICollection<> IList<> List<>
if (genericInterfaces.Any(d => d == typeof(IEnumerable))) if (genericInterfaces.Any(d => d == typeof(IEnumerable)))
{ {
return MapLists(conventionInfo); return MapLists(conventionInfo);
@ -59,7 +55,7 @@ namespace NzbDrone.Api.Mapping
} }
//for simple object types create a new instace and apply the clone injection on it //for simple object types create a new instace and apply the clone injection on it
return Activator.CreateInstance(conventionInfo.SourceProp.Type) return Activator.CreateInstance(conventionInfo.TargetProp.Type)
.InjectFrom<CloneInjection>(conventionInfo.SourceProp.Value); .InjectFrom<CloneInjection>(conventionInfo.SourceProp.Value);
} }
@ -80,20 +76,26 @@ namespace NzbDrone.Api.Mapping
private static object MapLists(ConventionInfo conventionInfo) private static object MapLists(ConventionInfo conventionInfo)
{ {
var t = conventionInfo.SourceProp.Type.GetGenericArguments()[0]; var genericArgument = conventionInfo.TargetProp.Type.GetGenericArguments()[0];
if (t.IsValueType || t == typeof(string)) return conventionInfo.SourceProp.Value; if (genericArgument.IsValueType || genericArgument == typeof(string))
var tlist = typeof(List<>).MakeGenericType(t);
var list = Activator.CreateInstance(tlist);
var addMethod = tlist.GetMethod("Add");
foreach (var o in (IEnumerable)conventionInfo.SourceProp.Value)
{ {
var e = Activator.CreateInstance(t).InjectFrom<CloneInjection>(o); return conventionInfo.SourceProp.Value;
addMethod.Invoke(list, new[] { e }); // in 4.0 you can use dynamic and just do list.Add(e);
} }
return list;
var listType = typeof(List<>).MakeGenericType(genericArgument);
var addMethod = listType.GetMethod("Add");
var result = Activator.CreateInstance(listType);
foreach (var sourceItem in (IEnumerable)conventionInfo.SourceProp.Value)
{
var e = Activator.CreateInstance(genericArgument).InjectFrom<CloneInjection>(sourceItem);
addMethod.Invoke(result, new[] {e });
}
return result;
} }
} }
} }