类中的Automapper IEnumerable未映射到RepeatedField [英] Automapper IEnumerable within class is not being mapped to RepeatedField

查看:303
本文介绍了类中的Automapper IEnumerable未映射到RepeatedField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在两个班级之间映射:

I want to map between two classes:

public class A {
    public IEnumerable<C> someList
}

public class B {
    public RepeatedField<D> someList
}

其中RepeatedField是Google.Protobuf.Collections中的一个类,用于处理gRPC数据.

where RepeatedField is a class from Google.Protobuf.Collections that handles gRPC data.

事实证明,gRPC通过其原型创建类的方式并不完全类似于创建类似B的类.

As it turns out, the way that gRPC creates classes via its prototype is not exactly like creating a class like B. See my answer.

我这样创建一个Automapper MappingConfiguration

I create an Automapper MappingConfiguration like this

return new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<C, D>().ReverseMap();
        cfg.CreateMap<A, B>().ReverseMap();
    });

,然后通过ASP.NET Startup类进行注册.

and then it gets registered via ASP.NET Startup class.

如果我在另一个班级做类似的事情

If I do something like this in another class

A instanceA; // assume A's list has values inside
var listofD = this.mapper.Map<List<D>>(A.someList)

它正确地返回一个包含值的列表.但是:

it correctly returns a list with values inside. However:

A instanceA; // assume A's list has values inside
B instanceB = this.mapper.Map<B>(A);

返回B的一个实例,但是instanceB内的列表为空.我该如何解决?

returns an instance of B, but the list inside of instanceB is empty. How do I fix this?

推荐答案

我已经解决了这个问题.

I've solved the issue.

C#类中的Google.Protobuf.Collections.RepeatedField是只读的,这意味着直接向其中分配值将不起作用,并且只会在返回的途中返回一个空列表.因此,我在两个较大的类之间创建了一个自定义类型转换器,以将它们组合在一起.它的作用是将值直接添加到RepeatedField中,而不是填充我自己的RepeatedField并将值分配给类.

A Google.Protobuf.Collections.RepeatedField inside a C# class is readonly, meaning that directly assigning values into it won't work and will only return an empty list on the way back. Therefore, I created a custom type converter between the two larger classes to bring them together. What it does is add values directly into the RepeatedField rather than populating my own RepeatedField and assigning the value into the class.

public static class mapConfig
{
    public static ContainerBuilder RegisterObjectMappers(this ContainerBuilder builder)
    {
        builder.Register(c => GetV1MapperConfiguration().CreateMapper())
            .As<IMapper>().SingleInstance();

        return builder;
    }
    private static MapperConfiguration GetMapConfig()
    {
        return new MapperConfiguration(cfg =>
        {
            // some mappings here
            cfg.CreateMap<C, D>().ReverseMap();
            cfg.CreateMap<A, B>().ConvertUsing<AToBConverter>();
        });
    }
}
public class AToBConverter : ITypeConverter<A, B>
{
    public B Convert(A source, B destination, ResolutionContext context)
    {
        var b = new B
        {
            // internal values here aside from the repeated field(s)
        };

        // Need to use the Add method to add values rather than assign it with an '=' sign
        foreach (var someValue in source.someList)
        {
            b.someList.Add(context.Mapper.Map<D>(someValue));
        }
        return b;
    }
}

从RepeatedField转换为List或映射类中的任何其他IEnumerable都没有问题,并且不需要其他转换器.

Converting from RepeatedField to a List or any other IEnumerable in a mapped class isn't any trouble and didn't require another converter for me.

这篇关于类中的Automapper IEnumerable未映射到RepeatedField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆