lwl1569  

参考资料:C#中Dictionary的用法
实例:建立字典服务,字典为string-->List
1、建立一个类,继承List,用来做字典的映射类

    public class PropertyMappingValue
    {
        public IEnumerable<string> DestinationProperties { get; private set; }
        public PropertyMappingValue(IEnumerable<string> destinationProperties)
        {
            DestinationProperties = destinationProperties;
        }
    }

2、建立一个接口类PropertyMapping<TSource, TDestination>作为映射类,其表达从TSource到TDestination的映射,该映射包含一个字典规则Dictionary<string, PropertyMappingValue>,并在构造函数中用一个字典规则初始化该映射

    public interface IPropertyMapping
    {
    }
    public class PropertyMapping<TSource, TDestination> : IPropertyMapping
    {
        public Dictionary<string, PropertyMappingValue> _mappingDictionary { get; set; }

        public PropertyMapping(Dictionary<string, PropertyMappingValue> mappingDictionary)
        {
            _mappingDictionary = mappingDictionary;
        }
    }

3、建一个接口类(本例中将字典的初始化与服务初始化放到了一起,也可以分开)

    public interface IPropertyMappingService
    {
        Dictionary<string, PropertyMappingValue> GetPropertyMapping<TSource, TDestination>();
        bool IsMappingExists<TSource, TDestination>(string fields);
        bool IsPropertiesExists<T>(string fields);
    }
    public class PropertyMappingService : IPropertyMappingService
    {
        private Dictionary<string, PropertyMappingValue> _touristRoutePropertyMapping = new Dictionary<string, PropertyMappingValue>(StringComparer.OrdinalIgnoreCase)
           {
               { "Id", new PropertyMappingValue(new List<string>(){ "Id" }) },
               { "Title", new PropertyMappingValue(new List<string>(){ "Title" })},
               { "Rating", new PropertyMappingValue(new List<string>(){ "Rating" })},
               { "OriginalPrice", new PropertyMappingValue(new List<string>(){ "OriginalPrice" })},
           };

        private IList<IPropertyMapping> _propertyMappings = new List<IPropertyMapping>();

        public PropertyMappingService()
        {
            _propertyMappings.Add( new PropertyMapping<TouristRouteDto, TouristRoute>(_touristRoutePropertyMapping));
        }

        public Dictionary<string, PropertyMappingValue>
            GetPropertyMapping<TSource, TDestination>()
        {
            // 获得匹配的映射对象
            var matchingMapping =
                _propertyMappings.OfType<PropertyMapping<TSource, TDestination>>();//根据类型参数从IEnumerable集合中筛选出对应的元素

            if (matchingMapping.Count() == 1)
            {
                return matchingMapping.First()._mappingDictionary;
            }

            throw new Exception(
                $"Cannot find exact property mapping instance for <{typeof(TSource)},{typeof(TDestination)}");

        }

        public bool IsMappingExists<TSource, TDestination>(string fields)
        {
            var propertyMapping = GetPropertyMapping<TSource, TDestination>();

            if (string.IsNullOrWhiteSpace(fields))
            {
                return true;
            }

            //逗号来分隔字段字符串
            var fieldsAfterSplit = fields.Split(",");

            foreach (var field in fieldsAfterSplit)
            {
                // 去掉空格
                var trimmedField = field.Trim();
                // 获得属性名称字符串
                var indexOfFirstSpace = trimmedField.IndexOf(" ");
                var propertyName = indexOfFirstSpace == -1 ? trimmedField : trimmedField.Remove(indexOfFirstSpace);
                if (!propertyMapping.ContainsKey(propertyName))
                {
                    return false;
                }
            }
            return true;
        }

        public bool IsPropertiesExists<T>(string fields)
        {
            if (string.IsNullOrWhiteSpace(fields))
            {
                return true;
            }

            //逗号来分隔字段字符串
            var fieldsAfterSplit = fields.Split(',');

            foreach(var field in fieldsAfterSplit)
            {
                // 获得属性名称字符串
                var propertyName = field.Trim();

                var propertyInfo = typeof(T).GetProperty( propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance
                    );

                // 如果T中没找到对应的属性
                if(propertyInfo == null)
                {
                    return false;
                }
            }

            return true;
        }
    }

如果将初始化做成构造函数,如下:

    public class PropertyMappingService : IPropertyMappingService
    {
        private IList<IPropertyMapping> _propertyMappings = new List<IPropertyMapping>();

        public PropertyMappingService(params IPropertyMapping[] propertyMapping)
        {
            foreach(var property in propertyMapping)
                _propertyMappings.Add(property);
        }
  1. 注入服务
    services.AddTransient<IPropertyMappingService, PropertyMappingService>();

※此处存在疑惑,为何要用两个判断,一个判断是键中是否包含string,一个判断能否通过这个string得到属性,其本质相同,都是验证这个string是否在键中存在。

posted on 2021-09-29 09:47  lwl1569  阅读(266)  评论(0编辑  收藏  举报