WCF Service Exporter does not support contract interfaces that inherit from other interfaces [SPRNET-1464]
This commit is contained in:
@@ -377,23 +377,12 @@ namespace Spring.ServiceModel
|
||||
protected virtual void GenerateProxy()
|
||||
{
|
||||
IProxyTypeBuilder builder = new ConfigurableServiceProxyTypeBuilder(
|
||||
TargetName, this.objectName, this.objectFactory, _useServiceProxyTypeCache,
|
||||
TargetName, this.objectName, this.objectFactory, _useServiceProxyTypeCache, ContractInterface,
|
||||
Name, Namespace, ConfigurationName, CallbackContract, ProtectionLevel, SessionMode);
|
||||
|
||||
if (ContractInterface != null)
|
||||
{
|
||||
builder.Interfaces = new Type[] { ContractInterface };
|
||||
}
|
||||
builder.TypeAttributes = TypeAttributes;
|
||||
builder.MemberAttributes = MemberAttributes;
|
||||
|
||||
if (builder.Interfaces.Length > 1)
|
||||
{
|
||||
throw new ArgumentException(String.Format(
|
||||
"ServiceExporter cannot export service type '{0}' as a WCF service because it implements multiple interfaces. Specify the contract interface to expose via the ContractInterface property.",
|
||||
builder.TargetType));
|
||||
}
|
||||
|
||||
proxyType = builder.BuildProxyType();
|
||||
}
|
||||
|
||||
@@ -406,13 +395,15 @@ namespace Spring.ServiceModel
|
||||
/// </summary>
|
||||
private sealed class ConfigurableServiceProxyTypeBuilder : ServiceProxyTypeBuilder
|
||||
{
|
||||
private Type contractInterface;
|
||||
private CustomAttributeBuilder serviceContractAttribute;
|
||||
private DefaultListableObjectFactory objectFactory;
|
||||
|
||||
public ConfigurableServiceProxyTypeBuilder(string targetName, string objectName, DefaultListableObjectFactory objectFactory, bool useServiceProxyTypeCache, string name, string ns, string configurationName, Type callbackContract, ProtectionLevel protectionLevel, SessionMode sessionMode)
|
||||
public ConfigurableServiceProxyTypeBuilder(string targetName, string objectName, DefaultListableObjectFactory objectFactory, bool useServiceProxyTypeCache, Type contractInterface, string name, string ns, string configurationName, Type callbackContract, ProtectionLevel protectionLevel, SessionMode sessionMode)
|
||||
: base(targetName, objectName, objectFactory, useServiceProxyTypeCache)
|
||||
{
|
||||
this.objectFactory = objectFactory;
|
||||
this.contractInterface = contractInterface;
|
||||
if (!StringUtils.HasText(configurationName))
|
||||
{
|
||||
name = this.Interfaces[0].Name;
|
||||
@@ -505,9 +496,21 @@ namespace Spring.ServiceModel
|
||||
|
||||
protected override Type[] GetProxiableInterfaces(Type[] interfaces)
|
||||
{
|
||||
Type[] proxiableInterfaces = base.GetProxiableInterfaces(interfaces);
|
||||
|
||||
return proxiableInterfaces;
|
||||
if (contractInterface == null)
|
||||
{
|
||||
Type[] proxiableInterfaces = base.GetProxiableInterfaces(interfaces);
|
||||
if (proxiableInterfaces.Length > 1)
|
||||
{
|
||||
throw new ArgumentException(String.Format(
|
||||
"ServiceExporter cannot export service type '{0}' as a WCF service because it implements multiple interfaces. Specify the contract interface to expose via the ContractInterface property.",
|
||||
this.TargetType));
|
||||
}
|
||||
return proxiableInterfaces;
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.GetProxiableInterfaces(new Type[] { this.contractInterface });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace Spring.ServiceModel
|
||||
<object id='service' type='Spring.ServiceModel.ServiceExporterTests+Service, Spring.Services.Tests'/>
|
||||
<object id='serviceWithMultipleInterfaces' type='Spring.ServiceModel.ServiceExporterTests+ServiceWithMultipleInterfaces, Spring.Services.Tests'/>
|
||||
<object id='decoratedService' type='Spring.ServiceModel.ServiceExporterTests+DecoratedService, Spring.Services.Tests'/>
|
||||
<object id='anotherService' type='Spring.ServiceModel.ServiceExporterTests+AnotherService, Spring.Services.Tests'/>
|
||||
</objects>";
|
||||
|
||||
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
|
||||
@@ -161,6 +162,19 @@ namespace Spring.ServiceModel
|
||||
Assert.IsTrue(typeof(IContract).IsAssignableFrom(proxyType));
|
||||
}
|
||||
|
||||
[Test(Description = "https://jira.springsource.org/browse/SPRNET-1464")]
|
||||
public void ProxiesInheritedContractInterface()
|
||||
{
|
||||
se.ObjectName = "ProxiesInheritedContractInterface";
|
||||
se.TargetName = "anotherService";
|
||||
se.ContractInterface = typeof(IInheritedContract);
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
Assert.IsTrue(typeof(IInheritedContract).IsAssignableFrom(proxyType));
|
||||
}
|
||||
|
||||
[Test(Description = "http://jira.springframework.org/browse/SPRNET-1179")]
|
||||
[ExpectedException(typeof(ArgumentException), ExpectedMessage = "ServiceExporter cannot export service type 'Spring.ServiceModel.ServiceExporterTests+ServiceWithMultipleInterfaces' as a WCF service because it implements multiple interfaces. Specify the contract interface to expose via the ContractInterface property.")]
|
||||
public void ProxiesOnlyContractInterfaceFailsIfNoContractInterface()
|
||||
@@ -344,6 +358,24 @@ namespace Spring.ServiceModel
|
||||
}
|
||||
}
|
||||
|
||||
public interface IInheritedContract : IContract
|
||||
{
|
||||
string AnotherMethod(int param);
|
||||
}
|
||||
|
||||
public class AnotherService : IInheritedContract
|
||||
{
|
||||
public string SomeMethod(int param)
|
||||
{
|
||||
return param.ToString();
|
||||
}
|
||||
|
||||
public string AnotherMethod(int param)
|
||||
{
|
||||
return param.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
//[ServiceContract(Namespace = "http://Spring.Services.Tests")]
|
||||
//public interface IDecoratedContract
|
||||
//{
|
||||
|
||||
Reference in New Issue
Block a user