diff --git a/build-support/solutions/Spring.Net.Core.2008.sln b/build-support/solutions/Spring.Net.Core.2008.sln
index 7214bace..7d77c74d 100644
--- a/build-support/solutions/Spring.Net.Core.2008.sln
+++ b/build-support/solutions/Spring.Net.Core.2008.sln
@@ -15,6 +15,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Aop.2008", "..\..\sr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Aop.Tests.2008", "..\..\test\Spring\Spring.Aop.Tests\Spring.Aop.Tests.2008.csproj", "{2111596A-0327-4C9D-8919-294FBD988A23}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Services.2008", "..\..\src\Spring\Spring.Services\Spring.Services.2008.csproj", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Services.Tests.2008", "..\..\test\Spring\Spring.Services.Tests\Spring.Services.Tests.2008.csproj", "{4374F018-9738-46BF-A399-4594CEE75B21}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|.NET = Debug|.NET
@@ -95,6 +99,26 @@ Global
{2111596A-0327-4C9D-8919-294FBD988A23}.Release|Any CPU.Build.0 = Release|Any CPU
{2111596A-0327-4C9D-8919-294FBD988A23}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{2111596A-0327-4C9D-8919-294FBD988A23}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Debug|.NET.ActiveCfg = Debug|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Release|.NET.ActiveCfg = Release|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Debug|.NET.ActiveCfg = Debug|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Release|.NET.ActiveCfg = Release|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {4374F018-9738-46BF-A399-4594CEE75B21}.Release|Mixed Platforms.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs b/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs
index e24e844b..4df2e96b 100644
--- a/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs
+++ b/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs
@@ -57,13 +57,37 @@ namespace Spring.Web.Services
///
///
/// Aleksandar Seovic
- public class WebServiceExporter : IInitializingObject, IObjectFactoryAware, IFactoryObject, IObjectNameAware
+ public class WebServiceExporter : IInitializingObject, IObjectFactoryAware, IFactoryObject, IObjectNameAware, IDisposable
{
+ ///
+ /// Holds EXPORTER_ID to WebServiceExporter instance mappings.
+ ///
+ private static readonly IDictionary s_activeExporters = new Hashtable();
+
+ ///
+ /// Returns the target object instance exported by the WebServiceExporter identified by .
+ ///
+ ///
+ ///
+ public static object GetTarget( string exporterId )
+ {
+ WebServiceExporter exporterInstance;
+ lock (s_activeExporters.SyncRoot)
+ {
+ exporterInstance = (WebServiceExporter)s_activeExporters[exporterId];
+ }
+ AssertUtils.ArgumentNotNull( exporterInstance, "exporterId", "Remoting Server object is not associated with any active SaoExporter" );
+ object target = exporterInstance.GetTargetInstance();
+ AssertUtils.ArgumentNotNull( target, "exporterId", string.Format( "Failed retrieving target object for SaoExporter ID {0}", exporterId ) );
+ return target;
+ }
+
#region Fields
#if NET_2_0
private WsiProfiles _wsiProfile = WsiProfiles.BasicProfile1_1;
#endif
+ private readonly string EXPORTER_ID = Guid.NewGuid().ToString();
private Type _webServiceBaseType = typeof(WebService);
private string _targetName;
private string _description;
@@ -93,11 +117,52 @@ namespace Spring.Web.Services
#region Constructor(s) / Destructor
///
- /// Creates a new instance of the
- /// class.
+ /// Creates a new instance of the class.
///
public WebServiceExporter()
- {}
+ {
+ lock (s_activeExporters.SyncRoot)
+ {
+ s_activeExporters[EXPORTER_ID] = this;
+ }
+ }
+
+ ///
+ /// Cleanup before GC
+ ///
+ ~WebServiceExporter()
+ {
+ Dispose( false );
+ }
+
+ #region IDisposable Members
+
+ ///
+ /// Disconnect the remote object from the registered remoting channels.
+ ///
+ public void Dispose()
+ {
+ GC.SuppressFinalize( this );
+ Dispose( true );
+ }
+
+ ///
+ /// Stops exporting the object identified by .
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected virtual void Dispose( bool disposing )
+ {
+ if (disposing)
+ {
+ lock (s_activeExporters.SyncRoot)
+ {
+ s_activeExporters.Remove( this.EXPORTER_ID );
+ }
+ objectFactory = null;
+ }
+ }
+
+ #endregion
#endregion
@@ -261,6 +326,11 @@ namespace Spring.Web.Services
#region IFactoryObject Members
+ private object GetTargetInstance()
+ {
+ return objectFactory.GetObject( TargetName );
+ }
+
///
/// Return an instance (possibly shared or independent) of the object
/// managed by this factory.
@@ -365,9 +435,9 @@ namespace Spring.Web.Services
protected virtual void GenerateProxy()
{
#if NET_2_0
- IProxyTypeBuilder builder = new WebServiceProxyTypeBuilder(TargetName, Description, Name, Namespace, WsiProfile);
+ IProxyTypeBuilder builder = new WebServiceProxyTypeBuilder(this, Description, Name, Namespace, WsiProfile);
#else
- IProxyTypeBuilder builder = new WebServiceProxyTypeBuilder(TargetName, Description, Name, Namespace);
+ IProxyTypeBuilder builder = new WebServiceProxyTypeBuilder(this, Description, Name, Namespace);
#endif
builder.Name = WebUtils.GetPageName(objectName);
builder.BaseType = WebServiceBaseType;
@@ -390,13 +460,8 @@ namespace Spring.Web.Services
{
#region Fields
- private static readonly MethodInfo GetObject =
- typeof(IObjectFactory).GetMethod("GetObject", new Type[] {typeof(string)});
-
- private static readonly MethodInfo GetApplicationContext =
- typeof(WebApplicationContext).GetProperty("Current", BindingFlags.Public | BindingFlags.Static, null, typeof(IApplicationContext), Type.EmptyTypes, null).GetGetMethod();
-
- private string targetName;
+ private static readonly MethodInfo WebServiceExporter_GetTargetInstance = typeof( WebServiceExporter ).GetMethod( "GetTarget", new Type[] { typeof( string ) } );
+ private WebServiceExporter exporter;
private CustomAttributeBuilder webServiceAttribute;
#if NET_2_0
private CustomAttributeBuilder webServiceBindingAttribute;
@@ -406,19 +471,17 @@ namespace Spring.Web.Services
#region Constructor(s) / Destructor
- public WebServiceProxyTypeBuilder(
- string targetName, string description, string name, string ns)
+ public WebServiceProxyTypeBuilder(WebServiceExporter exporter, string description, string name, string ns)
{
- this.targetName = targetName;
+ this.exporter = exporter;
// Creates a WebServiceAttribute from configuration info
this.webServiceAttribute = CreateWebServiceAttribute(description, name, ns);
}
#if NET_2_0
- public WebServiceProxyTypeBuilder(
- string targetName, string description, string name, string ns, WsiProfiles wsiProfile)
+ public WebServiceProxyTypeBuilder(WebServiceExporter exporter, string description, string name, string ns, WsiProfiles wsiProfile)
{
- this.targetName = targetName;
+ this.exporter = exporter;
// Creates a WebServiceAttribute from configuration info
this.webServiceAttribute = CreateWebServiceAttribute(description, name, ns);
@@ -466,9 +529,7 @@ namespace Spring.Web.Services
/// Implements constructors for the proxy class.
///
///
- /// This implementation generates a constructor
- /// that gets instance of the target object using
- /// .
+ /// This implementation generates an empty noop default constructor
///
///
/// The builder to use.
@@ -483,17 +544,25 @@ namespace Spring.Web.Services
attributes, CallingConventions.Standard, Type.EmptyTypes);
ILGenerator il = cb.GetILGenerator();
-
- il.Emit(OpCodes.Ldarg_0);
- il.EmitCall(OpCodes.Call, GetApplicationContext, null);
- il.Emit(OpCodes.Ldstr, targetName);
- il.EmitCall(OpCodes.Callvirt, GetObject, null);
- il.Emit(OpCodes.Stfld, targetInstance);
-
-
il.Emit(OpCodes.Ret);
}
+ ///
+ /// Generates the IL instructions that pushes
+ /// the target instance on which calls should be delegated to.
+ ///
+ ///
+ /// This will cause the builder to generate
+ /// WebServiceExporter.GetTarget( EXPORTER_ID ).<targetmethod>(..)
+ /// for each exported method.
+ ///
+ /// The IL generator to use.
+ public override void PushTarget( ILGenerator il )
+ {
+ il.Emit( OpCodes.Ldstr, this.exporter.EXPORTER_ID );
+ il.Emit( OpCodes.Call, WebServiceExporter_GetTargetInstance );
+ }
+
protected override IList GetTypeAttributes(Type type)
{
IList attrs = base.GetTypeAttributes(type);
diff --git a/src/Spring/Spring.Web/Web/Support/LocalResourceManager.cs b/src/Spring/Spring.Web/Web/Support/LocalResourceManager.cs
index 01b05dd6..a3007b5e 100644
--- a/src/Spring/Spring.Web/Web/Support/LocalResourceManager.cs
+++ b/src/Spring/Spring.Web/Web/Support/LocalResourceManager.cs
@@ -33,7 +33,7 @@ namespace Spring.Web.Support
{
///
/// This ResourceManager implementation swallows s and
- /// simply returns null from if no resource is found.
+ /// simply returns null from if no resource is found.
///
/// Erich Eichinger
internal class LocalResourceManager : ResourceManager
@@ -81,7 +81,7 @@ namespace Spring.Web.Support
return HttpContext.GetLocalResourceObject(_virtualPath, name, culture);
//return base.GetObject( name, culture );
}
- catch (MissingManifestResourceException ex)
+ catch (MissingManifestResourceException)
{
_isMissingManifest = true;
}
diff --git a/src/Spring/Spring.Web/Web/UI/Page.cs b/src/Spring/Spring.Web/Web/UI/Page.cs
index 083eac96..e3b1e4bb 100644
--- a/src/Spring/Spring.Web/Web/UI/Page.cs
+++ b/src/Spring/Spring.Web/Web/UI/Page.cs
@@ -1601,10 +1601,9 @@ namespace Spring.Web.UI
// {
// return new LocalResourceManager( VirtualPathUtility.GetFileName( this.AppRelativeVirtualPath ), localResourceAssembly );
// }
+// return null;
return new LocalResourceManager( this.AppRelativeVirtualPath );
- // TODO: investigate HttpContext.GetLocalResourceObject()
- return null;
#endif
}