Ни подход ILMerge, ни Lars Holm Jensen, обрабатывающий событие AssemblyResolve, не будут работать для хоста плагина. Скажем, исполняемый файл H динамически загружает сборку P и обращается к ней через интерфейс IP , определенный в отдельной сборке. Чтобы вставить IP в H , потребуется небольшая модификация кода Ларса:
Dictionary<string, Assembly> loaded = new Dictionary<string,Assembly>();
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{ Assembly resAssembly;
string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");
dllName = dllName.Replace(".", "_");
if ( !loaded.ContainsKey( dllName ) )
{ if (dllName.EndsWith("_resources")) return null;
System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
byte[] bytes = (byte[])rm.GetObject(dllName);
resAssembly = System.Reflection.Assembly.Load(bytes);
loaded.Add(dllName, resAssembly);
}
else
{ resAssembly = loaded[dllName]; }
return resAssembly;
};
Трюк для обработки повторных попыток разрешить одну и ту же сборку и верните существующий, вместо создания нового экземпляра.
РЕДАКТИРОВАТЬ: чтобы он не испортил сериализацию .NET, обязательно верните значение null для всех сборок, не встроенных в ваш, тем самым не соблюдая стандартное поведение. Вы можете получить список этих библиотек:
static HashSet<string> IncludedAssemblies = new HashSet<string>();
string[] resources = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
for(int i = 0; i < resources.Length; i++)
{ IncludedAssemblies.Add(resources[i]); }
и просто вернуть значение null, если переданная сборка не принадлежит IncludedAssemblies
.