Assembly.GetEntryAssembly() does not work for web applications.
But... I really need something like that. I work with some deeply-nested code that i
In my case, I needed to get the "entry assembly" for a web app before System.Web.HttpContext.Current.ApplicationInstance is initialized. Also, my code needed to work for a variety of app types (window services, desktop apps, etc), and I don't like to pollute my common code with Web concerns.
I created a custom assembly-level attribute, which can be declared in the AssembyInfo.cs file of an assembly which you want to designate as the entry point assembly. Then, you just call the attribute's static GetEntryAssembly method to get the entry assembly. If Assembly.GetEntryAssembly returns non-null, that is used, otherwise it searches through loaded assemblies for the one with the custom attribute. The result is cached in a Lazy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace EntryAssemblyAttributeDemo
{
///
/// For certain types of apps, such as web apps,
/// returns null. With the , we can designate
/// an assembly as the entry assembly by creating an instance of this attribute,
/// typically in the AssemblyInfo.cs file.
///
/// [assembly: EntryAssembly]
///
///
[AttributeUsage(AttributeTargets.Assembly)]
public sealed class EntryAssemblyAttribute : Attribute
{
///
/// Lazily find the entry assembly.
///
private static readonly Lazy EntryAssemblyLazy = new Lazy(GetEntryAssemblyLazily);
///
/// Gets the entry assembly.
///
/// The entry assembly.
public static Assembly GetEntryAssembly()
{
return EntryAssemblyLazy.Value;
}
///
/// Invoked lazily to find the entry assembly. We want to cache this value as it may
/// be expensive to find.
///
/// The entry assembly.
private static Assembly GetEntryAssemblyLazily()
{
return Assembly.GetEntryAssembly() ?? FindEntryAssemblyInCurrentAppDomain();
}
///
/// Finds the entry assembly in the current app domain.
///
/// The entry assembly.
private static Assembly FindEntryAssemblyInCurrentAppDomain()
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var entryAssemblies = new List();
foreach (var assembly in assemblies)
{
// Note the usage of LINQ SingleOrDefault. The EntryAssemblyAttribute's AttrinuteUsage
// only allows it to occur once per assembly; declaring it more than once results in
// a compiler error.
var attribute =
assembly.GetCustomAttributes().OfType().SingleOrDefault();
if (attribute != null)
{
entryAssemblies.Add(assembly);
}
}
// Note that we use LINQ Single to ensure we found one and only one assembly with the
// EntryAssemblyAttribute. The EntryAssemblyAttribute should only be put on one assembly
// per application.
return entryAssemblies.Single();
}
}
}