Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Castle Windsor upgrade causes TypeLoadException for generic types

I have the following mapping in my Castle Windsor xml file which has worked okay (unchanged) for some time:

<component id="defaultBasicRepository"
           service="MyApp.Models.Repositories.IBasicRepository`1, MyApp.Models"
           type="MyApp.Models.Repositories.Linq.BasicRepository`1, MyApp.Models"
           lifestyle="perWebRequest"/>

I got this from the Windsor documentation at http://www.castleproject.org/container/documentation/v1rc3/usersguide/genericssupport.html.

Since I upgraded Windsor, I now get the following exception at runtime:

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.TypeLoadException: GenericArguments[0], 'T', on 'MyApp.Models.Repositories.Linq.BasicRepository`1[TEntity]' violates the constraint of type parameter 'TEntity'.

Source Error:

Line 44: public static void ConfigureIoC()
Line 45: {
Line 46: var windsor = new WindsorContainer("Windsor.xml");
Line 47:
Line 48: ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(windsor));

I'm using ASP.NET MVC 1.0, Visual Studio 2008 and Castle Windsor as downloaded from http://sourceforge.net/projects/castleproject/files/InversionOfControl/2.1/Castle-Windsor-2.1.1.zip/download

Can anyone shed any light on this? I'm sure the upgrade of Castle Windsor is what caused it - it's been working well for ages.

UPDATE:
I fixed it myself in the end. See my answer below for details.

like image 337
Neil Barnwell Avatar asked Jun 02 '10 22:06

Neil Barnwell


1 Answers

I found the answer for myself in the end, by comparing all the classes/interfaces in the mapping.

The answer was that the BasicRepository's generic type argument had a generic constraint as follows:

public class BasicRepository<TEntity> : IBasicRepository<TEntity>
    where TEntity : class
{

...but the interface that it implemented didn't have the same constraint:

public interface IBasicRepository<T>
{

I updated the interface to match:

public interface IBasicRepository<T>
    where T : class
{

and now everything works fine.

Hope this helps someone. :)

like image 124
Neil Barnwell Avatar answered Sep 30 '22 05:09

Neil Barnwell