Доступ к не-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, прочитайте эти парни:
- Как включить ведение журнала ошибок привязки сборки (Fusion) в.NET
- http://www.hanselman.com/blog/BackToBasicsUsingFusionLogViewerToDebugObscureLoaderErrors.aspx
- http://www.hanselman.com/blog/MoreOnAssemblyBindingStrongNamingTheGACPublisherPolicyAndDynamicallyLoadedAssemblies.aspx
Удачи, и, пожалуйста, дайте нам знать, что сработало для вас.