2012-03-26 8 views
1

私はValue Injectorを使用してASP.NET MVCプロジェクトのマッピングを管理しています。ドメインは、dbの標準メトリック単位として格納された長さ測定の概念を持ち、サービス層までの小数点の値として公開されています。Value Injectorを使用してターゲットプロパティの属性を検査するにはどうすればよいですか?

UIの長さのレンダリングは、測定対象、ユーザーカルチャなどによって異なります。ビューモデルタイプのプロパティに関する属性で示されるコンテキストについてのヒント。 Value Injectorを使用して、注入時にこれらの属性を検査し、ソースプロパティが10進数で、ターゲットプロパティが上記の属性の1つで飾られた文字列である場合、適切にフォーマットされた文字列を表示します。

namespace TargetValueAttributes 
{ 
    public class Person 
    { 
     public decimal Height { get; set; } 
     public decimal Waist { get; set; } 
    } 

    public class PersonViewModel 
    { 
     [LengthLocalizationHint(LengthType.ImperialFeetAndInches)] 
     [LengthLocalizationHint(LengthType.MetricMeters)] 
     public string Height { get; set; } 

     [LengthLocalizationHint(LengthType.ImperialInches)] 
     [LengthLocalizationHint(LengthType.MetricCentimeters)] 
     public string Waist { get; set; } 
    } 

    public enum LengthType 
    { 
     MetricMeters, 
     MetricCentimeters, 
     ImperialFeetAndInches, 
     ImperialInches 
    } 

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 
    public class LengthLocalizationHintAttribute : Attribute 
    { 
     public LengthType SuggestedLengthType { get; set; } 

     public LengthLocalizationHintAttribute(LengthType suggestedLengthType) 
     { 
      SuggestedLengthType = suggestedLengthType; 
     } 
    } 

    public class LengthLocalizationInjection : FlatLoopValueInjection<decimal, string> 
    { 
     protected override void Inject(object source, object target) 
     { 
      base.Inject(source, target);//I want to be able to inspect the attributes on the target value here 
     } 
     protected override string SetValue(decimal sourceValues) 
     { 
      var derivedLengthType = LengthType.MetricMeters;//here would be even better 
      return sourceValues.ToLength(derivedLengthType);//this is an extension method that does the conversion to whatever the user needs to see 
     } 
    } 

答えて

1

ソースを掘り下げた後、私は「FlatLoopValueInjection」の実装に基づいた解決策を思いつきました。

public abstract class LocalizationStringInjection<TSource, TTarget> : LoopValueInjectionBase 
{ 
    public ILocalizationContext LocalizationContext { get; set; } 

    protected LocalizationStringInjection(ILocalizationContext localizationContext) 
    { 
     LocalizationContext = localizationContext; 
    } 

    protected virtual bool TypesMatch(Type sourceType, Type targetType) 
    { 
     return sourceType == typeof(TSource) && targetType == typeof(TTarget); 
    } 

    protected override void Inject(object source, object target) 
    { 
     foreach (PropertyDescriptor targetPropertyDescriptor in target.GetProps()) 
     { 
      var t1 = targetPropertyDescriptor; 
      var es = UberFlatter.Flat(targetPropertyDescriptor.Name, source, type => TypesMatch(type, t1.PropertyType)); 

      var endpoint = es.FirstOrDefault(); 
      if (endpoint == null) continue; 

      var sourceValue = endpoint.Property.GetValue(endpoint.Component) is TSource ? (TSource)endpoint.Property.GetValue(endpoint.Component) : default(TSource); 

      if (AllowSetValue(sourceValue)) 
       targetPropertyDescriptor.SetValue(target, SetValue(sourceValue, targetPropertyDescriptor)); 
     } 
    } 

    protected abstract TTarget SetValue(TSource sourcePropertyValue, PropertyDescriptor targetPropertyDescriptor); 
} 

public class LengthLocalizationStringInjection : LocalizationStringInjection<decimal, string> 
{ 
    public LengthLocalizationStringInjection(ILocalizationContext localizationContext) : base(localizationContext) { } 

    protected override string SetValue(decimal sourceValue, PropertyDescriptor targetPropertyDescriptor) 
    { 
     var lengthHints = targetPropertyDescriptor.Attributes.Cast<object>().Where(attribute => attribute.GetType() == typeof(LengthLocalizationAttribute)).Cast<LengthLocalizationAttribute>().ToList(); 
     return lengthHints.Any() ? sourceValue.ToLength(lengthHints.First(l => l.SuggestedLengthType == LocalizationContext.Length).SuggestedLengthType) : sourceValue.ToLength(default(LengthType)); 
    } 
} 

これは私の目的には十分であることが証明されています。私は、そのアイデアをあいまいにしないように、いくつかの参照された型を除外しました。

関連する問題