Asp.net 如何使用ValueInjector映射列表

Asp.net 如何使用ValueInjector映射列表,asp.net,asp.net-mvc,asp.net-mvc-3,valueinjecter,Asp.net,Asp.net Mvc,Asp.net Mvc 3,Valueinjecter,我使用的是ASP.netmvc3 有人能帮我澄清一下这里发生了什么吗: var person = new PersonRepository().Get(); var personViewModel = new PersonViewModel(); personViewModel.InjectFrom<LoopValueInjection>(person) .InjectFrom<CountryToLookup>(person); 我原以为下面的方法行得通,但

我使用的是
ASP.netmvc3

有人能帮我澄清一下这里发生了什么吗:

var person = new PersonRepository().Get();

var personViewModel = new PersonViewModel();
personViewModel.InjectFrom<LoopValueInjection>(person)
     .InjectFrom<CountryToLookup>(person);
我原以为下面的方法行得通,但行不通:

// Mapping
IList<CategoryViewModel> viewModelList = new List<CategoryViewModel>();
viewModelList.InjectFrom(categoryList);
//映射
IList viewModelList=新列表();
viewModelList.InjectFrom(类别列表);

AFAIK value Injector不支持像AutoMapper那样的自动集合映射,但您可以使用简单的LINQ表达式对每个元素进行操作:

IEnumerable<Category> categoryList = categoryService.GetAll();
IList<CategoryViewModel> viewModelList = categoryList
    .Select(x => new CategoryViewModel().InjectFrom(x)).Cast<CategoryViewModel>()
    .ToList();
IEnumerable categoryList=categoryService.GetAll();
IList viewModelList=类别列表
.Select(x=>newcategoryviewmodel().InjectFrom(x)).Cast()
.ToList();
更新-从不同来源注入

public static ICollection<TTo> InjectFrom<TFrom, TTo>(this ICollection<TTo> to, params IEnumerable<TFrom>[] sources) where TTo : new()
{
    foreach (var from in sources)
    {
        foreach (var source in from)
        {
            var target = new TTo();
            target.InjectFrom(source);
            to.Add(target);
        }
    }
    return to;
}
公共静态ICollection InjectFrom(此ICollection to,params IEnumerable[]源),其中TTo:new()
{
foreach(来源中的var)
{
foreach(from中的变量源)
{
var target=new TTo();
目标。从(源)注入;
添加(目标);
}
}
返回;
}
用法:

var activeUsers = new PersonRepository().GetActive();
var lockedUsers = new PersonRepository().GetLocked();
var personViewModels = new List<PersonViewModel>();

personViewModels.InjectFrom(activeUsers, lockedUsers);
var-activeUsers=newpersonrepository().GetActive();
var lockedUsers=newPersonRepository().GetLocked();
var personViewModels=新列表();
personViewModels.InjectFrom(activeUsers、lockedUsers);

使用此函数定义

public static object InjectCompleteFrom(this object target, object source)
{
    if (target.GetType().IsGenericType &&
        target.GetType().GetGenericTypeDefinition() != null && 
        target.GetType().GetGenericTypeDefinition().GetInterfaces() != null &&
        target.GetType().GetGenericTypeDefinition().GetInterfaces()
              .Contains(typeof(IEnumerable)) && 
        source.GetType().IsGenericType &&
        source.GetType().GetGenericTypeDefinition() != null &&
        source.GetType().GetGenericTypeDefinition().GetInterfaces() != null &&
        source.GetType().GetGenericTypeDefinition().GetInterfaces()
              .Contains(typeof(IEnumerable)))
    {
        var t = target.GetType().GetGenericArguments()[0];
        var tlist = typeof(List<>).MakeGenericType(t);
        var addMethod = tlist.GetMethod("Add");

        foreach (var sourceItem in source as IEnumerable)
        {
            var e = Activator.CreateInstance(t).InjectFrom<CloneInjection>(sourceItem);
            addMethod.Invoke(target, new[] { e });
        }

        return target;
    }
    else
    {
        return target.InjectFrom(source);
    }
}    
公共静态对象InjectCompleteFrom(此对象目标,对象源)
{
if(target.GetType().IsGenericType&&
target.GetType().GetGenericTypeDefinition()!=null&&
target.GetType().GetGenericTypeDefinition().GetInterfaces()!=null&&
target.GetType().GetGenericTypeDefinition().GetInterfaces()
.Contains(typeof(IEnumerable))&&
source.GetType().IsGenericType&&
source.GetType().GetGenericTypeDefinition()!=null&&
source.GetType().GetGenericTypeDefinition().GetInterfaces()!=null&&
source.GetType().GetGenericTypeDefinition().GetInterfaces()
.Contains(typeof(IEnumerable)))
{
var t=target.GetType().GetGenericArguments()[0];
var tlist=typeof(List).MakeGenericType(t);
var addMethod=tlist.GetMethod(“Add”);
foreach(源中的var sourceItem作为IEnumerable)
{
var e=Activator.CreateInstance(t).InjectFrom(sourceItem);
Invoke(目标,new[]{e});
}
回报目标;
}
其他的
{
返回target.InjectFrom(源);
}
}    

对于像我这样喜欢尽可能短的符号的人

public static ICollection<TTarget> InjectFromList<TTarget, TOrig>(this ICollection<TTarget> target, ICollection<TOrig> source) where TTarget : new()
{
    source.Select(r => new TTarget().InjectFrom(r))
       .Cast<TTarget>().ToList().ForEach(e => target.Add(e));
    return target;
}
public static ICollection<TTarget> InjectFromList<TTarget, TOrig>(this ICollection<TTarget> target, params ICollection<TOrig>[] sources) where TTarget : new()
{
    sources.ToList().ForEach(s => s.ToList().Select(r => new TTarget().InjectFrom(r))
       .Cast<TTarget>().ToList().ForEach(e => target.Add(e)));
    return target;
}
publicstaticicollection InjectFromList(此ICollection目标,ICollection源),其中TTarget:new()
{
source.Select(r=>newttarget().InjectFrom(r))
.Cast().ToList().ForEach(e=>target.Add(e));
回报目标;
}
公共静态ICollection InjectFromList(此ICollection目标,参数ICollection[]源),其中TTarget:new()
{
sources.ToList().ForEach(s=>s.ToList().Select(r=>newttarget().InjectFrom(r))
.Cast().ToList().ForEach(e=>target.Add(e));
回报目标;
}

创建通用列表映射器:

public class ValueMapper
{
     public static TResult Map<TResult>(object item) where TResult : class
    {
        return item == null ? null : Mapper.Map<TResult>(item);
    }

    public static IEnumerable<TResult> MapList<TResult>(IEnumerable<object> items) where TResult : class
    {
        return items?.Select(i => Mapper.Map<TResult>(i));
    }
}

改为创建一个扩展方法,您将得到+1(以避免重复代码)。谢谢:我这样做了,但是我得到了以下结果:
无法将类型“System.Collections.Generic.List”隐式转换为“System.Collections.Generic.IList”。存在显式转换(是否缺少转换?
)。为演员设置
(IList)
就足够了吗?@jgauffin:我不知道如何创建一个扩展:)你想这样做吗?@BrendanVogt:请看我的单独答案。@BrendanVogt我在Darin的答案中添加了一个演员设置,现在试试你也可以看这里:如果你想要更像automapper@ChuckNorris:您是否错过了标签“valueinjector”? ;)是的,我给了你一个ValueInjector页面的链接,这里展示了如何以更自动化的方式使用valueinjecter。Umbraco CMS使用此方法默认InjectFrom仅适用于对象类型,它不会对int和string@ChuckNorris:奇怪。在发布代码之前,我先测试运行代码。很好。我的ValueInjector副本中一定有个bug。无论如何,类型并不重要。该示例适用于集合此扩展方法是否可以扩展,以便我们可以从多个源注入,其中每个源都是一个列表?谢谢。@jgauffin感谢扩展方法,使我的生活更轻松!哈三年后的今天,我又找到了这个答案。我忘记了我在过去发现并实现了您的扩展方法。就在最近,我换了工作,开始使用InjectFromList(为了帮助其他团队成员找到它,我稍微重命名了它),但它不在那里。这是一个平滑的解决方案,与您的日常工作无缝集成,让您忘记了它的存在!这个答案是否适用于
对象
,这些对象是任何类型的集合,如
IEnumerable
ICollection
?现在如何@杰戈芬
var activeUsers = new PersonRepository().GetActive();
var lockedUsers = new PersonRepository().GetLocked();
var personViewModels = new List<PersonViewModel>();

personViewModels.InjectFrom(activeUsers, lockedUsers);
public static object InjectCompleteFrom(this object target, object source)
{
    if (target.GetType().IsGenericType &&
        target.GetType().GetGenericTypeDefinition() != null && 
        target.GetType().GetGenericTypeDefinition().GetInterfaces() != null &&
        target.GetType().GetGenericTypeDefinition().GetInterfaces()
              .Contains(typeof(IEnumerable)) && 
        source.GetType().IsGenericType &&
        source.GetType().GetGenericTypeDefinition() != null &&
        source.GetType().GetGenericTypeDefinition().GetInterfaces() != null &&
        source.GetType().GetGenericTypeDefinition().GetInterfaces()
              .Contains(typeof(IEnumerable)))
    {
        var t = target.GetType().GetGenericArguments()[0];
        var tlist = typeof(List<>).MakeGenericType(t);
        var addMethod = tlist.GetMethod("Add");

        foreach (var sourceItem in source as IEnumerable)
        {
            var e = Activator.CreateInstance(t).InjectFrom<CloneInjection>(sourceItem);
            addMethod.Invoke(target, new[] { e });
        }

        return target;
    }
    else
    {
        return target.InjectFrom(source);
    }
}    
public static ICollection<TTarget> InjectFromList<TTarget, TOrig>(this ICollection<TTarget> target, ICollection<TOrig> source) where TTarget : new()
{
    source.Select(r => new TTarget().InjectFrom(r))
       .Cast<TTarget>().ToList().ForEach(e => target.Add(e));
    return target;
}
public static ICollection<TTarget> InjectFromList<TTarget, TOrig>(this ICollection<TTarget> target, params ICollection<TOrig>[] sources) where TTarget : new()
{
    sources.ToList().ForEach(s => s.ToList().Select(r => new TTarget().InjectFrom(r))
       .Cast<TTarget>().ToList().ForEach(e => target.Add(e)));
    return target;
}
public class ValueMapper
{
     public static TResult Map<TResult>(object item) where TResult : class
    {
        return item == null ? null : Mapper.Map<TResult>(item);
    }

    public static IEnumerable<TResult> MapList<TResult>(IEnumerable<object> items) where TResult : class
    {
        return items?.Select(i => Mapper.Map<TResult>(i));
    }
}
var mydtos = ValueMapper.MapList<MyDto>(dtos);
var mydto = ValueMapper.Map<MyDto>(dto);