Как читать атрибуты сборки
в моей программе, как я могу прочитать свойства, установленные в 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 ответов:
Это достаточно легко. Вы должны использовать отражение. Вам нужен экземпляр сборки, представляющий сборку с атрибутами, которые вы хотите прочитать. Простой способ получить это сделать:
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), у него есть классные вещи, чтобы черпать вдохновение.