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.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using Marr.Data;
using NUnit.Framework;
@ -19,6 +21,7 @@ using NzbDrone.Core.Qualities;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Update;
using NzbDrone.Test.Common;
using System.Linq;
namespace NzbDrone.Api.Test.MappingTests
{
@ -72,6 +75,44 @@ namespace NzbDrone.Api.Test.MappingTests
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
@ -86,14 +127,32 @@ namespace NzbDrone.Api.Test.MappingTests
public class TestLazyLoaded<T> : LazyLoaded<T>
{
public TestLazyLoaded()
{
}
public override void Prepare(Func<IDataMapper> dataMapperFactory, object parent)
{
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)
{
//for value types and string just return the value as is
if (conventionInfo.SourceProp.Type.IsValueType || conventionInfo.SourceProp.Type == typeof(string))
return conventionInfo.SourceProp.Value;
//handle arrays
if (conventionInfo.SourceProp.Type.IsArray)
{
var array = (Array)conventionInfo.SourceProp.Value;
@ -39,11 +37,9 @@ namespace NzbDrone.Api.Mapping
return clone;
}
if (conventionInfo.SourceProp.Type.IsGenericType)
{
var genericInterfaces = conventionInfo.SourceProp.Type.GetGenericTypeDefinition().GetInterfaces();
//handle IEnumerable<> also ICollection<> IList<> List<>
if (genericInterfaces.Any(d => d == typeof(IEnumerable)))
{
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
return Activator.CreateInstance(conventionInfo.SourceProp.Type)
return Activator.CreateInstance(conventionInfo.TargetProp.Type)
.InjectFrom<CloneInjection>(conventionInfo.SourceProp.Value);
}
@ -80,20 +76,26 @@ namespace NzbDrone.Api.Mapping
private static object MapLists(ConventionInfo conventionInfo)
{
var t = conventionInfo.SourceProp.Type.GetGenericArguments()[0];
if (t.IsValueType || t == typeof(string)) return conventionInfo.SourceProp.Value;
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 genericArgument = conventionInfo.TargetProp.Type.GetGenericArguments()[0];
if (genericArgument.IsValueType || genericArgument == typeof(string))
{
var e = Activator.CreateInstance(t).InjectFrom<CloneInjection>(o);
addMethod.Invoke(list, new[] { e }); // in 4.0 you can use dynamic and just do list.Add(e);
return conventionInfo.SourceProp.Value;
}
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;
}
}
}