Тема как бы охватывает мою проблему.Я видел документ «Лучшая практика» по этой проблеме, но на самом деле он не описывает, как выйти из ситуации.http://msdn.microsoft.com/en-us/library/dd153782.aspx
Моя ситуация.Путь A: Основное применение.(Подпись, версия.. 3.5) Сборка общего интерфейса X. (Подпись, версия)
Путь B: Сборка пользователя.Сборка Common Interface X. (Подписано, версиями) (Возможно, версия отличается от описанной выше. Может не знать фактическую версию, поскольку мы не можем контролировать действия клиента / пользователя.)
Наше Основное приложение загружаетуказанный класс из пользовательской сборки, используя отражение, и взаимодействует с классом, используя указанный интерфейс, определенный в сборке общего интерфейса X. Приложения должны оставаться в одном конкретном пути, а пользовательские (бизнес) сборки - в другом пути.Не просите меня изменить это, это не в моих руках.
Проблема в том, что, скорее всего, будет копия Common Interface Assembly X на пути B. Поэтому, когда я загружаю пользовательскую сборку, используяотражая это, он автоматически загружает Common Interface Assembly X по тому же пути, вместо того, чтобы использовать уже загруженный в память вместе с Приложением.В итоге я обнаружил, что тип iXXX не совпадает с типом iXXX или не могу найти конструктор для класса User Assembly, потому что, опять же, он перепутал интерфейсы между двумя копиями Common Interface Assembly X.
Итак,как я могу загрузить и создать класс из User Assembly в Path B, но не загружать Common Interface Assembly X из Path B (и использовать тот из Path A, который уже находится в памяти)?
Дополнительная информация: большинство проблем, с которыми я сталкиваюсь, возникает вокруг CreateInstance, так как ClientContext находится в Common Interface Assembly X, поэтому, хотя я создал его по пути A, конструктор в моем диалоговом окне, похоже, ожидает его из пути BЗатем я получаю «конструктор типа« ExternalTestForms.WindowDemo1 »не найден».ошибка.(Даже с точно такой же [подписанной и версионной] сборкой как в пути A, так и в пути B, эта ошибка все еще происходит.)
Я думаю, что это покрывает код, который я использую для загрузки сборки и созданияПользовательское окно с использованием интерфейса.
public IExternalForm ShowExternalWindow(string filename, string classname, string parameters, string formIdentity)
{
if (File.Exists(filename))
{
ClientContext context = GetCurrentClientContext(parameters, formIdentity);
object dialog = null;
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += this.CurrentDomain_AssemblyResolve;
this.basePath = Path.GetDirectoryName(filename);
Assembly externalAssembly = Assembly.LoadFile(filename);
try
{
// The Window must must have a ClientContext defined in the constructor.
dialog = externalAssembly.CreateInstance(classname, false, BindingFlags.CreateInstance, null, new object[] { context }, context.Desktop.Culture, null);
}
catch (Exception ex)
{
// MessageBox "Could not launch the Window"
// LogTraceException
}
if (dialog != null && dialog is IExternalForm && dialog is System.Windows.Window)
{
System.Windows.Window window = (System.Windows.Window)dialog;
...
...
...
}
...
}
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string filename = args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
// Seek out the specified assembly in the current Application path first.
string assemblyPath = Path.Combine(Application.StartupPath, filename);
if (!File.Exists(assemblyPath))
{
assemblyPath = Path.Combine(this.basePath, filename);
}
if (File.Exists(assemblyPath))
{
// Load the assembly from the specified path.
Assembly myAssembly = Assembly.LoadFrom(assemblyPath);
// Return the loaded assembly.
return myAssembly;
}
return null;
}