Мне нужна помощь с сообщением об ошибке, которое я получаю. По сути, я занимаюсь разработкой библиотеки классов динамической отчетности с использованием C # .NET и NHibernate.
Сам отчет будет реализован через класс с использованием пользовательских атрибутов для указания метаданных и любых требуемых параметров, включая любые таблицы поиска, которые могут ему понадобиться, например:
[Report( Guid="{D9DEB982-02A3-4700-868D-404E615F1DDA}",
Title="Golf Course Report",
Description= "Produces a list of golf courses by city" )]
[LookupParameter( ParamName="City", LookupTable="Cities", LabelName="Select a city" )]
[LookupTable( Table="Cities", IDColumn="CityID", ValueColumn="CityName" )]
public class GolfCourseReportByCity : Report { }
Когда веб-приложение запускается, оно перечисляет все сборки в папке \bin
и загружает их одним, ища классы, которые были украшены атрибутом Report
. Когда он встречает атрибут LookupTable
, он генерирует новую сборку, используя Reflection Emit, чтобы создать класс со свойствами, заданными параметрами атрибута IDColumn
и ValueColumn
. Кроме того, файл сопоставления NHibernate .hbm.xml будет сгенерирован динамически и встроен в сборку, так что NHibernate сам загрузит его в свою конфигурацию.
Теперь, когда мне удалось продвинуться так далеко, меня застопорила необычная проблема. У меня есть следующий код:
Type generic = typeof( GolfScoreDAL.PersistenceManager<> );
Type constructed = generic.MakeGenericType( EntityType );
dynamic instance = Activator.CreateInstance( constructed );
dynamic results = instance.FindAll();
Этот блок кода создает общий экземпляр DAL
PersistenceManager<CitiesDomain.Cities>
Универсальный параметр CitiesDomain.Cities
берется из свойства EntityType
, которое задается в процессе перечисления сборки и содержит Type
самого класса домена. К сожалению, при вызове строки instance.FindAll()
выше я получаю следующее сообщение об ошибке:
The value "CitiesDomain.Cities" is not of type "CitiesDomain.Cities" and cannot be used in this generic collection.
Parameter name: value
Эта ошибка выдается в строке return results.List<T>();
в коде ниже:
public IList<T> FindAll()
{
using ( ISession session = OpenSession() )
{
var results = session.CreateCriteria( typeof( T ) );
return results.List<T>(); // <------ falls over here
}
}
Я не понимаю, почему, поскольку универсальный тип T
совпадает с типом результатов, возвращаемых методом CreateCriteria
, то есть ввод следующего в промежуточном окне подтверждает это.
? results.List()[0] is typeof(T)
true
По какой-то причине return results.List<T>();
не работает, но return results.List();
работает.
Если я заменил строку Type constructed = generic.MakeGenericType( EntityType );
выше на конкретный класс домена, на который ссылается проект, он работает и не выдает ошибку, например, Type constructed = generic.MakeGenericType( typeof(City) );
Шаблон здесь является ссылочным классом не выдает исключение, но динамически загружаемый класс делает.
Может кто-нибудь сказать мне, почему код не работает, иначе дни работы будут утеряны в канализацию и обратно на чертежную доску.
Заранее спасибо.