В .NET 3.5 и ниже, следующий (немного грубый пример) работает довольно хорошо:
Сборка A:
public static class ClassInAssemblyA
{
public static string GetCallingAssemblyLocation()
{
return System.Reflection.Assembly.GetCallingAssembly().GetName(false).CodeBase;
}
}
Сборка B:
public class ClassInAssemblyB
{
public string AssemblyName { get; private set; }
public ClassInAssemblyB()
{
AssemblyName = ClassInAssemblyA.GetCallingAssemblyLocation();
}
}
Сборка C:
var assemblyName = new ClassInAssemblyB().AssemblyName;
Assert.That(assemblyName.Contains("AssemblyB"));
К сожалению, CLR .NET 4.0, по-видимому, оптимизирован для встраивания кода AssemblyA в AssemblyB, поэтому вышеприведенный тест фактически проходит при выполнении в режиме отладки, но не работает в режиме выпуска . По сути, невозможно воспроизвести ошибку во время перехода.
Один из способов остановить встраивание - это потребовать от вызывающей стороны добавлять атрибут [MethodImpl(MethodImplOptions.NoInlining)]
каждый раз, когда они ссылаются на AssemblyA. Это хитрое решение, которое требует от вызывающего абонента знать внутреннюю работу библиотеки, и это не должно быть их проблемой, поэтому я не хочу идти по этому пути.
Существуют ли альтернативные способы выяснить во время выполнения, какое имя файла у вызывающей сборки ?