如何使用[override modelmetadata]事件[动态]添加自定义属性? [英] How to add custom attributes [dynamically] using [override modelmetadata] event?

查看:81
本文介绍了如何使用[override modelmetadata]事件[动态]添加自定义属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的,



我想做一些奇怪的工作:

动态地向我的模型类添加属性< 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆