From 097bda93bd11f64a6ad7133e8ccf00f78898cd7e Mon Sep 17 00:00:00 2001 From: bbaia Date: Mon, 12 Apr 2010 17:34:25 +0000 Subject: [PATCH] Fix WebServiceExporter to allow type-based auto-wiring and auto-proxying [SPRNET-1323] --- .../Script/Services/ScriptHandlerFactory.cs | 12 +++- .../Web/Services/WebServiceExporter.cs | 72 +++++-------------- .../Web/Services/WebServiceHandlerFactory.cs | 21 ++++-- .../Web/Services/WebServiceExporterTests.cs | 26 +++---- 4 files changed, 55 insertions(+), 76 deletions(-) diff --git a/src/Spring/Spring.Web.Extensions/Web/Script/Services/ScriptHandlerFactory.cs b/src/Spring/Spring.Web.Extensions/Web/Script/Services/ScriptHandlerFactory.cs index 4a74fb85..693059a9 100644 --- a/src/Spring/Spring.Web.Extensions/Web/Script/Services/ScriptHandlerFactory.cs +++ b/src/Spring/Spring.Web.Extensions/Web/Script/Services/ScriptHandlerFactory.cs @@ -95,7 +95,17 @@ namespace Spring.Web.Script.Services if (nod != null) { - Type serviceType = appContext.GetType(nod.Name); + Type serviceType = null; + if (appContext.IsTypeMatch(nod.Name, typeof(WebServiceExporter))) + { + WebServiceExporter wse = (WebServiceExporter)appContext.GetObject(nod.Name); + serviceType = wse.GetExportedType(); + } + else + { + serviceType = appContext.GetType(nod.Name); + } + object[] attrs = serviceType.GetCustomAttributes(typeof(ScriptServiceAttribute), false); if (attrs.Length > 0) { diff --git a/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs b/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs index 15415c5a..fa3c916e 100644 --- a/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs +++ b/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs @@ -57,7 +57,7 @@ namespace Spring.Web.Services ///

/// /// Aleksandar Seovic - public class WebServiceExporter : IInitializingObject, IObjectFactoryAware, IFactoryObject, IObjectNameAware, IDisposable + public class WebServiceExporter : IInitializingObject, IObjectFactoryAware, IObjectNameAware, IDisposable { /// /// Holds EXPORTER_ID to WebServiceExporter instance mappings. @@ -330,58 +330,6 @@ namespace Spring.Web.Services #endregion - #region IFactoryObject Members - - private object GetTargetInstance() - { - return objectFactory.GetObject( TargetName ); - } - - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - /// - /// If this method is being called in the context of an enclosing IoC container and - /// returns , the IoC container will consider this factory - /// object as not being fully initialized and throw a corresponding (and most - /// probably fatal) exception. - /// - /// - /// - /// An instance (possibly shared or independent) of the object managed by - /// this factory. - /// - public virtual object GetObject() - { - // no sense to call this method, because the web service type - // will be instantiated by the .NET infrastructure. (ObjectType is used instead) - // Users should use GetObject("TargetName") instead. - return new InvalidOperationException( - "The web service instance is created and managed by the .NET infrastructure."); - } - - /// - /// Return the of object that this - /// creates, or - /// if not known in advance. - /// - public virtual Type ObjectType - { - get { return (proxyType != null ? proxyType : objectFactory.GetType(TargetName)); } - } - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - public virtual bool IsSingleton - { - get { return false; } - } - - #endregion - #region IObjectNameAware Members /// @@ -422,7 +370,16 @@ namespace Spring.Web.Services #endregion - #region Protected Methods + #region Methods + + /// + /// Returns the Web Service wrapper type for the object that is to be exposed. + /// + /// + public virtual Type GetExportedType() + { + return (proxyType != null ? proxyType : objectFactory.GetType(TargetName)); + } /// /// Validates the configuration. @@ -458,6 +415,11 @@ namespace Spring.Web.Services proxyType = builder.BuildProxyType(); } + private object GetTargetInstance() + { + return objectFactory.GetObject(TargetName); + } + #endregion #region WebServiceProxyTypeBuilder inner class implementation @@ -466,7 +428,7 @@ namespace Spring.Web.Services { #region Fields - private static readonly MethodInfo WebServiceExporter_GetTargetInstance = typeof( WebServiceExporter ).GetMethod( "GetTarget", new Type[] { typeof( string ) } ); + private static readonly MethodInfo WebServiceExporter_GetTargetInstance = typeof(WebServiceExporter).GetMethod( "GetTarget", new Type[] { typeof( string ) } ); private WebServiceExporter exporter; private CustomAttributeBuilder webServiceAttribute; #if NET_2_0 diff --git a/src/Spring/Spring.Web/Web/Services/WebServiceHandlerFactory.cs b/src/Spring/Spring.Web/Web/Services/WebServiceHandlerFactory.cs index 65572a52..97beafba 100644 --- a/src/Spring/Spring.Web/Web/Services/WebServiceHandlerFactory.cs +++ b/src/Spring/Spring.Web/Web/Services/WebServiceHandlerFactory.cs @@ -83,14 +83,21 @@ namespace Spring.Web.Services Type serviceType = null; if (nod != null) { - serviceType = appContext.GetType(nod.Name); - - // check if the type defines a Web Service - object[] wsAttribute = serviceType.GetCustomAttributes(typeof(WebServiceAttribute), true); - if (wsAttribute.Length == 0) + if (appContext.IsTypeMatch(nod.Name, typeof(WebServiceExporter))) { - serviceType = null; - } + WebServiceExporter wse = (WebServiceExporter)appContext.GetObject(nod.Name); + serviceType = wse.GetExportedType(); + } + else + { + serviceType = appContext.GetType(nod.Name); + // check if the type defines a Web Service + object[] wsAttribute = serviceType.GetCustomAttributes(typeof(WebServiceAttribute), true); + if (wsAttribute.Length == 0) + { + serviceType = null; + } + } } if (serviceType == null) diff --git a/test/Spring/Spring.Web.Tests/Web/Services/WebServiceExporterTests.cs b/test/Spring/Spring.Web.Tests/Web/Services/WebServiceExporterTests.cs index 2466c2b6..2a56f02b 100644 --- a/test/Spring/Spring.Web.Tests/Web/Services/WebServiceExporterTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/Services/WebServiceExporterTests.cs @@ -78,7 +78,7 @@ namespace Spring.Web.Services wse.TargetName = "noDecoratedService"; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); Assert.IsTrue(typeof(IService).IsAssignableFrom(proxyType)); } @@ -89,7 +89,7 @@ namespace Spring.Web.Services wse.TargetName = "noDecoratedService"; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceAttribute), true); Assert.IsNotEmpty(attrs); Assert.AreEqual(1, attrs.Length); @@ -110,7 +110,7 @@ namespace Spring.Web.Services wse.Namespace = "http://www.springframework.net"; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceAttribute), true); Assert.IsNotEmpty(attrs); Assert.AreEqual(1, attrs.Length); @@ -129,7 +129,7 @@ namespace Spring.Web.Services wse.TargetName = "noDecoratedService"; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceBindingAttribute), true); Assert.IsNotEmpty(attrs); Assert.AreEqual(1, attrs.Length); @@ -146,7 +146,7 @@ namespace Spring.Web.Services wse.WsiProfile = WsiProfiles.None; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceBindingAttribute), true); Assert.IsNotEmpty(attrs); Assert.AreEqual(1, attrs.Length); @@ -162,7 +162,7 @@ namespace Spring.Web.Services wse.TargetName = "decoratedService"; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceBindingAttribute), true); Assert.IsNotEmpty(attrs); Assert.AreEqual(1, attrs.Length); @@ -179,7 +179,7 @@ namespace Spring.Web.Services wse.TargetName = "noDecoratedService"; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); MethodInfo method = proxyType.GetMethod("SomeMethod"); Assert.IsNotNull(method); @@ -196,7 +196,7 @@ namespace Spring.Web.Services wse.MemberAttributes.Add("SomeMethod", new WebMethodAttribute(true)); // default value is false wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); MethodInfo method = proxyType.GetMethod("SomeMethod"); Assert.IsNotNull(method); @@ -215,7 +215,7 @@ namespace Spring.Web.Services wse.TargetName = "decoratedService"; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceAttribute), true); Assert.IsNotEmpty(attrs); Assert.AreEqual(1, attrs.Length); @@ -233,7 +233,7 @@ namespace Spring.Web.Services wse.TargetName = "decoratedService"; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); MethodInfo method = proxyType.GetMethod("SomeMethod"); Assert.IsNotNull(method); @@ -255,7 +255,7 @@ namespace Spring.Web.Services wse.MemberAttributes.Add("SomeMethod", new WebMethodAttribute(true)); // default value is false wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); MethodInfo method = proxyType.GetMethod("SomeMethod"); Assert.IsNotNull(method); @@ -277,7 +277,7 @@ namespace Spring.Web.Services new CustomAttributeBuilder(typeof(WebServiceAttribute).GetConstructor(Type.EmptyTypes), ObjectUtils.EmptyObjects) }; wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceAttribute), true); Assert.IsNotEmpty(attrs); @@ -295,7 +295,7 @@ namespace Spring.Web.Services wse.WebServiceBaseType = typeof(CustomWebService); wse.AfterPropertiesSet(); - Type proxyType = wse.ObjectType; + Type proxyType = wse.GetExportedType(); Assert.IsTrue(typeof(CustomWebService).IsAssignableFrom(proxyType)); }