Как читать атрибуты сборки


в моей программе, как я могу прочитать свойства, установленные в AssemblyInfo.cs:

[assembly: AssemblyTitle("My Product")]
[assembly: AssemblyDescription("...")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Radeldudel inc.")]
[assembly: AssemblyProduct("My Product")]
[assembly: AssemblyCopyright("Copyright @ me 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Я хотел бы отобразить некоторые из этих значений для пользователя моей программы, поэтому я хотел бы знать, как загрузить их из основной программы и из компонентных сборок, которые я использую.

6 52

6 ответов:

Это достаточно легко. Вы должны использовать отражение. Вам нужен экземпляр сборки, представляющий сборку с атрибутами, которые вы хотите прочитать. Простой способ получить это сделать:

typeof(MyTypeInAssembly).Assembly

затем вы можете сделать это, например:

object[] attributes = assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);

AssemblyProductAttribute attribute = null;
if (attributes.Length > 0)
{
   attribute = attributes[0] as AssemblyProductAttribute;
}

ссылка attribute.Product теперь даст вам значение, которое вы передали атрибуту в AssemblyInfo.цезий. Конечно, если атрибут, который вы ищете, может встречаться более одного раза, вы можете получить несколько экземпляров в массив, возвращаемый GetCustomAttributes, но обычно это не проблема для атрибутов уровня сборки, таких как те, которые вы надеетесь получить.

Я создал этот метод расширения, который использует LINQ:

public static T GetAssemblyAttribute<T>(this System.Reflection.Assembly ass) where T :  Attribute
{
    object[] attributes = ass.GetCustomAttributes(typeof(T), false);
    if (attributes == null || attributes.Length == 0)
        return null;
    return attributes.OfType<T>().SingleOrDefault();
}

и тогда вы можете удобно использовать его так:

var attr = targetAssembly.GetAssemblyAttribute<AssemblyDescriptionAttribute>();
if(attr != null)
     Console.WriteLine("{0} Assembly Description:{1}", Environment.NewLine, attr.Description);

хорошо, возможно, немного устарел сейчас для первоначального вопроса, но я представлю это для дальнейшего использования в любом случае.

Если вы хотите сделать это изнутри самой сборки, то используйте следующее:

using System.Runtime.InteropServices;
using System.Reflection;

object[] customAttributes = this.GetType().Assembly.GetCustomAttributes(false);

затем вы можете перебирать все пользовательские атрибуты, чтобы найти тот (Ы), который вам нужен, например

foreach (object attribute in customAttributes)
{
  string assemblyGuid = string.Empty;    

  if (attribute.GetType() == typeof(GuidAttribute))
  {
    assemblyGuid = ((GuidAttribute) attribute).Value;
    break;
  }
}

хорошо, я пытался пройти через многие ресурсы, чтобы найти способ извлечения .dll файлы атрибутов Assembly.LoadFrom(path) . Но, к сожалению, я не смог найти хороший ресурс. И этот вопрос был самым лучшим результатом для поиска по c# get assembly attributes (по крайней мере, для меня), поэтому я подумал о том, чтобы поделиться своей работой.

я написал следующую простую консольную программу для извлечения атрибутов Генеральной Ассамблеи после многих часов борьбы. Здесь я предоставил код, так что любой может использовать его для дальнейшего ведения работы.

я использую CustomAttributes свойство для этого. Не стесняйтесь комментировать этот подход

код :

using System;
using System.Reflection;

namespace MetaGetter
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asembly = Assembly.LoadFrom("Path to assembly");

            foreach (CustomAttributeData atributedata in asembly.CustomAttributes)
            {
                Console.WriteLine(" Name : {0}",atributedata.AttributeType.Name);

                foreach (CustomAttributeTypedArgument argumentset in atributedata.ConstructorArguments)
                {
                    Console.WriteLine("   >> Value : {0} \n" ,argumentset.Value);
                }
            }

            Console.ReadKey();
        }
    }
}

Пример Вывода :

Name : AssemblyTitleAttribute
   >> Value : "My Product"

Я использую этот:

public static string Title
{
    get
    {
        return GetCustomAttribute<AssemblyTitleAttribute>(a => a.Title);
    }
}

для справки:

using System;
using System.Reflection;
using System.Runtime.CompilerServices;



namespace Extensions
{


    public static class AssemblyInfo
    {


        private static Assembly m_assembly;

        static AssemblyInfo()
        {
            m_assembly = Assembly.GetEntryAssembly();
        }


        public static void Configure(Assembly ass)
        {
            m_assembly = ass;
        }


        public static T GetCustomAttribute<T>() where T : Attribute
        {
            object[] customAttributes = m_assembly.GetCustomAttributes(typeof(T), false);
            if (customAttributes.Length != 0)
            {
                return (T)((object)customAttributes[0]);
            }
            return default(T);
        }

        public static string GetCustomAttribute<T>(Func<T, string> getProperty) where T : Attribute
        {
            T customAttribute = GetCustomAttribute<T>();
            if (customAttribute != null)
            {
                return getProperty(customAttribute);
            }
            return null;
        }

        public static int GetCustomAttribute<T>(Func<T, int> getProperty) where T : Attribute
        {
            T customAttribute = GetCustomAttribute<T>();
            if (customAttribute != null)
            {
                return getProperty(customAttribute);
            }
            return 0;
        }



        public static Version Version
        {
            get
            {
                return m_assembly.GetName().Version;
            }
        }


        public static string Title
        {
            get
            {
                return GetCustomAttribute<AssemblyTitleAttribute>(
                    delegate(AssemblyTitleAttribute a)
                    {
                        return a.Title;
                    }
                );
            }
        }

        public static string Description
        {
            get
            {
                return GetCustomAttribute<AssemblyDescriptionAttribute>(
                    delegate(AssemblyDescriptionAttribute a)
                    {
                        return a.Description;
                    }
                );
            }
        }


        public static string Product
        {
            get
            {
                return GetCustomAttribute<AssemblyProductAttribute>(
                    delegate(AssemblyProductAttribute a)
                    {
                        return a.Product;
                    }
                );
            }
        }


        public static string Copyright
        {
            get
            {
                return GetCustomAttribute<AssemblyCopyrightAttribute>(
                    delegate(AssemblyCopyrightAttribute a)
                    {
                        return a.Copyright;
                    }
                );
            }
        }



        public static string Company
        {
            get
            {
                return GetCustomAttribute<AssemblyCompanyAttribute>(
                    delegate(AssemblyCompanyAttribute a)
                    {
                        return a.Company;
                    }
                );
            }
        }


        public static string InformationalVersion
        {
            get
            {
                return GetCustomAttribute<AssemblyInformationalVersionAttribute>(
                    delegate(AssemblyInformationalVersionAttribute a)
                    {
                        return a.InformationalVersion;
                    }
                );
            }
        }



        public static int ProductId
        {
            get
            {
                return GetCustomAttribute<AssemblyProductIdAttribute>(
                    delegate(AssemblyProductIdAttribute a)
                    {
                        return a.ProductId;
                    }
                );
            }
        }


        public static string Location
        {
            get
            {
                return m_assembly.Location;
            }
        }

    }

}

мне лично очень нравится реализация Лэнс Ларсен и его статический AssemblyInfo класс.

один в основном вставляет класс в свою сборку (я обычно использую уже существующий AssemblyInfo.cs-файл, как он соответствует Соглашению об именах)

код для вставки:

internal static class AssemblyInfo
{
    public static string Company { get { return GetExecutingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company); } }
    public static string Product { get { return GetExecutingAssemblyAttribute<AssemblyProductAttribute>(a => a.Product); } }
    public static string Copyright { get { return GetExecutingAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright); } }
    public static string Trademark { get { return GetExecutingAssemblyAttribute<AssemblyTrademarkAttribute>(a => a.Trademark); } }
    public static string Title { get { return GetExecutingAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title); } }
    public static string Description { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
    public static string Configuration { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
    public static string FileVersion { get { return GetExecutingAssemblyAttribute<AssemblyFileVersionAttribute>(a => a.Version); } }

    public static Version Version { get { return Assembly.GetExecutingAssembly().GetName().Version; } }
    public static string VersionFull { get { return Version.ToString(); } }
    public static string VersionMajor { get { return Version.Major.ToString(); } }
    public static string VersionMinor { get { return Version.Minor.ToString(); } }
    public static string VersionBuild { get { return Version.Build.ToString(); } }
    public static string VersionRevision { get { return Version.Revision.ToString(); } }

    private static string GetExecutingAssemblyAttribute<T>(Func<T, string> value) where T : Attribute
    {
        T attribute = (T)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(T));
        return value.Invoke(attribute);
    }
}

добавить с помощью System; в верхней части файла, и вы хорошо идти.

для моих приложений я использую этот класс для установки / получения / работы с моими локальными пользователями настройки с помощью:

internal class ApplicationData
{

    DirectoryInfo roamingDataFolder;
    DirectoryInfo localDataFolder;
    DirectoryInfo appDataFolder;

    public ApplicationData()
    {
        appDataFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AssemblyInfo.Product,"Data"));
        roamingDataFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),AssemblyInfo.Product));
        localDataFolder   = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AssemblyInfo.Product));

        if (!roamingDataFolder.Exists)            
            roamingDataFolder.Create();

        if (!localDataFolder.Exists)
            localDataFolder.Create();
        if (!appDataFolder.Exists)
            appDataFolder.Create();

    }

    /// <summary>
    /// Gets the roaming application folder location.
    /// </summary>
    /// <value>The roaming data directory.</value>
    public DirectoryInfo RoamingDataFolder => roamingDataFolder;


    /// <summary>
    /// Gets the local application folder location.
    /// </summary>
    /// <value>The local data directory.</value>
    public DirectoryInfo LocalDataFolder => localDataFolder;

    /// <summary>
    /// Gets the local data folder location.
    /// </summary>
    /// <value>The local data directory.</value>
    public DirectoryInfo AppDataFolder => appDataFolder;
}

посмотрите на сайт Larsens (MVP), у него есть классные вещи, чтобы черпать вдохновение.