View Model 含驗證/顯示屬性(DataAnnotations),Business Model 為持久化實體。兩者高度相似卻需手動映射,架構繁瑣。
System.ComponentModel.DataAnnotations 提供 [MetadataType(typeof(ViewModel))] 標記 Business Model,指定外部元資料類別:
[MetadataType(typeof(Product_Metadata))]
public partial class Product { }
public class Product_Metadata
{
[Required] public string Name { get; set; }
[Range(1, 1000)] public decimal Price { get; set; }
}
若 Business Model 與 MetadataType 不在同一組件,partial class 無法跨組件擴展。需延遲註冊映射關係。
public static class TypeDescriptorHelper
{
static Hashtable hashtable = new Hashtable();
static ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
public static void RegisterMetadataType(Type type, Type metadataType)
{
locker.EnterWriteLock();
hashtable[type] = metadataType;
locker.ExitWriteLock();
}
public static ICustomTypeDescriptor Get(Type type)
{
locker.EnterReadLock();
var metadataType = hashtable[type] as Type;
ICustomTypeDescriptor descriptor = null;
if (metadataType != null)
descriptor = new AssociatedMetadataTypeTypeDescriptionProvider(type, metadataType).GetTypeDescriptor(type);
locker.ExitReadLock();
return descriptor;
}
}
應用啟動時呼叫 RegisterMetadataType 註冊映射,MVC 模型繫結器透過 GetTypeDescriptor 取得外部元資料,實現跨組件解耦。