Доступ к не-COM видимому методу DLL из видимой COM DLL, зарегистрированной в GAC

Приложение моего сайта использует компоненты C# COM+, работающие под определенным именем, для доступа к SQL Server, вызываемому из классического ASP.

Существует также веб-служба, которая использует библиотеку \bin в приложении веб-сайта, которое содержит метод для вставки некоторых данных в базу данных SQL Server (назовем это MyApp.Database.dll).

Начиная с веб-сайта, я хочу предоставить аутентифицированным пользователям такую ​​же функциональность.

Я не хочу дублировать код в MyApp.Database.dll внутри компонента COM + по очевидным причинам.

Моя идея состояла в том, чтобы использовать компонент COM + из ASP для вызова метода MyApp.Database.dll для доступа к базе данных SQL с использованием учетных данных приложения, поскольку ASP работает как пользователь и не имеет доступа к SQL Server.

Проблема, с которой я, кажется, сталкиваюсь, заключается в том, что, хотя я могу ссылаться на MyApp.Database.dll в моем проекте компонента COM + (в разделе "Ссылки" и "Использование MyApp.Database.dll"), когда дело доходит до фактического запуска или отладки COM + компонент, когда он пытается вызвать метод из MyApp.Database.dll, он сообщает мне "Не удалось загрузить файлы или сборку" MyApp.Database, Version=3.3.3.11658, Culture= нейтральный, PublicKeyToken=.....'или одна из его зависимостей.'

MyApp.Database.dll не зарегистрирован в GAC (пытаясь избежать этого, он также используется другими приложениями), и его кодовая база не была зарегистрирована в реестре с помощью regasm (я пробовал это и все еще не работал). Версия правильная, и я поместил MyApp.Database.dll в папку приложения компонента COM +.

Я что-то упустил или это невозможно сделать?

Заранее спасибо за помощь.

1 ответ

Решение

Это распространенное ошибочное ожидание: просто потому, что ваша.NET COM DLL была найдена в некоторой заданной папке (папке, установленной аргументом /codebase или RegAsm) - это не означает, что.NET будет искать эту папку в поисках чего-либо еще.

Вообще говоря, это не так. Загрузка сборок.NET через COM-взаимодействие является особым случаем. Для всего остального сборки будут загружаться в AppDomain на основе политики привязки Fusion для процесса, которая не имеет ничего общего с тем, где находится.NET COM DLL. Процесс на самом деле (в зависимости от вашей версии IIS) либо dllhost.exe, iisexpress.exe или w3wp.exe.

У вас есть несколько вариантов.

Во-первых, очевидным решением является помещение MyApp.Database.dll в GAC, поскольку.NET всегда выглядит там. Иногда это правильный выбор (я сделал это, и это работает). Вы отказались это сделать, и у вас есть свои причины; это нормально.

Во-вторых, я считаю, что вы можете изменить политику привязки с помощью файла web.config. Смотрите здесь: http://msdn.microsoft.com/en-us/library/823z9h8w(v=vs.110).aspx. Да, ваш проект ASP Classic может иметь файл web.config. Очевидно, что это не влияет на ваши классические сценарии ASP, но (в зависимости от версии IIS).NET и / или сам IIS используют его для конфигурации. Боюсь, что я не могу вам чем-то помочь с этой альтернативой, потому что мне никогда не приходилось пробовать ее раньше, но вы можете изучить этот вариант - дайте мне знать, как он работает.

Третий вариант - мой личный выбор: вы сказали, что эта DLL уже является веб-службой, верно? Просто вызовите функциональность с помощью вызова веб-службы из вашей COM DLL. Это не требует взлома с волшебными папками, GAC и политиками связывания. Гораздо чище. Единственное легкое усложнение - это отслеживание конфигурации, в которой находится ваш веб-сервис, и я уверен, что вы все равно уже делаете это для подключения к базе данных, поэтому добавить его не составит труда.

Если вам интересно узнать, где.NET ищет DLL, прочитайте эти парни:

Удачи, и, пожалуйста, дайте нам знать, что сработало для вас.

Другие вопросы по тегам