English 中文(简体)
AutoMapper忽视了全球化学品统一分类标签制度任择领域的模式
原标题:AutoMapper ignore pattern for optional GRPC fields

我试图混淆<条码>AutoMapper,以忽视也拥有<条码>的财产。 Has{PropertyName} nature on the same category, set to false

This is for mapping GRPC classes which use optional in the .proto definition. (I require presence detection, so using wrapper classes won t help me.)

e.g.

syntax = "proto3";

message MyGRPCFoo {
    optional int32 bar = 1;
}

然后,在我的C#类别中,在使用变量之前,我会核对<代码>HasBar。

I am aware how to do this per individual member, but I want to achieve it for all members at once.

我尝试了<代码>ShouldMapProperty,但只暴露了PropertyInfo/code>,因此,我无法了解来文方的标语。

I also tried ForAllMembers, but while it exposes the source object, I did not see how to get the current source property name, only the destination name is exposed. I don t want to rely on the assumption that source and destination names are the same.

问题回答

采用以下案文:

message MyGRPCFoo  {
    optional int32 bar = 1;
}

[TestClass]
public class GRPCTests
{
    public class Foo
    {
        public int MyBar { get; set; }
    }

    [TestMethod]
    public void PresenceDetectionTest()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<MyGRPCFoo, Foo>()
                        .ForMember(e => e.MyBar, prop => prop.MapFrom(src => src.Bar));

            // Use reflection to determine which properties require precense detection
            var properties = typeof(MyGRPCFoo).GetProperties();
            var propertyLookup = properties.ToDictionary(e => e.Name, e => e); // Name as lookup should be safe because CodeGen doesn t create methods with overloads

            // Contains a func to invoke to check if property has precense
            var propertyCheck = new Dictionary<MemberInfo, Func<MyGRPCFoo, bool>>();

            foreach (var prop in properties)
            {
                if (propertyLookup.TryGetValue($"Has{prop.Name}", out var propToCheck))
                {
                    Func<MyGRPCFoo, bool> check = (obj) => (bool)propToCheck.GetValue(obj);
                    propertyCheck.Add(prop, check);
                }
            }

            var @internal = cfg.Internal();

            // Although the precondition is added after the previous mapping, it still gets evaluated first
            @internal.ForAllPropertyMaps(e => propertyCheck.ContainsKey(e.SourceMember),
                (propertyMap, ex) => ex.PreCondition((src, ctx) => propertyCheck[propertyMap.SourceMember]((MyGRPCFoo)src)));
        });

        config.AssertConfigurationIsValid();

        // Source Value is 1
        var grpcFoo = new MyGRPCFoo() { Bar = 1 };

        // But cleared, so should not be applied to target value
        grpcFoo.ClearBar();

        var mapper = config.CreateMapper();

        var target = new Foo() { MyBar = 2 };
        mapper.Map(grpcFoo, target);

        Assert.AreEqual(2, target.MyBar);
    }
}




相关问题
Blazor Server App : Unable to unprotect the message.State

I am getting an Exception as above in my Blazor server application. Below is my Program.cs File builder.Services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme) .AddOpenIdConnect(...

System Text JsonSerializer Deserialization of TimeSpan

In researching how to deserialize a TimeSpan using Newtonsoft s JSON.net I came across code in my current project that did not use Json.net. It used System.Text.Json.JsonSerializer and appeared to not ...

TCP Connection Creation and Closing Event Hooking [closed]

What helper classes C# provides to monitor all TCP connection on an OS. A piece of Sample code would also be appreciated. Note: Original intent was to monitor this on Windows but would be nice to do ...