private static ViewModelMetadata InitializeViewModelMetaData(Type viewModelType)
{
if (_metaData.ContainsKey(viewModelType))
{
return _metaData[viewModelType];
}
var properties = new List<PropertyInfo>();
var bindingFlags = BindingFlagsHelper.GetFinalBindingFlags(true, false, true);
properties.AddRange(viewModelType.GetPropertiesEx(bindingFlags));
var modelObjectsInfo = new Dictionary<string, ModelInfo>();
var viewModelToModelMap = new Dictionary<string, ViewModelToModelMapping>();
var validationSummaries = new Dictionary<string, ValidationToViewModelAttribute>();
var modelNames = (from propertyInfo in properties
where propertyInfo.IsDecoratedWithAttribute<ModelAttribute>()
select propertyInfo.Name).ToList();
foreach (var propertyInfo in properties)
{
#region Model attributes
var modelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ModelAttribute), true) as ModelAttribute;
if (modelAttribute != null)
{
modelObjectsInfo.Add(propertyInfo.Name, new ModelInfo(propertyInfo.Name, modelAttribute));
}
#endregion
#region ViewModelToModel attributes
var viewModelToModelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ViewModelToModelAttribute), true) as ViewModelToModelAttribute;
if (viewModelToModelAttribute != null)
{
if (string.IsNullOrEmpty(viewModelToModelAttribute.Property))
{
// Assume the property name in the model is the same as in the view model
viewModelToModelAttribute.Property = propertyInfo.Name;
}
if (string.IsNullOrWhiteSpace(viewModelToModelAttribute.Model))
{
Log.Debug("ViewToViewModel is missing the Model name, searching for the right model automatically");
if (modelNames.Count != 1)
{
throw Log.ErrorAndCreateException<InvalidOperationException>("It is only possible to automatically select the right model if there is 1 model. There are '{0}' models, so please specify the model name explicitly.", modelNames.Count);
}
viewModelToModelAttribute.Model = modelNames[0];
}
if (!viewModelToModelMap.ContainsKey(propertyInfo.Name))
{
viewModelToModelMap.Add(propertyInfo.Name, new ViewModelToModelMapping(propertyInfo.Name, viewModelToModelAttribute));
}
}
#endregion
#region ValidationToViewModel attributes
var validationToViewModelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ValidationToViewModelAttribute), true) as ValidationToViewModelAttribute;
if (validationToViewModelAttribute != null)
{
if (propertyInfo.PropertyType != typeof(IValidationSummary))
{
throw Log.ErrorAndCreateException<InvalidOperationException>("A property decorated with the ValidationToViewModel attribute must be of type IValidationSummary, but '{0}' is not", propertyInfo.Name);
}
validationSummaries.Add(propertyInfo.Name, validationToViewModelAttribute);
Log.Debug("Registered property '{0}' as validation summary", propertyInfo.Name);
}
#endregion
}
_metaData.Add(viewModelType, new ViewModelMetadata(viewModelType, modelObjectsInfo, viewModelToModelMap, validationSummaries));
return _metaData[viewModelType];
}