it-swarm.com.de

So lesen Sie Assembly-Attribute

Wie kann ich in meinem Programm die in AssemblyInfo.cs festgelegten Eigenschaften lesen:

[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("")]

Ich möchte dem Benutzer meines Programms einige dieser Werte anzeigen. Daher möchte ich wissen, wie er vom Hauptprogramm und von den von mir verwendeten komponent-Baugruppen geladen wird.

55
Sam

Das ist einigermaßen einfach. Sie müssen Reflexion verwenden. Sie benötigen eine Assembly-Instanz, die die Assembly mit den Attributen darstellt, die Sie lesen möchten. Ein einfacher Weg, dies zu erreichen, ist zu tun:

typeof(MyTypeInAssembly).Assembly

Dann können Sie dies zum Beispiel tun:

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

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

Wenn Sie auf attribute.Product verweisen, erhalten Sie jetzt den Wert, den Sie an das Attribut in Ihrer AssemblyInfo.cs übergeben haben. Wenn das von Ihnen gesuchte Attribut mehr als einmal vorkommt, erhalten Sie möglicherweise mehrere Instanzen in dem von GetCustomAttributes zurückgegebenen Array. Dies ist jedoch normalerweise kein Problem für Attribute auf Assembly-Ebene wie die, die Sie abrufen möchten.

55
Jeff Yates

Ich habe diese Erweiterungsmethode erstellt, die Linq verwendet:

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();
}

und dann können Sie es bequem so verwenden:

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

Ok, vielleicht ein bisschen veraltet für die ursprüngliche Frage, aber ich werde dies sowieso für die Zukunft vorstellen.

Wenn Sie es von innerhalb der Assembly selbst ausführen möchten, verwenden Sie Folgendes:

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

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

Sie können dann alle benutzerdefinierten Attribute durchlaufen, um die gewünschten Attribute zu finden, z.

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

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

Okay, ich habe versucht, durch viele Ressourcen eine Methode zum Extrahieren von .dll-Attributen für eine Assembly.LoadFrom(path) zu suchen. Leider konnte ich keine gute Ressource finden. Und diese Frage war das beste Ergebnis für die Suche nach c# get Assembly attributes (zumindest für mich). Also dachte ich daran, meine Arbeit zu teilen.

Ich schrieb folgendes einfaches Konsolenprogramm, um nach vielen Stunden des Kampfes allgemeine Assembly-Attribute abzurufen. Hier habe ich den Code bereitgestellt, damit jeder ihn für weitere Nachschlagewerke verwenden kann. 

Ich benutze dafür die CustomAttributes-Eigenschaft. Fühlen Sie sich frei, diesen Ansatz zu kommentieren

Code:

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();
        }
    }
}

Beispielausgabe:

Name : AssemblyTitleAttribute
   >> Value : "My Product"
4

Ich benutze das:

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

als Referenz:

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;
            }
        }

    }

}
2
Stefan Steiger

Wenn Sie wissen, dass das von Ihnen gesuchte Attribut eindeutig ist, ist es viel einfacher, diese häufig übersehene statische Hilfsmethode der Attribute-Klasse zu verwenden:

var attribute = Attribute.GetCustomAttribute(Assembly, typeof(AssemblyTitleAttribute))

Dies ist einfacher, da Sie nicht mit Arrays herumspielen müssen oder sich um den inherit-Parameter kümmern müssen. Sie erhalten nur den einzelnen Attributwert direkt oder null, wenn keiner vorhanden ist.

1
glopes

Ich persönlich mag die Implementierung von Lance Larsen und seine statische AssemblyInfo-Klasse

Grundsätzlich fügt man die Klasse in seine Assembly ein (normalerweise verwende ich die bereits vorhandene AssemblyInfo.cs-Datei, da sie der Namenskonvention entspricht).

Der einzufügende Code lautet:

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);
    }
}

Sie fügen ein using System hinzu; zum Anfang der Datei und du kannst loslegen.

Für meine Anwendungen verwende ich diese Klasse, um Einstellungen für lokale Benutzer festzulegen/mit diesen Einstellungen zu arbeiten:

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;
}

Schau mal auf Larsens Website (MVP), er hat coole Sachen, aus denen er Inspiration ziehen kann.