如何使用[override modelmetadata]事件[动态]添加自定义属性? [英] How to add custom attributes [dynamically] using [override modelmetadata] event?
问题描述
亲爱的,
我想做一些奇怪的工作:
动态地向我的模型类添加属性< u>没有直接在模型类的每个属性上添加这些属性。
整个故事是:
我有一个使用Code首先使用域驱动设计的MVC项目,所以我有以下内容:
核心类:员工存在于DDD.Core项目中
模型类:EmployeeModel存在于DDDApp项目中[主应用程序]
现在,我希望Model类[EmployeeModel]具有核心类[Employee]的映射属性。
注意:
为了不破坏设计,我不应该在DDDApp中添加DDD.Core的引用。
我尝试了什么:
其实我在这方面取得了很大的进步: />
在 global.asax 文件中我已经加载了所有DDD.Core类
Dears,
I want to do some weird job which is:
adding attributes dynamically to my model class without adding these attributes directly on each property in the model class.
the whole story is:
I have an MVC project using Code first with domain driven design so i have the following:
Core Class : Employee exists in DDD.Core Project
Model Class : EmployeeModel exists in DDDApp Project [main App]
Now, i wants Model class [EmployeeModel] to have the mapped attributes of core class [Employee].
Note:
To not break down the design, i should not add reference of DDD.Core in DDDApp.
What I have tried:
Actually i made a good progress in that:
In global.asax File i have loaded all of the DDD.Core classes
string webRootPath = HttpContext.Current.Server.MapPath("~");
string docPath = Path.GetFullPath(Path.Combine(webRootPath, "..\\DDD.Core\\bin\\Debug\\DDD.Core.dll"));
Assembly DDDCore = Assembly.LoadFile(docPath);
Application["DDDCoreAssembly"] = DDDCore;
在我继承的 DataAnnotationsModelMetadataProvider类中,我做了以下代码:
In DataAnnotationsModelMetadataProvider class which i inherit, i did the following code:
public class MetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
//All DDD.Core Asembly which contains the core classes
Assembly DDDCoreAssembly = HttpContext.Current.Application["DDDCoreAssembly"] as Assembly;
if (containerType != null)
{
//Get the Core Class Employee for example.
Type coreModelType = DDDCoreAssembly.GetTypes().Single(x => x.Name == containerType.Name.Replace("Model", ""));
//Get Employee Class Property
MemberInfo coreClassProperty = coreModelType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (coreClassProperty != null)
{
//Get All Attributes of CoreClass Property
object[] coreClassPropertyAttributes = coreClassProperty.GetCustomAttributes(true);
foreach (var item in coreClassPropertyAttributes)
{
if (item.GetType() == typeof(RequiredAttribute))
{
RequiredAttribute ra = new RequiredAttribute();
//#########################
//Now, I can't add this attribute to the property dynamically (Any Ideas)
//#########################
}
else if (item.GetType() == typeof(StringLengthAttribute))
{
StringLengthAttribute sla = new StringLengthAttribute(((System.ComponentModel.DataAnnotations.StringLengthAttribute)(item)).MaximumLength);
sla.MinimumLength = ((System.ComponentModel.DataAnnotations.StringLengthAttribute)(item)).MinimumLength;
sla.ErrorMessage = "el length ya ged3an";
//#########################
//Now, I can't add this attribute to the property dynamically (Any Ideas)
//#########################
}
else if (item.GetType() == typeof(RegularExpressionAttribute))
{
}
}
}
}
var result = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
//*************************
//This Part of Code is used for localization
//*************************
if (string.IsNullOrEmpty(result.DisplayName) && containerType != null && propertyName != null)
{
var keyForDisplayValue = string.Format("{0}_{1}", containerType.Name, propertyName);
var translatedValue = MCITemplateV4.Properties.Resources.ResourceManager.GetObject(keyForDisplayValue) as string;
if (!string.IsNullOrEmpty(translatedValue))
{
result.DisplayName = translatedValue;
}
}
return result;
}
}
我无法添加最后一步,即添加属性动态属性?
那么任何人都能帮助我吗?!!!!
I just can't add the final step which is adding attributes to the properties dynamically?
So Can any one help me with that?!!!!
推荐答案
听起来不可能 - 至少我想不出办法来做...
无论如何有些想法:
你的意思是你不能添加对你的核心DLL的引用?无论如何,当你反思时,你会给它一个硬编码参考(更好的依赖),不是吗?
你为什么不使用任何标准模式出于这种问题?
*创建一个包装器并在那里添加属性(如果可以的话,将比向原始类添加属性的代码更多)
*使用一些二进制重写器和AOP(在本机.NET中尚未提供,但我听说过一些第三方产品(代码签约等))
*生成具有属性的类以节省打字工作(我认为这是大多数工具所做的,使用T4来定义代码生成器)
*编写一些VS(IDE)扩展来添加或(预)处理模型文件并添加属性编译。
*如果只是你正在使用这些属性(我不认为是这种情况,你似乎计划使用验证器)你可以为你的模型类型操作TypeDescriptor(其中属性可以动态添加AFAI K)
所以也许你可以找到另一种方式(我曾经用T4为整个模型类解决了类似的问题)
祝你的项目好运!
Sounds impossible - at least I can't think about a way to do it...
Anyway some thoughts:
What do you mean you can't add a reference to your core dll? But you crate a "hardcoded" reference (better dependency) to it anyway when reflecting, don't you?
Why don't you use any of the "Standard Patterns" for this kind of Problem?
* create a wrapper and add the attributes there (would be more code than adding the attributes to the original classes, if you can)
* Use some binary rewriter and AOP (not yet available in native .NET, but I heard about some 3rd Party products (codecontracts etc.))
* Generate the classes with the attributes to save typing work (I think this is what most Tools do, use T4 to define the code Generator)
* Write some VS (IDE) Extension to add or (pre-)process the model files and add the attributes before compilation.
* If only you are consuming the attributes (I don't think this is the case, it seems you plan use by a validator) you can manipulate the TypeDescriptor for your model types (where Attributes can be added dynamically AFAIK)
so maybe you can find another way (I did once solve a similar problem with T4 generated templates for the whole model class)
Good luck with your Project!
这篇关于如何使用[override modelmetadata]事件[动态]添加自定义属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!