Lance Larsen - .NET Architect Madison Wisconsin

Reading Values from AssemblyInfo.cs

So if you haven’t looked – in VisualStudio projects under the “Properties” folder – there is a file called “AssemblyInfo.cs” – it contains many useful assembly attributes for your project including AssemblyTitle, AssemblyCompany, AssemblyCopyright, AssemblyVersion, etc.

My goal was to make a simple and elegant static class to retrieve these values – on top of that wanted to be able to retrieve the values within another project ( class library ) from the calling project, ie. what is the AssemblyTitle that is calling this class library.  I was specifically doing this for logging purposes – wanting to capture the project and version.  Accomplished both as follows…

How to get the values…
.

   1:  string company = ApplicationInfo.Company;
   2:  string product = ApplicationInfo.Product;
   3:  string copyright = ApplicationInfo.Copyright;
   4:  string trademark = ApplicationInfo.Trademark;
   5:  string title = ApplicationInfo.Title;
   6:  string description = ApplicationInfo.Description;
   7:  string configuration = ApplicationInfo.Configuration;
   8:  string fileversion = ApplicationInfo.FileVersion;
   9:  Version version = ApplicationInfo.Version;
  10:  string versionFull = ApplicationInfo.VersionFull;
  11:  string versionMajor = ApplicationInfo.VersionMajor;
  12:  string versionMinor = ApplicationInfo.VersionMinor;
  13:  string versionBuild = ApplicationInfo.VersionBuild;
  14:  string versionRevision = ApplicationInfo.VersionRevision;

 

Code that makes it possible… ( Updated 4/4/2013 )
.

   1:  /// <summary>
   2:  /// Gets the values from the AssemblyInfo.cs file for the current executing assembly
   3:  /// </summary>
   4:  /// <example>        
   5:  /// string company = AssemblyInfo.Company;
   6:  /// string product = AssemblyInfo.Product;
   7:  /// string copyright = AssemblyInfo.Copyright;
   8:  /// string trademark = AssemblyInfo.Trademark;
   9:  /// string title = AssemblyInfo.Title;
  10:  /// string description = AssemblyInfo.Description;
  11:  /// string configuration = AssemblyInfo.Configuration;
  12:  /// string fileversion = AssemblyInfo.FileVersion;
  13:  /// Version version = AssemblyInfo.Version;
  14:  /// string versionFull = AssemblyInfo.VersionFull;
  15:  /// string versionMajor = AssemblyInfo.VersionMajor;
  16:  /// string versionMinor = AssemblyInfo.VersionMinor;
  17:  /// string versionBuild = AssemblyInfo.VersionBuild;
  18:  /// string versionRevision = AssemblyInfo.VersionRevision;
  19:  /// </example>
  20:  static public class AssemblyInfo
  21:  {
  22:      public static string Company { get { return GetExecutingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company); } }
  23:      public static string Product { get { return GetExecutingAssemblyAttribute<AssemblyProductAttribute>(a => a.Product); } }
  24:      public static string Copyright { get { return GetExecutingAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright); } }
  25:      public static string Trademark { get { return GetExecutingAssemblyAttribute<AssemblyTrademarkAttribute>(a => a.Trademark); } }
  26:      public static string Title { get { return GetExecutingAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title); } }
  27:      public static string Description { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
  28:      public static string Configuration { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
  29:      public static string FileVersion { get { return GetExecutingAssemblyAttribute<AssemblyFileVersionAttribute>(a => a.Version); } }
  30:   
  31:      public static Version Version { get { return Assembly.GetExecutingAssembly().GetName().Version; } }
  32:      public static string VersionFull { get { return Version.ToString(); } }
  33:      public static string VersionMajor { get { return Version.Major.ToString(); } }
  34:      public static string VersionMinor { get { return Version.Minor.ToString(); } }
  35:      public static string VersionBuild { get { return Version.Build.ToString(); } }
  36:      public static string VersionRevision { get { return Version.Revision.ToString(); } }
  37:   
  38:      private static string GetExecutingAssemblyAttribute<T>(Func<T, string> value) where T : Attribute
  39:      {
  40:          T attribute = (T)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(T));
  41:          return value.Invoke(attribute);
  42:      }
  43:  }
  44:   
  45:   
  46:  /// <summary>
  47:  /// Gets the values from the AssemblyInfo.cs file for the previous assembly
  48:  /// </summary>
  49:  /// <example>
  50:  /// AssemblyInfoCalling assembly = new AssemblyInfoCalling();
  51:  /// string company1 = assembly.Company;
  52:  /// string product1 = assembly.Product;
  53:  /// string copyright1 = assembly.Copyright;
  54:  /// string trademark1 = assembly.Trademark;
  55:  /// string title1 = assembly.Title;
  56:  /// string description1 = assembly.Description;
  57:  /// string configuration1 = assembly.Configuration;
  58:  /// string fileversion1 = assembly.FileVersion;
  59:  /// Version version1 = assembly.Version;
  60:  /// string versionFull1 = assembly.VersionFull;
  61:  /// string versionMajor1 = assembly.VersionMajor;
  62:  /// string versionMinor1 = assembly.VersionMinor;
  63:  /// string versionBuild1 = assembly.VersionBuild;
  64:  /// string versionRevision1 = assembly.VersionRevision;
  65:  /// </example>
  66:  public class AssemblyInfoCalling
  67:  {
  68:      /// <summary>
  69:      /// Initializes a new instance of the <see cref="AssemblyInfoCalling"/> class.
  70:      /// </summary>
  71:      /// <param name="traceLevel">The trace level needed to get correct assembly 
  72:      /// - will need to adjust based on where you put these classes in your project(s).</param>
  73:      public AssemblyInfoCalling(int traceLevel = 4)
  74:      {
  75:          //----------------------------------------------------------------------
  76:          // Default to "3" as the number of levels back in the stack trace to get the 
  77:          //  correct assembly for "calling" assembly
  78:          //----------------------------------------------------------------------
  79:          StackTraceLevel = traceLevel;
  80:      }
  81:   
  82:      //----------------------------------------------------------------------
  83:      // Standard assembly attributes
  84:      //----------------------------------------------------------------------
  85:      public string Company { get { return GetCallingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company); } }
  86:      public string Product { get { return GetCallingAssemblyAttribute<AssemblyProductAttribute>(a => a.Product); } }
  87:      public string Copyright { get { return GetCallingAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright); } }
  88:      public string Trademark { get { return GetCallingAssemblyAttribute<AssemblyTrademarkAttribute>(a => a.Trademark); } }
  89:      public string Title { get { return GetCallingAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title); } }
  90:      public string Description { get { return GetCallingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
  91:      public string Configuration { get { return GetCallingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
  92:      public string FileVersion { get { return GetCallingAssemblyAttribute<AssemblyFileVersionAttribute>(a => a.Version); } }
  93:   
  94:      //----------------------------------------------------------------------
  95:      // Version attributes
  96:      //----------------------------------------------------------------------
  97:      public static Version Version
  98:      {
  99:          get
 100:          {
 101:              //----------------------------------------------------------------------
 102:              // Get the assembly, return empty if null
 103:              //----------------------------------------------------------------------
 104:              Assembly assembly = GetAssembly(StackTraceLevel);
 105:              return assembly == null ? new Version() : assembly.GetName().Version;
 106:          }
 107:      }
 108:      public string VersionFull { get { return Version.ToString(); } }
 109:      public string VersionMajor { get { return Version.Major.ToString(); } }
 110:      public string VersionMinor { get { return Version.Minor.ToString(); } }
 111:      public string VersionBuild { get { return Version.Build.ToString(); } }
 112:      public string VersionRevision { get { return Version.Revision.ToString(); } }
 113:   
 114:      //----------------------------------------------------------------------
 115:      // Set how deep in the stack trace we're looking - allows for customized changes
 116:      //----------------------------------------------------------------------
 117:      public static int StackTraceLevel { get; set; }
 118:   
 119:      //----------------------------------------------------------------------
 120:      // Custom Attributes
 121:      //----------------------------------------------------------------------
 122:      public string Location 
 123:      { 
 124:          get
 125:          {
 126:              try
 127:              {
 128:                  return GetCallingAssemblyAttribute<AssemblyLocationAttribute>(a => a.Value);
 129:              }
 130:              catch (NullReferenceException)
 131:              {
 132:                  return string.Empty;
 133:              }
 134:              
 135:          } 
 136:      }
 137:   
 138:      /// <summary>
 139:      /// Gets the calling assembly attribute.
 140:      /// </summary>
 141:      /// <typeparam name="T"></typeparam>
 142:      /// <param name="value">The value.</param>
 143:      /// <example>return GetCallingAssemblyAttribute&lt;AssemblyCompanyAttribute&gt;(a => a.Company);</example>
 144:      /// <returns></returns>
 145:      private string GetCallingAssemblyAttribute<T>(Func<T, string> value) where T : Attribute
 146:      {
 147:          //----------------------------------------------------------------------
 148:          // Get the assembly, return empty if null
 149:          //----------------------------------------------------------------------
 150:          Assembly assembly = GetAssembly(StackTraceLevel);
 151:          if (assembly == null) return string.Empty;
 152:   
 153:          //----------------------------------------------------------------------
 154:          // Get the attribute value
 155:          //----------------------------------------------------------------------
 156:          T attribute = (T) Attribute.GetCustomAttribute(assembly, typeof (T));
 157:          return value.Invoke(attribute);
 158:      }
 159:   
 160:      /// <summary>
 161:      /// Go through the stack and gets the assembly
 162:      /// </summary>
 163:      /// <param name="stackTraceLevel">The stack trace level.</param>
 164:      /// <returns></returns>
 165:      private static Assembly GetAssembly(int stackTraceLevel)
 166:      {
 167:          //----------------------------------------------------------------------
 168:          // Get the stack frame, returning null if none
 169:          //----------------------------------------------------------------------
 170:          StackTrace stackTrace = new StackTrace();
 171:          StackFrame[] stackFrames = stackTrace.GetFrames();
 172:          if (stackFrames == null) return null;
 173:   
 174:          //----------------------------------------------------------------------
 175:          // Get the declaring type from the associated stack frame, returning null if nonw
 176:          //----------------------------------------------------------------------
 177:          var declaringType = stackFrames[stackTraceLevel].GetMethod().DeclaringType;
 178:          if (declaringType == null) return null;
 179:   
 180:          //----------------------------------------------------------------------
 181:          // Return the assembly
 182:          //----------------------------------------------------------------------
 183:          var assembly = declaringType.Assembly;
 184:          return assembly;
 185:      }
 186:  }
 
Comments

string company = ApplicationInfo.Company; // Should this be updated to “AssemblyInfo.Company” ?

Some suggestions. :-) Remove the row number count in the example, those numbers make it hard to copy the code. Or provide a gist, or even make this into a Nuget package.

Also in the GetAssembly() add this code, for some reason in a test project I have, the default worked in one call but was over in another, so a safety check would be good:

if (stackTraceLevel >= stackFrames.Count())
stackTraceLevel = stackFrames.Count() – 1;

Thanks.

Leave a Reply to Shenan