I <3 Steve McConnell*
Coding Horror
programming and human factors
by Jeff Atwood

Nov 28, 2004

Custom AssemblyInfo Attributes

To complement my previous post bemoaning the lack of respect for AssemblyInfo, I wanted to illustrate just how easy it is to add a few custom attributes to our AssemblyInfo file:

Imports System
Imports System.Reflection

<Assembly: AssemblyTitle("ASPUnhandledException")> 
<Assembly: AssemblyDescription("ASP.NET unhandled exception handling library")> 
<Assembly: AssemblyCompany("Atwood Heavy Industries")> 
<Assembly: AssemblyCompanyEmail("jatwood@atwoodheavyindustries.com")> 
<Assembly: AssemblyCompanyUrl("http://www.atwoodheavyindustries.com")>
<Assembly: AssemblyProduct("Exception Handling Framework")> 
<Assembly: AssemblyCopyright(" 2004, Atwood Heavy Industries")> 
<Assembly: AssemblyTrademark("All Rights Reserved")> 
<Assembly: CLSCompliant(True)> 

<Assembly: AssemblyVersion("2.1.*")> 

To get the custom attributes AssemblyCompanyUrl and AssemblyCompanyEmail working, just add these two classes to your solution:

<AttributeUsage(AttributeTargets.Assembly)> _
Public Class AssemblyCompanyEmailAttribute
    Inherits System.Attribute

    Private _strCompanyEmail As String

    Public Sub New(ByVal email As String)
        _strCompanyEmail = email
    End Sub

    Public Overridable ReadOnly Property CompanyEmail() As String
        Get
            Return _strCompanyEmail
        End Get
    End Property
End Class

<AttributeUsage(AttributeTargets.Assembly)> _
Public Class AssemblyCompanyUrlAttribute
    Inherits System.Attribute

    Private _strCompanyUrl As String

    Public Sub New(ByVal url As String)
        _strCompanyUrl = url
    End Sub

    Public Overridable ReadOnly Property CompanyUrl() As String
        Get
            Return _strCompanyUrl
        End Get
    End Property
End Class

Once you've compiled your assembly, the obvious question is, how do we get these attributes (custom or standard) back out? I do it with a reflection loop into a NameValueCollection:

Private Shared Function GetAssemblyAttribs(ByVal a As Reflection.Assembly) _
  As Specialized.NameValueCollection

Dim attribs() As Object
Dim attrib As Object
Dim Name As String
Dim Value As String
Dim nvc As New Specialized.NameValueCollection

attribs = a.GetCustomAttributes(False)
For Each attrib In attribs
  Name = attrib.GetType().ToString()
  Value = ""
  Select Case Name
    Case "System.Reflection.AssemblyTrademarkAttribute"
      Name = "Trademark"
      Value = CType(attrib, AssemblyTrademarkAttribute).Trademark.ToString
    Case "System.Reflection.AssemblyProductAttribute"
      Name = "Product"
      Value = CType(attrib, AssemblyProductAttribute).Product.ToString
    Case "System.Reflection.AssemblyCopyrightAttribute"
      Name = "Copyright"
      Value = CType(attrib, AssemblyCopyrightAttribute).Copyright.ToString
    Case "System.Reflection.AssemblyCompanyAttribute"
      Name = "Company"
      Value = CType(attrib, AssemblyCompanyAttribute).Company.ToString
    Case "System.Reflection.AssemblyTitleAttribute"
      Name = "Title"
      Value = CType(attrib, AssemblyTitleAttribute).Title.ToString
    Case "System.Reflection.AssemblyDescriptionAttribute"
      Name = "Description"
      Value = CType(attrib, AssemblyDescriptionAttribute).Description.ToString
    Case Else
      'Console.WriteLine(Name)
  End Select
  If Value <> "" Then
    If nvc.Item(Name) = "" Then
      nvc.Add(Name, Value)
    End If
  End If
Next

Return nvc
End Function

But I am sure there are other ways.

Posted by Jeff Atwood    View blog reactions
« Populate your AssemblyInfo
Because I love the smell of compilation in the morning »
Comments

Yeah, you could also just strip the "System.Reflection.Assembly" from the beginning and "Attribute" from the end of the assembly type name. This way you wouldn't need to add a case clause for every new costum attribute you add. It would result in cleaner code, but in a little less efficient method.

Hermann Klinke on November 28, 2004 12:28 PM

Yay, thanks for that. I wanted to have a ReleaseType Attribute :)

If anyone needs that in C#, here you go:

[AttributeUsage(AttributeTargets.Assembly)]
public class AssemblyReleaseTypeAttribute : System.Attribute
{
private string _strReleaseType;

public AssemblyReleaseTypeAttribute(string ReleaseType)
{
_strReleaseType = ReleaseType;
}

public virtual string ReleaseType {
get {
return _strReleaseType;
}
}
}

Tyron on December 16, 2005 5:22 AM

Thanks. This was just what I was looking for.

Mike on January 17, 2006 12:22 PM

How do you call the GetAssemblyAttribs function? I can't find a valid value for the parameter.

Dan on April 25, 2006 4:07 AM

System.Reflection.Assembly.GetCallingAssembly
System.Reflection.Assembly.GetEntryAssembly

Jeff Atwood on April 25, 2006 6:08 AM

Great article...

john_mcpherson1 on September 7, 2006 6:23 AM

How can I make the custom attribute appear in the Version tab, when I look at the dll's properties in Windows Explorer?

Csabi on December 17, 2007 4:44 AM

Csabi,

in C# i have created 2 classess and i am able to compile them sucessfully, but the problem is I can not see them in properties tab.

Can anyone help?

TIA

shiamak on May 12, 2008 12:21 PM

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Content (c) 2009 Jeff Atwood. Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved.