When i try to create a proxy for the following (test) interface:
public interface ITestInterface<P> where P : struct { T GetIdentity<T>(T obj) where T : ITestInterface<P>; }
I get the following exception:
System.Security.VerificationException: Method ITestInterface`1[System.Int32].GetIdentity: type argument 'T' violates the constraint of type parameter 'T'.
When i remove the generic constraints, i get the following exception:
System.InvalidOperationException: Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.
Does LinFu have problems with generic methods in general?
Comment #1
Posted on Sep 17, 2009 by Massive BirdHi Rauhotz,
LinFu.DP1 doesn't have problems with generic methods. Did you try to proxy the ITestInterface
without specifying what P should be?
Comment #2
Posted on Sep 17, 2009 by Happy CatHi, it looks like the problem only appears when run from an NUnit unit test:
[TestFixture] public class LinFuTest { public interface ITestInterface
where P : struct { T GetIdentity(T obj) where T : ITestInterface
; }
public class TestInterfaceImpl<P> : ITestInterface<P> where P : struct
{
public T GetIdentity<T>(T obj) where T : ITestInterface<P>
{
return obj;
}
}
public class ProxyFactory
{
public class InterceptorWrapper : LinFu.DynamicProxy.IInterceptor
{
private readonly IInterceptor interceptor;
public InterceptorWrapper(IInterceptor interceptor)
{
this.interceptor = interceptor;
}
public object Intercept(LinFu.DynamicProxy.InvocationInfo info)
{
return this.interceptor.Intercept(
new InvocationInfo(info.Target,
info.TargetMethod,
info.StackTrace,
info.TypeArguments,
info.Arguments)
);
}
}
public static ProxyFactory Default = new ProxyFactory();
private readonly LinFu.DynamicProxy.ProxyFactory factory = new
LinFu.DynamicProxy.ProxyFactory();
public T CreateProxy<T>(IInterceptor interceptor)
{
return (T)this.factory.CreateProxy(typeof(object), new
InterceptorWrapper(interceptor), typeof(T)); }
public object CreateProxy(Type instanceType, IInterceptor interceptor)
{
return this.factory.CreateProxy<object>(new
InterceptorWrapper(interceptor), instanceType); } }
public static class LockingProxy
{
/// <summary>
/// Creates a proxy for an object that locks all calls to the
/// object by the object itself as semaphore.
/// </summary>
public static T Create<T>(object target)
{
var interceptor = new LockingInterceptor(target);
return ProxyFactory.Default.CreateProxy<T>(interceptor);
}
public static T Create<T>(T target)
{
var interceptor = new LockingInterceptor(target);
return ProxyFactory.Default.CreateProxy<T>(interceptor);
}
}
public class LockingInterceptor : IInterceptor
{
private readonly object target;
public LockingInterceptor(object target)
{
if (target == null) throw new ArgumentNullException("target");
this.target = target;
}
#region IInterceptor Members
public object Intercept(InvocationInfo info)
{
lock (target)
{
try
{
return info.TargetMethod.Invoke(target, info.Arguments);
}
catch (Exception ex)
{
throw ex.InnerException ?? ex;
}
}
}
#endregion
}
[Test]
public void Test()
{
var obj = new TestInterfaceImpl<int>();
Assert.AreEqual(obj, obj.GetIdentity(obj));
var proxy = LockingProxy.Create<ITestInterface<int>>(obj);
Assert.AreEqual(obj, proxy.GetIdentity(obj));
}
}
Status: New
Labels:
Type-Defect
Priority-Medium