User: xtoff
Date: 2009/12/30 02:23 AM

Added:
 /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/
  ReflectionOverProxyTestCase.cs
 /DynamicProxy/trunk/src/Castle.DynamicProxy/ComponentModel/
  ProxyPropertyDescriptor.cs, ProxyTypeDescriptionProvider.cs, 
ProxyTypeDescriptor.cs

Modified:
 /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/
  Castle.DynamicProxy.Tests-vs2008.csproj
 /DynamicProxy/trunk/src/Castle.DynamicProxy/
  Castle.DynamicProxy-vs2008.csproj, IProxyGenerationHook.cs
 /DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/
  BaseProxyGenerator.cs, ClassProxyGenerator.cs, 
InterfaceProxyWithTargetGenerator.cs, InterfaceProxyWithoutTargetGenerator.cs

Log:
 - first shot at adding custom TypeDescriptor to proxy (mostly to do 
transparent databinding for WPF)
 - most of the functionality is not working yet.
 - proxy types now have TypeDescriptionProviderAttribute defined on them.

File Changes:

Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy/
=======================================================

File [modified]: Castle.DynamicProxy-vs2008.csproj
Delta lines: +93 -0
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/ComponentModel/ProxyPropertyDescriptor.cs
                                (rev 0)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/ComponentModel/ProxyPropertyDescriptor.cs
        2009-12-30 09:23:44 UTC (rev 6544)
@@ -0,0 +1,93 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.DynamicProxy.ComponentModel
+{
+       using System;
+       using System.ComponentModel;
+       using System.Reflection;
+
+       public class ProxyPropertyDescriptor : PropertyDescriptor
+       {
+               private readonly string actualName;
+               private readonly Type proxyType;
+               private readonly PropertyInfo property;
+
+               public ProxyPropertyDescriptor(string name, Attribute[] 
attrs,Type proxyType) : base(StripName(name), attrs)
+               {
+                       actualName = name;
+                       property = proxyType.GetProperty(actualName,
+                                                        BindingFlags.Public | 
BindingFlags.NonPublic |
+                                                        BindingFlags.Instance 
| BindingFlags.Static);
+                       this.proxyType = proxyType;
+               }
+
+               private static string StripName(string name)
+               {
+                       var indexOfLastDot = name.LastIndexOf('.');
+                       if (indexOfLastDot == -1)
+                       {
+                               return name;
+                       }
+
+                       if (indexOfLastDot + 1 == name.Length)
+                       {
+                               // is it legal that property name ends with a 
dot?
+                               return name;
+                       }
+
+                       return name.Substring(indexOfLastDot + 1);
+               }
+
+               public override bool CanResetValue(object component)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public override object GetValue(object component)
+               {
+                       return property.GetValue(component, null);
+               }
+
+               public override void ResetValue(object component)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public override void SetValue(object component, object value)
+               {
+                       property.SetValue(component, value, null);
+               }
+
+               public override bool ShouldSerializeValue(object component)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public override Type ComponentType
+               {
+                       get { throw new NotImplementedException(); }
+               }
+
+               public override bool IsReadOnly
+               {
+                       get { return property.CanWrite == false;}
+               }
+
+               public override Type PropertyType
+               {
+                       get { return property.PropertyType; }
+               }
+       }
+}

File [modified]: IProxyGenerationHook.cs
Delta lines: +1 -0
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Castle.DynamicProxy.Tests-vs2008.csproj
    2009-12-29 19:57:09 UTC (rev 6543)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Castle.DynamicProxy.Tests-vs2008.csproj
    2009-12-30 09:23:44 UTC (rev 6544)
@@ -232,6 +232,7 @@
     <Compile Include="ProxyKind.cs" />
     <Compile Include="ProxyNothingHook.cs" />
     <Compile Include="ProxyTargetAccessorHandlingTestCase.cs" />
+    <Compile Include="ReflectionOverProxyTestCase.cs" />
     <Compile Include="RhinoMocksTestCase.cs" />
     <Compile Include="SerializableClassTestCase.cs" />

Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/
=============================================================

File [modified]: Castle.DynamicProxy.Tests-vs2008.csproj
Delta lines: +66 -0
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/ReflectionOverProxyTestCase.cs 
                            (rev 0)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/ReflectionOverProxyTestCase.cs 
    2009-12-30 09:23:44 UTC (rev 6544)
@@ -0,0 +1,66 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.DynamicProxy.Tests
+{
+       using System;
+       using System.ComponentModel;
+
+       using Castle.DynamicProxy.Tests.Interfaces;
+
+       using NUnit.Framework;
+
+       [TestFixture]
+       public class ReflectionOverProxyTestCase:BasePEVerifyTestCase
+       {
+               [Test]
+               public void Proxy_should_have_TypeDescriptionProviderAttribute()
+               {
+                       var type = 
generator.CreateClassProxy(typeof(SimpleClass)).GetType();
+                       Assert.IsTrue(Attribute.IsDefined(type, 
typeof(TypeDescriptionProviderAttribute)));
+
+                       type = 
generator.CreateInterfaceProxyWithoutTarget(typeof(IOne)).GetType();
+                       Assert.IsTrue(Attribute.IsDefined(type, 
typeof(TypeDescriptionProviderAttribute)));
+
+                       type = 
generator.CreateInterfaceProxyWithTargetInterface(typeof(IOne),new 
One()).GetType();
+                       Assert.IsTrue(Attribute.IsDefined(type, 
typeof(TypeDescriptionProviderAttribute)));
+
+                       type = 
generator.CreateInterfaceProxyWithTarget(typeof(IOne),new One()).GetType();
+                       Assert.IsTrue(Attribute.IsDefined(type, 
typeof(TypeDescriptionProviderAttribute)));
+               }
+
+               [Test]
+               public void 
Proxy_with_explicitly_implemented_interface_should_return_short_names_via_descriptor()
+               {
+                       var type = 
generator.CreateClassProxy(typeof(HasPropertyBar), new[] { typeof(IHasProperty) 
}).GetType();
+                       var properties = TypeDescriptor.GetProperties(type);
+                       Assert.IsNotEmpty(properties);
+                       foreach (PropertyDescriptor property in properties)
+                       {
+                               Assert.That(property.Name.IndexOf(".") == -1, 
"Name should have no dots: {0}", property.Name);
+                       }
+               }
+
+               [Test]
+               public void 
Should_be_able_to_set_get_interface_property_with_short_name_via_TypeDescriptor()
+               {
+                       var proxy = 
generator.CreateClassProxy(typeof(HasPropertyBar), new[] { typeof(IHasProperty) 
}) as IHasProperty;
+                       var properties = TypeDescriptor.GetProperties(proxy);
+                       var property = properties.Find("Prop", true);
+                       property.SetValue(proxy, 7);
+                       Assert.AreEqual(7, proxy.Prop);
+               }
+
+       }
+}

File [added]: ReflectionOverProxyTestCase.cs
Delta lines: +0 -0
===================================================================

Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy/ComponentModel/
======================================================================

File [added]: ProxyPropertyDescriptor.cs
Delta lines: +30 -0
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/ComponentModel/ProxyTypeDescriptionProvider.cs
                           (rev 0)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/ComponentModel/ProxyTypeDescriptionProvider.cs
   2009-12-30 09:23:44 UTC (rev 6544)
@@ -0,0 +1,30 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.DynamicProxy.ComponentModel
+{
+       using System;
+       using System.ComponentModel;
+
+       // TODO: support all other methods if needed
+       // TODO: support types that already have decription provider
+       public class ProxyTypeDescriptionProvider : TypeDescriptionProvider
+       {
+               public override ICustomTypeDescriptor GetTypeDescriptor(Type 
objectType, object instance)
+               {
+                       return new ProxyTypeDescriptor(objectType, instance);
+               }
+       }
+
+}

File [added]: ProxyTypeDescriptionProvider.cs
Delta lines: +126 -0
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/ComponentModel/ProxyTypeDescriptor.cs
                            (rev 0)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/ComponentModel/ProxyTypeDescriptor.cs
    2009-12-30 09:23:44 UTC (rev 6544)
@@ -0,0 +1,126 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.DynamicProxy.ComponentModel
+{
+       using System;
+       using System.ComponentModel;
+       using System.Reflection;
+
+       public class ProxyTypeDescriptor : ICustomTypeDescriptor
+       {
+               private readonly Type type;
+               private readonly object instance;
+               private PropertyDescriptor[] properties;
+
+               public ProxyTypeDescriptor(Type type, object instance)
+               {
+                       this.type = type;
+                       this.instance = instance;
+               }
+
+               public AttributeCollection GetAttributes()
+               {
+                       throw new NotImplementedException();
+               }
+
+               public string GetClassName()
+               {
+                       throw new NotImplementedException();
+               }
+
+               public string GetComponentName()
+               {
+                       throw new NotImplementedException();
+               }
+
+               public TypeConverter GetConverter()
+               {
+                       throw new NotImplementedException();
+               }
+
+               public EventDescriptor GetDefaultEvent()
+               {
+                       throw new NotImplementedException();
+               }
+
+               public PropertyDescriptor GetDefaultProperty()
+               {
+                       throw new NotImplementedException();
+               }
+
+               public object GetEditor(Type editorBaseType)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public EventDescriptorCollection GetEvents()
+               {
+                       throw new NotImplementedException();
+               }
+
+               public EventDescriptorCollection GetEvents(Attribute[] 
attributes)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public PropertyDescriptorCollection GetProperties()
+               {
+                       return new PropertyDescriptorCollection(Properties, 
true);
+               }
+
+               protected PropertyDescriptor[] Properties
+               {
+                       get
+                       {
+                               if (properties == null)
+                               {
+                                       properties = GetPropertiesInternal();
+                               }
+                               return properties;
+                       }
+               }
+
+               protected virtual PropertyDescriptor[] GetPropertiesInternal()
+               {
+                       var proxyProperties = type.GetProperties();
+                       var propertyDescriptors = new 
ProxyPropertyDescriptor[proxyProperties.Length];
+                       for (int i = 0; i < proxyProperties.Length; i++)
+                       {
+                               var attributes = 
GetAttributes(proxyProperties[i]);
+                               propertyDescriptors[i] = new 
ProxyPropertyDescriptor(proxyProperties[i].Name,
+                                                                               
     attributes, type);
+                       }
+                       return propertyDescriptors;
+               }
+
+               private Attribute[] GetAttributes(PropertyInfo proxyProperty)
+               {
+                       var customAttributes = 
proxyProperty.GetCustomAttributes(true);
+                       var attributes = new Attribute[customAttributes.Length];
+                       customAttributes.CopyTo(attributes, 0);
+                       return attributes;
+               }
+
+               public PropertyDescriptorCollection GetProperties(Attribute[] 
attributes)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public object GetPropertyOwner(PropertyDescriptor pd)
+               {
+                       throw new NotImplementedException();
+               }
+       }
+}

File [added]: ProxyTypeDescriptor.cs
Delta lines: +26 -7
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/BaseProxyGenerator.cs 
2009-12-29 19:57:09 UTC (rev 6543)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/BaseProxyGenerator.cs 
2009-12-30 09:23:44 UTC (rev 6544)
@@ -16,19 +16,22 @@
 {
        using System;
        using System.Collections.Generic;
+       using System.ComponentModel;
        using System.Diagnostics;
        using System.Reflection;
        using System.Runtime.Serialization;
        using System.Xml.Serialization;
+
        using Castle.Core.Interceptor;
        using Castle.Core.Logging;
+       using Castle.DynamicProxy.ComponentModel;
+       using Castle.DynamicProxy.Contributors;
        using Castle.DynamicProxy.Generators.Emitters;
        using Castle.DynamicProxy.Generators.Emitters.CodeBuilders;
        using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
 #if SILVERLIGHT
        using Castle.DynamicProxy.SilverlightExtensions;
 #endif
-       using Contributors;
 
        /// <summary>
        /// Base class that exposes the common functionalities
@@ -358,24 +361,40 @@
                        throw new ProxyGenerationException("This is a 
DynamicProxy2 error: " + message);
                }
 
-               protected FieldReference CreateInterceptorsField(ClassEmitter 
emitter)
+               protected void CreateInterceptorsField(ClassEmitter emitter)
                {
                        var interceptorsField = 
emitter.CreateField("__interceptors", typeof (IInterceptor[]));
 
 #if !SILVERLIGHT
                        
emitter.DefineCustomAttributeFor<XmlIgnoreAttribute>(interceptorsField);
 #endif
-                       return interceptorsField;
                }
 
-               protected FieldReference CreateSelectorField(ClassEmitter 
emitter)
+               protected void CreateSelectorField(ClassEmitter emitter)
                {
-                       if(ProxyGenerationOptions.Selector== null)
+                       if (ProxyGenerationOptions.Selector == null)
                        {
-                               return null;
+                               return;
                        }
 
-                       return emitter.CreateField("__selector", 
typeof(IInterceptorSelector));
+                       emitter.CreateField("__selector", 
typeof(IInterceptorSelector));
+                       return;
                }
+
+               protected virtual void CreateTypeAttributes(ClassEmitter 
emitter)
+               {
+                       emitter.AddCustomAttributes(ProxyGenerationOptions);
+                       
emitter.DefineCustomAttribute<TypeDescriptionProviderAttribute>(new 
object[]{typeof(ProxyTypeDescriptionProvider)});
+#if !SILVERLIGHT
+                       emitter.DefineCustomAttribute<XmlIncludeAttribute>(new 
object[] { targetType });
+#endif
+               }
+
+               protected virtual void CreateFields(ClassEmitter emitter)
+               {
+                       CreateOptionsField(emitter);
+                       CreateSelectorField(emitter);
+                       CreateInterceptorsField(emitter);
+               }
        }

Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/
==================================================================

File [modified]: BaseProxyGenerator.cs
Delta lines: +5 -8
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/ClassProxyGenerator.cs    
    2009-12-29 19:57:09 UTC (rev 6543)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/ClassProxyGenerator.cs    
    2009-12-30 09:23:44 UTC (rev 6544)
@@ -16,6 +16,7 @@
 {
        using System;
        using System.Collections.Generic;
+       using System.ComponentModel;
        using System.Reflection;
 #if !SILVERLIGHT
        using System.Xml.Serialization;
@@ -107,16 +108,11 @@
                        ProxyGenerationOptions.Hook.MethodsInspected();
 
                        var emitter = BuildClassEmitter(newName, targetType, 
implementedInterfaces);
-                       CreateOptionsField(emitter);
-                       CreateSelectorField(emitter);
-                       emitter.AddCustomAttributes(ProxyGenerationOptions);
 
-#if !SILVERLIGHT
-                       emitter.DefineCustomAttribute<XmlIncludeAttribute>(new 
object[] {targetType});
-#endif
-                       // Fields generations
-                       FieldReference interceptorsField = 
CreateInterceptorsField(emitter);
+                       CreateFields(emitter);
+                       CreateTypeAttributes(emitter);
 
+
                        // Constructor
                        var cctor = GenerateStaticConstructor(emitter);
 
@@ -133,6 +129,7 @@
                        }
 
                        // constructor arguments
+                       var interceptorsField = 
emitter.GetField("__interceptors");
                        constructorArguments.Add(interceptorsField);
                        var selector = emitter.GetField("__selector");

File [modified]: ClassProxyGenerator.cs
Delta lines: +13 -14
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceProxyWithTargetGenerator.cs
  2009-12-29 19:57:09 UTC (rev 6543)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceProxyWithTargetGenerator.cs
  2009-12-30 09:23:44 UTC (rev 6544)
@@ -184,26 +184,17 @@
                        Type baseType = 
ProxyGenerationOptions.BaseTypeForInterfaceProxy;
 
                        emitter = BuildClassEmitter(typeName, baseType, 
interfaces);
-                       CreateOptionsField(emitter);
-                       emitter.AddCustomAttributes(ProxyGenerationOptions);
-#if SILVERLIGHT
-#warning XmlIncludeAttribute is in silverlight, do we want to explore this?
-#else
-                       emitter.DefineCustomAttribute<XmlIncludeAttribute>(new 
object[] {targetType});
-                       emitter.DefineCustomAttribute<SerializableAttribute>();
-#endif
 
-                       // Fields generations
-                       interceptorsField = CreateInterceptorsField(emitter);
+                       CreateFields(emitter, proxyTargetType);
+                       CreateTypeAttributes(emitter);
 
-                       CreateTargetField(emitter, proxyTargetType);
-                       CreateSelectorField(emitter);
-
+                       interceptorsField = emitter.GetField("__interceptors");
                        return baseType;
                }
 
-               private void CreateTargetField(ClassEmitter emitter, Type 
proxyTargetType)
+               private void CreateFields(ClassEmitter emitter, Type 
proxyTargetType)
                {
+                       base.CreateFields(emitter);
                        targetField = emitter.CreateField("__target", 
proxyTargetType);
 
 #if SILVERLIGHT
@@ -213,6 +204,14 @@
 #endif
                }
 
+               protected override void CreateTypeAttributes(ClassEmitter 
emitter)
+               {
+                       base.CreateTypeAttributes(emitter);
+#if (!SILVERLIGHT)
+                       emitter.DefineCustomAttribute<SerializableAttribute>();
+#endif
+               }
+
                protected virtual string GeneratorType
                {

File [modified]: InterfaceProxyWithTargetGenerator.cs
Delta lines: +0 -2
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceProxyWithoutTargetGenerator.cs
       2009-12-29 19:57:09 UTC (rev 6543)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceProxyWithoutTargetGenerator.cs
       2009-12-30 09:23:44 UTC (rev 6544)
@@ -42,7 +42,6 @@
 
                protected override Type GenerateType(string typeName, Type 
proxyTargetType, Type[] interfaces, INamingScope namingScope)
                {
-                       // TODO: this anemic dictionary should be made into a 
real object
                        IEnumerable<ITypeContributor> contributors;
                        var allInterfaces = 
GetTypeImplementerMapping(interfaces, targetType, out contributors,namingScope);
                        
@@ -73,7 +72,6 @@
                                if (contributor is MixinContributor)
                                {
                                        mixinFieldsList.AddRange((contributor 
as MixinContributor).Fields);
-
                                }
                        }

File [modified]: InterfaceProxyWithoutTargetGenerator.cs
Delta lines: +0 -2
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/IProxyGenerationHook.cs  
2009-12-29 19:57:09 UTC (rev 6543)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/IProxyGenerationHook.cs  
2009-12-30 09:23:44 UTC (rev 6544)
@@ -41,8 +41,6 @@
                /// any non-virtual member of a type that has been requested to 
be proxied, and if
                /// appropriate - throw an exception to notify the caller.
                /// </remarks>
-               // TODO: At some point rename this from Member to Method, and 
change the parameter to match the
-               // other methods of this interface.
                void NonVirtualMemberNotification(Type type, MemberInfo 
memberInfo);
 

--

You received this message because you are subscribed to the Google Groups 
"Castle Project Commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-commits?hl=en.


Reply via email to