Основа для объединения хозяйствующих субъектов

Есть ли рамки, которые могут сделать следующее:

var source = new Entity()
{
    StringProp = null,
    IntProp = 100,

};

var target = new Entity()
{
    StringProp = "stringValue", // Property value should remain the same if source value is null 
    IntProp = 222
};

var mergedEntity = MergeFramework.Merge(source, target); // Here is what I am looking for

Assert.AreEqual(100, mergedEntity.IntField);
Assert.AreEqual("stringValue", mergedEntity.StringField);

Ниже рабочий процесс, где мне это нужно:

  1. Приложение получает экземпляр объекта. Некоторые свойства экземпляра являются нулевыми. (исходный экземпляр)

  2. Приложение извлекает из базы данных сущность с той же идентичностью, что и в источнике. (целевой экземпляр)

  3. Объединяет две сущности и сохраняет объединенные в базу данных.

Основная проблема заключается в том, что в моем проекте около 600 объектов, поэтому я не хочу писать логику слияния для каждого объекта вручную. По сути, я ищу что-то гибкое, например, AutoMapper или ValueInjecter, которое удовлетворяет следующим требованиям:

  • Предоставить возможность указать условия слияния типов. Например: если source.IntProp == int.MinInt -> не объединять свойство

  • Предоставить возможность указать специфические условия недвижимости. Как в AutoMapper:

    Mapper.CreateMap (). ForMember (dest => dest.EventDate, opt => opt.MapFrom (src => src.EventDate.Date));

2 ответа

Решение

Ну вот:

using System;
using NUnit.Framework;
using Omu.ValueInjecter;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            var source = new Entity()
            {
                StringProp = null,
                IntProp = 100,

            };

            var target = new Entity()
            {
                StringProp = "stringValue", // Property value should remain the same if source value is null 
                IntProp = 222
            };

            var mergedEntity = (Entity) target.InjectFrom<Merge>(source);

            Assert.AreEqual(100, mergedEntity.IntProp);
            Assert.AreEqual("stringValue", mergedEntity.StringProp);
            Console.WriteLine("ok");
        }
    }

    public class Merge : ConventionInjection
    {
        protected override bool Match(ConventionInfo c)
        {
            return c.SourceProp.Name == c.TargetProp.Name
                   && c.SourceProp.Value != null;
        }
    }

    public class Entity
    {
        public string StringProp { get; set; }

        public int IntProp { get; set; }
    }

}

Чтобы обновить текущий ответ, ConventionInjection был объявлен устаревшим Теперь вы можете использовать LoopInjection при создании пользовательских инъекций.

Пример обновленного Merge Инъекционный класс:

public class Merge : LoopInjection
{

    protected override bool MatchTypes(Type source, Type target)
    {
        return source.Name == target.Name;
    }

    protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp)
    {
        if (sp.GetValue(source) == null) return;
        base.SetValue(source, target, sp, tp);
    }

}
Другие вопросы по тегам