diff --git a/src/Spring/Spring.Services/ServiceModel/Activation/ServiceHostFactoryObject.cs b/src/Spring/Spring.Services/ServiceModel/Activation/ServiceHostFactoryObject.cs index 14ccdac2..30b8de4e 100644 --- a/src/Spring/Spring.Services/ServiceModel/Activation/ServiceHostFactoryObject.cs +++ b/src/Spring/Spring.Services/ServiceModel/Activation/ServiceHostFactoryObject.cs @@ -46,6 +46,7 @@ namespace Spring.ServiceModel.Activation #region Fields private string _targetName; + private bool _useServiceProxyTypeCache = true; private Uri[] _baseAddresses = new Uri[] { }; /// @@ -86,6 +87,16 @@ namespace Spring.ServiceModel.Activation set { _baseAddresses = value; } } + /// + /// Contorls, wether the underlying should cache + /// the generated proxy types based on the service name. Defaults to true. + /// + public bool UseServiceProxyTypeCache + { + get { return _useServiceProxyTypeCache; } + set { _useServiceProxyTypeCache = value; } + } + #endregion #region Constructor(s) / Destructor @@ -171,7 +182,7 @@ namespace Spring.ServiceModel.Activation { ValidateConfiguration(); - springServiceHost = new SpringServiceHost(TargetName, objectFactory, BaseAddresses); + springServiceHost = new SpringServiceHost(TargetName, objectFactory, UseServiceProxyTypeCache, BaseAddresses); springServiceHost.Open(); diff --git a/src/Spring/Spring.Services/ServiceModel/SpringServiceHost.cs b/src/Spring/Spring.Services/ServiceModel/SpringServiceHost.cs index 92b82ba3..4b8a66da 100644 --- a/src/Spring/Spring.Services/ServiceModel/SpringServiceHost.cs +++ b/src/Spring/Spring.Services/ServiceModel/SpringServiceHost.cs @@ -22,7 +22,7 @@ #region Imports using System; - +using System.Collections; using Spring.Util; using Spring.Context; using Spring.Context.Support; @@ -69,7 +69,19 @@ namespace Spring.ServiceModel /// The to use. /// The base addresses for the hosted service. public SpringServiceHost(string serviceName, IObjectFactory objectFactory, params Uri[] baseAddresses) - : base(CreateServiceType(serviceName, objectFactory), baseAddresses) + : this(serviceName, objectFactory, true, baseAddresses) + { + } + + /// + /// Creates a new instance of the class. + /// + /// The name of the service within Spring's IoC container. + /// The to use. + /// whether to cache the generated service proxy type by + /// The base addresses for the hosted service. + public SpringServiceHost(string serviceName, IObjectFactory objectFactory, bool useServiceProxyTypeCache, params Uri[] baseAddresses) + : base(CreateServiceType(serviceName, objectFactory, useServiceProxyTypeCache), baseAddresses) { } @@ -85,7 +97,9 @@ namespace Spring.ServiceModel } } - private static Type CreateServiceType(string serviceName, IObjectFactory objectFactory) + private static Hashtable s_serviceTypeCache = new Hashtable(); + + private static Type CreateServiceType(string serviceName, IObjectFactory objectFactory, bool useServiceProxyTypeCache) { if (StringUtils.IsNullOrEmpty(serviceName)) { @@ -96,10 +110,26 @@ namespace Spring.ServiceModel { return objectFactory.GetObject(serviceName) as Type; } + + Type serviceType = null; + if (useServiceProxyTypeCache) + { + lock(s_serviceTypeCache) + { + serviceType = (Type) s_serviceTypeCache[serviceName]; + if (serviceType == null) + { + serviceType = new ServiceProxyTypeBuilder(serviceName, objectFactory).BuildProxyType(); + s_serviceTypeCache[serviceName] = serviceType; + } + } + } else { - return new ServiceProxyTypeBuilder(serviceName, objectFactory).BuildProxyType(); + serviceType = new ServiceProxyTypeBuilder(serviceName, objectFactory).BuildProxyType(); } + + return serviceType; } #endregion diff --git a/test/Spring/Spring.Services.Tests/ServiceModel/SpringServiceHostTests.cs b/test/Spring/Spring.Services.Tests/ServiceModel/SpringServiceHostTests.cs new file mode 100644 index 00000000..2be90a9a --- /dev/null +++ b/test/Spring/Spring.Services.Tests/ServiceModel/SpringServiceHostTests.cs @@ -0,0 +1,57 @@ +#region License + +/* + * Copyright 2002-2009 the original author or authors. + * + * 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. + */ + +#endregion + +using System.ServiceModel; +using NUnit.Framework; +using Spring.Objects.Factory.Support; + +namespace Spring.ServiceModel +{ + /// + /// + /// Erich Eichinger + [TestFixture] + public class SpringServiceHostTests + { + [ServiceContract] + public interface IService + { + [OperationContract] + int Add(int a, int b); + } + + internal class Service : IService + { + public int Add(int a, int b) + { + return (a + b); + } + } + + [Test] + public void CanCreateHostTwice() + { + DefaultListableObjectFactory of = new DefaultListableObjectFactory(); + of.RegisterObjectDefinition("service", new RootObjectDefinition(new RootObjectDefinition(typeof(Service)))); + SpringServiceHost ssh = new SpringServiceHost("service", of, true); + SpringServiceHost ssh1 = new SpringServiceHost("service", of, true); + } + } +} \ No newline at end of file diff --git a/test/Spring/Spring.Services.Tests/Spring.Services.Tests.2008.csproj b/test/Spring/Spring.Services.Tests/Spring.Services.Tests.2008.csproj index b3c6bc23..2ff6aa06 100644 --- a/test/Spring/Spring.Services.Tests/Spring.Services.Tests.2008.csproj +++ b/test/Spring/Spring.Services.Tests/Spring.Services.Tests.2008.csproj @@ -111,6 +111,7 @@ +