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.