Использование универсальных классов с ObjectDataSource
-
09-06-2019 - |
Вопрос
У меня есть универсальный репозиторий<T> класс, который я хочу использовать с ObjectDataSource.Репозиторий<T> находится в отдельном проекте под названием DataAccess.Согласно это сообщение из групп новостей MS (соответствующая часть скопирована ниже):
Внутренне ObjectDataSource вызывает Type .GetType(строка) для получения типа, поэтому нам нужно следовать рекомендациям, задокументированным в Type .GetType о том, как получить тип с помощью дженериков.Вы можете обратиться к библиотеке MSDN для определения типа.Получите тип:
http://msdn2.microsoft.com/en-us/library/w3f99sx1.aspx
Из документа вы узнаете, что вам нужно использовать обратную метку (`) для обозначения имени типа, в котором используются обобщенные значения.
Кроме того, здесь мы должны указать имя сборки в строке имени типа.
Итак, на ваш вопрос ответ заключается в использовании имени типа следующим образом:
TypeName="TestObjectDataSourceAssembly.MyDataHandler`1[System.Строка],TestObjectDataSourceAssembly"
Ладно, в этом есть смысл.Однако, когда я пытаюсь это сделать, страница выдает исключение:
<asp:ObjectDataSource ID="MyDataSource" TypeName="MyProject.Repository`1[MyProject.MessageCategory],DataAccess" />
[Исключение InvalidOperationException:Не удалось найти тип, указанный в свойстве TypeName ObjectDataSource 'MyDataSource'.]
Любопытно, что это происходит только тогда, когда я просматриваю страницу.Когда я открываю диалоговое окно "Настроить источник данных" из конструктора VS2008, оно правильно показывает мне методы в моем универсальном классе репозитория.Передача строки TypeName в Type .Функция GetType() при отладке также возвращает допустимый тип.Так что же это дает?
Решение
Сделайте что-нибудь вроде этого.
Type type = typeof(Repository<MessageCategory);
string assemblyQualifiedName = type.AssemblyQualifiedName;
получите значение AssemblyQualifiedName и вставьте его в поле TypeName.Обратите внимание, что Type.GetType(строка), передаваемое значение должно быть
Точное для сборки имя типа, который нужно получить.Видишь Квалифицированное имя сборки.Если тип находится в текущей исполняемой сборке или в Mscorlib.dll, достаточно указать имя типа, указанное в его пространстве имен.
Таким образом, это может сработать, передав эту строку в ваш код, потому что этот класс находится в текущей исполняемой сборке (где вы его вызываете), где в качестве ObjectDataSource нет.
Скорее всего, тип, который вы ищете, это
MyProject.Repository`1[MyProject.MessageCategory, DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null], DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null
Другие советы
Я знаю, что это старый пост, но недавно я сам столкнулся с этой проблемой.Другим решением было бы заменить наследование композицией объекта, например
[DataObject]
public class DataAccessObject {
private Repository<MessageCategory> _repository;
// ctor omitted for clarity
// ...
[DataObjectMethod(DataObjectMethodType.Select)]
public MessageCategory Get(int key) {
return _repository.Get(key);
}
}
Таким образом, ObjectDataSource не знает о репозитории, потому что он скрыт внутри класса.У меня есть библиотека классов в моем фасадном слое, которая является вполне разумным местом для размещения этого кода в проекте, над которым я работаю.
Кроме того, если вы используете Resharper и интерфейсы, можно заставить Resharper выполнить рефакторинг, используя функцию Resharpers "Реализовать с помощью поля".
Даррен,
Большое, очень большое спасибо за ваш пост.Я боролся с этим весь день.Как ни странно, в моем случае мне нужно удвоить квадратные скобки, напримердля вашего фрагмента кода:
MyProject.Repository`1[[MyProject.MessageCategory, доступ к данным, Версия=1.0.0.0, Culture= нейтральный, PublicKey= null]], Доступ к данным, Версия=1.0.0.0, Culture= нейтральный, PublicKey=null
Понял