violates the constraint of type parameter 'T'

1,224 views
Skip to first unread message

Ido Samuelson

unread,
Nov 14, 2007, 2:03:14 PM11/14/07
to castle-pro...@googlegroups.com

Hello,

 

I have a couple of components that has generic methods like Get<T>();

Both components register ok. However resolving the 2nd components causing an exception:

 

violates the constraint of type parameter:

 

Method xxx.GetProxy: type argument xxx.ILoginService' violates the constraint of type parameter 'T'.

 

 

I would appreciate any help.

 

Best,

 

Ido

image001.png

James Curran

unread,
Nov 14, 2007, 4:03:06 PM11/14/07
to castle-pro...@googlegroups.com
Presumably, you have something along the lines of:
class A {};
class B : A {}
 
Get<T>() where T: A {...}
 
And it fails when you write:
Get<B>();
 
Now, then problem is that B is not an A, which it must be to use Get<T>.
 
"But wait", you say.  "B really IS an A -- look right at the code." 
 
And of course, you are right.  in fact, if it weren't you'd get a compile-time error, and you are in fact getting a run-time error.  The answer can only be that the A that B is derived from is different than the A that Get<T> is looking at. Which probably means the first item in the "Troubleshooting tips" is probably right.  I'm going to guess that A, B and Get<T> are defined in different assemblies, and that B.dll reference A.dll version 2.0, while Get.dll references A.dll, ver 1.0.

Ido Samuelson

unread,
Nov 14, 2007, 5:00:23 PM11/14/07
to castle-pro...@googlegroups.com

I have the following components

 

    public interface IServiceAgent

    {

         T GetProxy<T>() where T : class;

         T GetProxy<T>(object callbackInstance) where T : class;

    }

 

And

    public interface IPresentationHost

    {

       void Register<T>() where T : IPresentation;

       void Register<T>(Type service) where T : IPresentation;

    }

 

Both has simple implementation that do not do anything (stub objects) IServiceAgent actually return null.

 

The calling code is as follow:

    IServiceAgent agent = FourDPlatform.Loader.Resolve<IServiceAgent>();

    ILoginService proxy = agent.GetProxy<ILoginService>();

 

I get the error on the ILoginService.

The weird is that if I do not register the IPresentationHost to the container, then resolving of the ILoginService works fine.

There is no reference or relation between the ILoginService and the IPresentationHost. Both are completely decoupled.

Ido Samuelson

unread,
Nov 14, 2007, 5:22:16 PM11/14/07
to castle-pro...@googlegroups.com

I wrote a small sample that present the problem. It happens when my object implements two interfaces (one is IStartable)

 

I Added a comment near the problem

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Linq;

using System.Text;

using System.Threading;

using Castle.Core.Interceptor;

using Castle.MicroKernel;

using Castle.MicroKernel.Facilities;

using Castle.MicroKernel.ModelBuilder;

using Castle.Windsor.Proxy;

using Castle.Facilities.Startable;

using Castle.Core;

 

namespace ConsoleApplication3

{

    class Program

    {

        static void Main(string[] args)

        {

            IKernel k = new DefaultKernel(new DefaultProxyFactory());

            k.AddFacility("startable",new StartableFacility());

            k.AddFacility("tracing", new GenericFacility<TraceInterceptor>());

        

            k.AddComponent<PresentationHost>(typeof(IPresentationHost));

            k.AddComponent<ServiceAgent>(typeof(IServiceAgent));

 

            // For some reason there is a connection between IServiceAgent and IPresentation since it requires now an IPresentation. Though both are completely decoupled.

            k.Resolve<IServiceAgent>().GetProxy<MyPresentation>(); // This line works

 

            k.Resolve<IServiceAgent>().GetProxy<string>();// This line fails

           

 

        }

    }

 

    public class PresentationHost : IPresentationHost, IStartable

    {

        #region IPresentationHost Members

 

        public void Register<T>() where T : IPresentation

        {

        }

 

        public void Register<T>(Type service) where T : IPresentation

        {

        }

 

        #endregion

 

        #region IStartable Members

 

        public void Start()

        {

          

        }

 

        public void Stop()

        {

          

        }

 

        #endregion

    }

 

    public class ServiceAgent : IServiceAgent

    {

 

        #region IServiceAgent Members

 

        public T GetProxy<T>() where T : class

        {

            return null;

        }

 

        public T GetProxy<T>(object callbackInstance) where T : class

        {

            return null;

        }

 

        #endregion

    }

 

 

    public interface IPresentationHost

    {

        void Register<T>() where T : IPresentation;

        void Register<T>(Type service) where T : IPresentation;

        // void Register(Type classType); // THIS present another bug , castle scream that Register is defined already. Not the main concern though.

        // void Register(Type classType, Type serviceType);

    }

 

    public interface IServiceAgent

    {

        T GetProxy<T>() where T : class;

        T GetProxy<T>(object callbackInstance) where T : class;

    }

 

 

    public interface IPresentation

    {

       

    }

 

    public class MyPresentation : IPresentation

    {

       

    }

  

 

 

#region helpers

    [Serializable]

    public class DefaultInterceptor : IInterceptor

    {

 

        private bool enabled;

        public DefaultInterceptor()

        {

            enabled = true;

        }

        public bool Enabled

        {

            get { return enabled; }

            set { enabled = value; }

        }

 

        public virtual void Intercept(IInvocation invocation)

        {

            if (Enabled)

                PreProceed(invocation);

            invocation.Proceed();

            if (Enabled)

                PostProceed(invocation);

        }

 

        protected virtual void PreProceed(IInvocation invocation)

        {

        }

 

        protected virtual void PostProceed(IInvocation invocation)

        {

        }

    }

 

    internal class TraceInterceptor : DefaultInterceptor

    {

 

        static TraceInterceptor()

        {

            System.Diagnostics.Trace.Listeners.Add(new ConsoleTraceListener());

            Trace.AutoFlush = true;

        }

 

        protected override void PreProceed(IInvocation invocation)

        {

            //Trace.Indent();

 

            //  type = invocation.InvocationTarget.GetType();

            //  if (type.BaseType != typeof(System.Object))

            //       type = type.BaseType;

 

            string threadName = Thread.CurrentThread.Name ?? "???";

            Trace.WriteLine(string.Format("[{0}] {1}.{2}", threadName, invocation.TargetType.Name, invocation.MethodInvocationTarget.Name));

        }

 

        protected override void PostProceed(IInvocation invocation)

        {

            //  Trace.WriteLine(string.Format("After '{1}' ", type.FullName, invocation.MethodInvocationTarget.Name), category);

            // Trace.Unindent();

        }

    }

 

    public class GenericFacility<T> : AbstractFacility where T : class, IInterceptor

    {

        protected override void Init()

        {

            Kernel.AddComponent<T>();

            Kernel.ComponentModelBuilder.AddContributor(new DefaultComponentInspector<T>());

        }

    }

 

    public class DefaultComponentInspector<T> : IContributeComponentModelConstruction where T : IInterceptor

    {

        public virtual void ProcessModel(IKernel kernel, ComponentModel model)

        {

            model.Dependencies.Add(

                new DependencyModel(DependencyType.Service, null, typeof(T), false));

 

 

            model.Interceptors.Add(

                new InterceptorReference(typeof(T)));

        }

 

    }

 

#endregion

}

 

 

From: castle-pro...@googlegroups.com [mailto:castle-pro...@googlegroups.com] On Behalf Of James Curran


Sent: Wednesday, November 14, 2007 4:03 PM
To: castle-pro...@googlegroups.com

James Curran

unread,
Nov 15, 2007, 3:24:37 AM11/15/07
to castle-pro...@googlegroups.com
Well, after carefully stepping through the code, and my only answer is --- Damnned if I know.
 
So, let's answer the part that I can answer.


        void Register<T>(Type service) where T : IPresentation;

        // void Register(Type classType); // THIS present another bug , castle scream that Register is defined already.

 
This is not a bug.   Note that for a generic method, you do not need to specify the the type, if it can be deduced from the parameters.  So, given the method:
 
T MyFunc<T>(T t) {....}
 
then
 
MyFunc("Hello world");
 
is the same as writing
 
MyFunc<string>("Hello world");
 
So, given your two methods, if you'd written
 
Register(new MyPresentation());
 
which of this two method should it call?

Ido Samuelson

unread,
Nov 15, 2007, 5:50:37 AM11/15/07
to castle-pro...@googlegroups.com

Well. Not always I know the type explicitly in my code. Sometimes I have it dynamically. This is why I require the two methods. Though I can still use the implicit one. I agree on that.

Any how, this was not the main issue where I get the violation exception. Any comments on this one??

 

From: castle-pro...@googlegroups.com [mailto:castle-pro...@googlegroups.com] On Behalf Of James Curran
Sent: Thursday, November 15, 2007 3:25 AM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

 

Well, after carefully stepping through the code, and my only answer is --- Damnned if I know.

Ido Samuelson

unread,
Nov 15, 2007, 6:23:18 AM11/15/07
to castle-pro...@googlegroups.com

What really blew my mind was when I noticed the generic restrictions passed to a different object (where T : IPresentation).

I removed the restriction and added casting and now everything works fine. However, this is still a bug I would really like to fix. If someone can point me out to where exactly I should look, I’ll fix it.

 

Best,

Ido

Ayende Rahien

unread,
Nov 15, 2007, 6:27:08 AM11/15/07
to castle-pro...@googlegroups.com
Just to point out, there are many bugs related to generics in the BCL and runtime itself.
Try to isolate it outside of Castle, and see if it is reproducable.

josh robb

unread,
Nov 15, 2007, 6:53:00 AM11/15/07
to castle-pro...@googlegroups.com
On Nov 15, 2007 11:27 AM, Ayende Rahien <aye...@ayende.com> wrote:
> Just to point out, there are many bugs related to generics in the BCL and
> runtime itself.
> Try to isolate it outside of Castle, and see if it is reproducable.

Further to this - I've just run this and it works perfectly.

--output--
[???] ServiceAgent.GetProxy
[???] ServiceAgent.GetProxy
Press any key to continue . . .
--/output--

It fails if it's run under the debugger though. Weird.

It only fails if you include your Interceptor - so I'd start looking there.

j.

Ido Samuelson

unread,
Nov 15, 2007, 8:07:18 AM11/15/07
to castle-pro...@googlegroups.com

I did. This really looks like in castle.

 

From: castle-pro...@googlegroups.com [mailto:castle-pro...@googlegroups.com] On Behalf Of Ayende Rahien
Sent: Thursday, November 15, 2007 6:27 AM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

 

Just to point out, there are many bugs related to generics in the BCL and runtime itself.

Ido Samuelson

unread,
Nov 15, 2007, 8:08:15 AM11/15/07
to castle-pro...@googlegroups.com
True, since when you include the interceptor then the proxy is being
created. Otherwise no proxy is required. So this looks like a bug in
dynamicproxy2

-----Original Message-----
From: castle-pro...@googlegroups.com
[mailto:castle-pro...@googlegroups.com] On Behalf Of josh robb
Sent: Thursday, November 15, 2007 6:53 AM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

josh robb

unread,
Nov 15, 2007, 8:34:55 AM11/15/07
to castle-pro...@googlegroups.com
On Nov 15, 2007 1:07 PM, Ido Samuelson <ido.sa...@gmail.com> wrote:
> I did. This really looks like in castle.

That's a hard argument to make given that this problem only occurs
when running under a debugger.

j.

Ayende Rahien

unread,
Nov 15, 2007, 8:37:24 AM11/15/07
to castle-pro...@googlegroups.com
Hm, there are several runtime issues that are exposed only there, IIRC

josh robb

unread,
Nov 15, 2007, 9:07:03 AM11/15/07
to castle-pro...@googlegroups.com
On Nov 15, 2007 1:37 PM, Ayende Rahien <aye...@ayende.com> wrote:
> Hm, there are several runtime issues that are exposed only there, IIRC

I remember you mentioning..... :(

I've got a reproducible test case...

The problem is that if you have a constraint on a generic method then
you get the dreaded:

"An attempt was made to load a program with an incorrect format.
(Exception from HRESULT: 0x8007000B)"

j.

Ayende Rahien

unread,
Nov 15, 2007, 10:25:18 AM11/15/07
to castle-pro...@googlegroups.com
Yes, if the constraint is constrained on the parameter of the generic type, that will expose the bug.

On 11/15/07, josh robb < josh...@fastmail.fm> wrote:

David N. Godfrey

unread,
Nov 15, 2007, 10:32:33 AM11/15/07
to castle-pro...@googlegroups.com

When not using the debugger this code works fine here too.

When I use the debugger I get the failure on the first resolve too -
i.e. the one with the comment that says "// This line works". If I
remove the line to register the startable facility everything works
again so I'm not convinced the interceptor is the cause of the problem
as this is still there. The only real difference is that the
PresentationHost is not instantiated.

Dave.

-----Original Message-----
From: castle-pro...@googlegroups.com
[mailto:castle-pro...@googlegroups.com] On Behalf Of josh robb
Sent: 15 November 2007 11:53
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

Ido Samuelson

unread,
Nov 15, 2007, 11:49:33 AM11/15/07
to castle-pro...@googlegroups.com
I got lost in the discussion :) so is this an official bug now? Or is a
problem on my end?

-----Original Message-----
From: castle-pro...@googlegroups.com
[mailto:castle-pro...@googlegroups.com] On Behalf Of josh robb
Sent: Thursday, November 15, 2007 9:07 AM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

Ido Samuelson

unread,
Nov 15, 2007, 4:16:18 PM11/15/07
to castle-pro...@googlegroups.com
I was not able to replicate it without castle though.

-----Original Message-----
From: castle-pro...@googlegroups.com
[mailto:castle-pro...@googlegroups.com] On Behalf Of josh robb
Sent: Thursday, November 15, 2007 8:35 AM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

Ayende Rahien

unread,
Nov 15, 2007, 4:34:34 PM11/15/07
to castle-pro...@googlegroups.com
There are several runtime bugs that are exposed by Castle. They are mostly involving generics, reflection emit etc.
This could be one of those.

On 11/15/07, Ido Samuelson <ido.sa...@gmail.com> wrote:

Ido Samuelson

unread,
Nov 15, 2007, 10:11:24 PM11/15/07
to castle-pro...@googlegroups.com

I will take a deeper look at it.

 

From: castle-pro...@googlegroups.com [mailto:castle-pro...@googlegroups.com] On Behalf Of Ayende Rahien
Sent: Thursday, November 15, 2007 4:35 PM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

 

There are several runtime bugs that are exposed by Castle. They are mostly involving generics, reflection emit etc.
This could be one of those.

On 11/15/07, Ido Samuelson <ido.sa...@gmail.com> wrote:


I got lost in the discussion :) so is this an official bug now? Or is a
problem on my end?

-----Original Message-----
From: castle-pro...@googlegroups.com
[mailto:castle-pro...@googlegroups.com] On Behalf Of josh robb
Sent: Thursday, November 15, 2007 9:07 AM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'


On Nov 15, 2007 1:37 PM, Ayende Rahien <aye...@ayende.com > wrote:
> Hm, there are several runtime issues that are exposed only there, IIRC

I remember you mentioning..... :(

I've got a reproducible test case...

The problem is that if you have a constraint on a generic method then
you get the dreaded:

"An attempt was made to load a program with an incorrect format.
(Exception from HRESULT: 0x8007000B)"

j.


<br

josh robb

unread,
Nov 16, 2007, 6:19:03 AM11/16/07
to castle-pro...@googlegroups.com
On Nov 15, 2007 3:25 PM, Ayende Rahien <aye...@ayende.com> wrote:
> Yes, if the constraint is constrained on the parameter of the generic type,
> that will expose the bug.

Yep - except it's the generic type parameter of a generic method.

The only thing that's strange is that it doesn't fault when using a
CreateClassProxy, only CreateInterfaceProxy*

I haven't had time to dig into that yet.

j.

josh robb

unread,
Nov 16, 2007, 6:20:45 AM11/16/07
to castle-pro...@googlegroups.com
On Nov 15, 2007 4:49 PM, Ido Samuelson <ido.sa...@gmail.com> wrote:
>
> I got lost in the discussion :) so is this an official bug now? Or is a
> problem on my end?

If you mean an offical CLR bug then maybe. If you mean an official
Castle bug - then not yet. (and honestly - ATM it looks like it's not
going to be treated as such).

j.

Fabian Schmied

unread,
Nov 16, 2007, 11:32:36 AM11/16/07
to castle-pro...@googlegroups.com
> Yep - except it's the generic type parameter of a generic method.
>
> The only thing that's strange is that it doesn't fault when using a
> CreateClassProxy, only CreateInterfaceProxy*
>
> I haven't had time to dig into that yet.

Though I don't really have the time, either, I might be able to take
some to look into this on Monday or Tuesday. (After all, I'm the
generics guy or something.) Do you have a DynamicProxy-only test case
exposing the problem?

Fabian

josh robb

unread,
Nov 16, 2007, 1:28:54 PM11/16/07
to castle-pro...@googlegroups.com
On Nov 16, 2007 4:32 PM, Fabian Schmied <fabian....@gmail.com> wrote:
> Though I don't really have the time, either, I might be able to take
> some to look into this on Monday or Tuesday. (After all, I'm the
> generics guy or something.) Do you have a DynamicProxy-only test case
> exposing the problem?

Yay. it only occurs when running under the debugger.

RhinoMocksTestCase.ProxyingGenericClassWithGenericClassConstraint

j.

Ayende Rahien

unread,
Nov 16, 2007, 1:44:08 PM11/16/07
to castle-pro...@googlegroups.com

Ido Samuelson

unread,
Nov 16, 2007, 3:36:00 PM11/16/07
to castle-pro...@googlegroups.com

I am using Orcas Beta 2. If this bug is fixed then either beta 2 do not hold this fix or this one is different one.

 

 

From: castle-pro...@googlegroups.com [mailto:castle-pro...@googlegroups.com] On Behalf Of Ayende Rahien
Sent: Friday, November 16, 2007 1:44 PM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

 

Ido Samuelson

unread,
Nov 16, 2007, 4:00:34 PM11/16/07
to castle-pro...@googlegroups.com
Thank you for the help.

I will prepare one for you by Monday.

-----Original Message-----
From: castle-pro...@googlegroups.com
[mailto:castle-pro...@googlegroups.com] On Behalf Of Fabian Schmied
Sent: Friday, November 16, 2007 11:33 AM
To: castle-pro...@googlegroups.com
Subject: Re: violates the constraint of type parameter 'T'

Fabian Schmied

unread,
Nov 22, 2007, 8:32:29 AM11/22/07
to castle-pro...@googlegroups.com
> Thank you for the help.
>
> I will prepare one for you by Monday.

I finally found some time to look into this and have managed to
encapsulate the problem into a DP2-only test case. I've checked the
code generated by DynamicProxy 2, it is perfectly verifiable. Also,
the behavior is incredibly fragile to reproduce:

- The code fails only from within the debugger,
- It fails only if a second proxy was generated before the method is called,
- It fails only if dynamically generated code is executed; if the
proxy is saved and reloaded, it doesn't.

Therefore, I'm really sure that this is a CLR bug, which,
unfortunately, still exists in VS 2008. I've reported this on
Microsoft Connect, but I guess if it is fixed, it won't be in the near
future.

Sorry I can't do much more, it's a runtime issue at the moment.

Fabian

josh robb

unread,
Nov 22, 2007, 8:46:18 AM11/22/07
to castle-pro...@googlegroups.com

Thanks Fabian! I'm just glad that it wasn't something obviously dumb
that I missed. :)

j.

Johan Andersson

unread,
Jan 30, 2009, 5:41:01 AM1/30/09
to Fabian Schmied, castle-pro...@googlegroups.com
Hey everyone, thanks for a thread with alot of info!

Here's a follow up on my behalf which just confirms that this problem
still exists.

We got the same problem in our code base (we're using VS.Net 2008
SP1 / .net 3.5 SP1 and MSTest).
Since over a year or so we started to experience the problem that we
were unable to run our tests using the Debug configuration in VS.Net.
However, if we switch over to Release mode, everything works out just
fine.
Just before I found this thread I tried to turn on debug options for
our Release config of the test project (Project settings -> Build ->
Advanced -> Debug Info).
This is my conclusion:
- Having Debug Info set to none, everything works out just fine
- Having Debug Info set to full or pdb only, the following message
appears:

Initialization method
ApplicationTests.x.Presenters.xPresenterTests.Init threw exception.
System.TypeLoadException: System.TypeLoadException: GenericArguments
[0], 'TService', on
'IxyzProxyb09635780bbe42aa9a8d37e644190956+InvocationCreateHandler_13
[TContentType]' violates the constraint of type parameter
'TContentType'..

The line of code in the TestInitialize block:
SetupResult.For( xMock.CreateHandler<xyz>() ).Return( z );

First of all I supposed it was some conditional code that was the
reason (something triggered by #if !DEBUG ... ), but note that I only
changed Debug Info - I did not turn on the DEBUG compile time constant
to reproduce the error for our Release configuration.
I certainly feels like something related to the mix of generated code
and compiled code with debug info.

- Johan

On 22 Nov 2007, 14:32, "Fabian Schmied" <fabian.schm...@gmail.com>
wrote:

Reply all
Reply to author
Forward
0 new messages