代码之家  ›  专栏  ›  技术社区  ›  Edward Tanguay

如何使C识别外部.dll中的自定义属性?

  •  2
  • Edward Tanguay  · 技术社区  · 16 年前

    下面的代码成功识别 内部的 用我的自定义“module”属性修饰的类,我这样加载程序集:

    Assembly assembly = Assembly.GetExecutingAssembly();
    

    但是,当我加载 外部模块 并查看它的类,它在外部程序集中找到类,但是 无法识别自定义属性 :

    Assembly assembly = Assembly.LoadFrom(@"c:\tests\modules\CustomModules.dll");
    

    我必须指定什么,以便C识别外部.dll中的自定义属性,与内部类相同?

    下面是成功运行并识别用我的“module”属性修饰的内部类的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    
    namespace DynamicAssembly2
    {
        class Program
        {
            static void Main(string[] args)
            {
                var modules = from t in GetModules()
                               select t;
                foreach (var module in modules)
                {
                    ModuleAttribute[] moduleAttributes = GetModuleAttributes(module);
                    Console.WriteLine(module.FullName);
                    foreach (var moduleAttribute in moduleAttributes)
                    {
                        Console.WriteLine(moduleAttribute.Description);
                    }
                }
                Console.ReadLine();
            }
    
            public static IEnumerable<Type> GetModules()
            {
                //Assembly assembly = Assembly.LoadFrom(@"c:\tests\modules\CustomModules.dll");
                Assembly assembly = Assembly.GetExecutingAssembly();
    
                return GetAssemblyClasses(assembly)
                    .Where((Type type) => {return IsAModule(type);});
            }
    
            public static IEnumerable<Type> GetAssemblyClasses(Assembly assembly)
            {
                foreach (Type type in assembly.GetTypes())
                {
                    Console.WriteLine(type.FullName);
                    yield return type;
                }
            }
    
            public static bool IsAModule(Type type)
            {
                return GetModuleAttribute(type) != null;
            }
    
            public static ModuleAttribute GetModuleAttribute(Type type)
            {
                ModuleAttribute[] moduleAttributes = GetModuleAttributes(type);
                Console.WriteLine(moduleAttributes.Length);
                if (moduleAttributes != null && moduleAttributes.Length != 0)
                    return moduleAttributes[0];
                return null;
            }
    
            public static ModuleAttribute[] GetModuleAttributes(Type type)
            {
                return (ModuleAttribute[])type.GetCustomAttributes(typeof(ModuleAttribute), true);
            }
    
        }
    }
    

    这是我的自定义mdoule属性:

    using System;
    
    namespace DynamicAssembly2
    {
        [AttributeUsage(AttributeTargets.Class)]
        public class ModuleAttribute : Attribute
        {
            public string Description { get; set; }
        }
    }
    

    以下是自定义模块:

    namespace DynamicAssembly2
    {
        [Module(Description="This is the main customer class.")]
        class Customers
        {
        }
    }
    
    4 回复  |  直到 14 年前
        1
  •  4
  •   Rob Walker    16 年前

    您在程序集中定义了多少moduleAttribute类实例?

    看起来你有一个动态内存2和一个自定义模块…在这种情况下,它们是不同的类型。

    dynamicassembly2中的代码应该使用在custommodules中定义的属性类(或者两个程序集都应该从第三个程序集中加载属性)。

        2
  •  2
  •   Marc Gravell    16 年前

    我很确定它没有区别…你确定你在要求正确的属性吗?只要两个项目都引用 相同的 ModuleAttribute 然后 typeof(ModuleAttribute) 应该工作。否则,您需要先找到 Type 你想要的属性(从 Assembly.GetType() ,并在呼叫时使用 GetCustomAttributes .

        3
  •  1
  •   edosoft    16 年前

    阿罗哈

    我已经测试了您的代码,但无法编译它,因为类型 ModuleAttribute 必须在主程序和外部dll中都知道。我假设没有涉及到参考文献。

    我确实是通过介绍一个推荐人来实现的。

    这是班级。此程序集包含动态引用

    using System;    
    
    namespace DynamicAssembly2
    {
        [DynamicAssembly.Module(Description = "This is the main customer class.")]
        public class Customers
        {
        }
    }
    

    下面是动态代码:

    using System.Reflection;
    
    namespace DynamicAssembly
    {
        [AttributeUsage(AttributeTargets.Class)]
        public class ModuleAttribute : Attribute
        {
            public string Description { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var modules = from t in GetModules()
                              select t;
                foreach (var module in modules)
                {
                    ModuleAttribute[] moduleAttributes = GetModuleAttributes(module);
                    Console.WriteLine(module.FullName);
                    foreach (var moduleAttribute in moduleAttributes)
                    {
                        Console.WriteLine(moduleAttribute.Description);
                    }
                }
                Console.ReadLine();
            }
    
            public static IEnumerable<Type> GetModules()
            {
                Assembly assembly = Assembly.LoadFrom(@"C:\Temp\ClassLibrary1\bin\Debug\ClassLibrary1.dll");
    
                return GetAssemblyClasses(assembly)
                    .Where((Type type) => { return IsAModule(type); });
            }
    
            public static IEnumerable<Type> GetAssemblyClasses(Assembly assembly)
            {
                foreach (Type type in assembly.GetTypes())
                {
                    yield return type;
                }
            }
    
            public static bool IsAModule(Type type)
            {
                return GetModuleAttribute(type) != null;
            }
    
            public static ModuleAttribute GetModuleAttribute(Type type)
            {
                ModuleAttribute[] moduleAttributes = GetModuleAttributes(type);
                Console.WriteLine(moduleAttributes.Length);
                if (moduleAttributes != null && moduleAttributes.Length != 0)
                    return moduleAttributes[0];
                return null;
            }
    
            public static ModuleAttribute[] GetModuleAttributes(Type type)
            {
                return (ModuleAttribute[])type.GetCustomAttributes(typeof(ModuleAttribute), true);
            }
    
        }
    }
    
        4
  •  0
  •   Mark Lakata    14 年前

    我也有同样的问题。如果属性是在一个内部的*cs中定义的,我可以得到该属性,但是如果它是在一个外部的dll中定义的,我在查询它时只会得到空值(没有错误),但是也没有链接器错误。

    显然,在一个dll中定义的自定义属性和在本地代码(*cs)中定义的相同自定义属性将很高兴地编译为一个应用程序,而不会出现关于多个定义的任何警告(名称空间是相同的)。我去掉了本地代码(*cs),修复了引用,它工作了。