waoywssy / linfu

Automatically exported from code.google.com/p/linfu
0 stars 0 forks source link

DynamicProxy: Problem with generic constraints #36

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
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?

Original issue reported on code.google.com by Rauh...@googlemail.com on 17 Sep 2009 at 7:53

GoogleCodeExporter commented 9 years ago
Hi Rauhotz,

LinFu.DP1 doesn't have problems with generic methods. Did you try to proxy the
ITestInterface<P> without specifying what P should be? 

Original comment by Philip.L...@gmail.com on 17 Sep 2009 at 8:49

GoogleCodeExporter commented 9 years ago
Hi,
 it looks like the problem only appears when run from an NUnit unit test:

  [TestFixture]
    public class LinFuTest
    {
        public interface ITestInterface<P> where P : struct
        {
            T GetIdentity<T>(T obj) where T : ITestInterface<P>;
        }

        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));
        }
    }

Original comment by Rauh...@googlemail.com on 17 Sep 2009 at 1:00