Finalized WCF ServiceExporter [SPRNET-1001].
Polished WCF integration + QuickStart + Doc.
This commit is contained in:
@@ -242,8 +242,7 @@
|
||||
</object></programlisting>
|
||||
|
||||
<note>
|
||||
<para>This will be shortened using a custom namespce in the 1.2 final
|
||||
release</para>
|
||||
<para>This will be shortened using a custom namespce in a future release</para>
|
||||
</note>
|
||||
|
||||
<para>The value 'serverAppCalculatorEndpoint' refers to the name of an
|
||||
|
||||
@@ -2,31 +2,14 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.WcfQuickStart.ClientApp.2008", "src\Spring.WcfQuickStart.ClientApp\Spring.WcfQuickStart.ClientApp.2008.csproj", "{D58B3101-4433-49C5-B41B-51134424FC42}"
|
||||
EndProject
|
||||
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Spring.WcfQuickStart.Web.2008", "src\Spring.WcfQuickStart.Web.2008\", "{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}"
|
||||
ProjectSection(WebsiteProperties) = preProject
|
||||
TargetFramework = "3.5"
|
||||
ProjectReferences = ""
|
||||
Debug.AspNetCompiler.VirtualPath = "/Spring.WcfQuickStart.Web.2008"
|
||||
Debug.AspNetCompiler.PhysicalPath = "src\Spring.WcfQuickStart.Web.2008\"
|
||||
Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\Spring.WcfQuickStart.Web.2008\"
|
||||
Debug.AspNetCompiler.Updateable = "true"
|
||||
Debug.AspNetCompiler.ForceOverwrite = "true"
|
||||
Debug.AspNetCompiler.FixedNames = "false"
|
||||
Debug.AspNetCompiler.Debug = "True"
|
||||
Release.AspNetCompiler.VirtualPath = "/Spring.WcfQuickStart.Web.2008"
|
||||
Release.AspNetCompiler.PhysicalPath = "src\Spring.WcfQuickStart.Web.2008\"
|
||||
Release.AspNetCompiler.TargetPath = "PrecompiledWeb\Spring.WcfQuickStart.Web.2008\"
|
||||
Release.AspNetCompiler.Updateable = "true"
|
||||
Release.AspNetCompiler.ForceOverwrite = "true"
|
||||
Release.AspNetCompiler.FixedNames = "false"
|
||||
Release.AspNetCompiler.Debug = "False"
|
||||
VWDPort = "2637"
|
||||
DefaultWebSiteLanguage = "Visual C#"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405} = {EEC5B531-104B-44E6-975B-44C0C8973405}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.WcfQuickStart.ServerApp.2008", "src\Spring.WcfQuickStart.ServerApp\Spring.WcfQuickStart.ServerApp.2008.csproj", "{27AAD98C-4281-4DD4-9E20-1371C58C5283}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.WcfQuickStart.ServerWeb.2008", "src\Spring.WcfQuickStart.ServerWeb\Spring.WcfQuickStart.ServerWeb.2008.csproj", "{EEC5B531-104B-44E6-975B-44C0C8973405}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|.NET = Debug|.NET
|
||||
@@ -47,16 +30,6 @@ Global
|
||||
{D58B3101-4433-49C5-B41B-51134424FC42}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D58B3101-4433-49C5-B41B-51134424FC42}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{D58B3101-4433-49C5-B41B-51134424FC42}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Debug|.NET.ActiveCfg = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Debug|.NET.Build.0 = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Debug|Any CPU.ActiveCfg = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Debug|Mixed Platforms.ActiveCfg = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Debug|Mixed Platforms.Build.0 = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Release|.NET.ActiveCfg = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Release|.NET.Build.0 = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Release|Any CPU.ActiveCfg = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Release|Mixed Platforms.ActiveCfg = Debug|.NET
|
||||
{B71CEEE1-9C92-4C79-94BE-46D6D4CDE95A}.Release|Mixed Platforms.Build.0 = Debug|.NET
|
||||
{27AAD98C-4281-4DD4-9E20-1371C58C5283}.Debug|.NET.ActiveCfg = Debug|Any CPU
|
||||
{27AAD98C-4281-4DD4-9E20-1371C58C5283}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{27AAD98C-4281-4DD4-9E20-1371C58C5283}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
@@ -67,6 +40,16 @@ Global
|
||||
{27AAD98C-4281-4DD4-9E20-1371C58C5283}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{27AAD98C-4281-4DD4-9E20-1371C58C5283}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{27AAD98C-4281-4DD4-9E20-1371C58C5283}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Debug|.NET.ActiveCfg = Debug|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Release|.NET.ActiveCfg = Release|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{EEC5B531-104B-44E6-975B-44C0C8973405}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
<spring>
|
||||
|
||||
<context>
|
||||
<!-- Make sure 'http://localhost:2637/Spring.WcfQuickStart.Web/' web application is running -->
|
||||
<resource uri="assembly://Spring.WcfQuickStart.ClientApp/Spring.WcfQuickStart.Config/Web.xml" />
|
||||
<!-- Make sure 'http://localhost:2637/Spring.WcfQuickStart.ServerWeb/' web application is running -->
|
||||
<resource uri="assembly://Spring.WcfQuickStart.ClientApp/Spring.WcfQuickStart.Config/ServerWeb.xml" />
|
||||
|
||||
<!-- Make sure 'ServerApp' console application is running and listening. -->
|
||||
<!-- Make sure 'Spring.WcfQuickStart.ServerApp' console application is running and listening. -->
|
||||
<resource uri="assembly://Spring.WcfQuickStart.ClientApp/Spring.WcfQuickStart.Config/ServerApp.xml" />
|
||||
</context>
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
</bindings>
|
||||
|
||||
<client>
|
||||
<endpoint name="webCalculatorEndpoint"
|
||||
address="http://localhost:2637/Spring.WcfQuickStart.Web.2008/Calculator.svc"
|
||||
<endpoint name="serverWebCalculatorEndpoint"
|
||||
address="http://localhost:2637/Spring.WcfQuickStart.ServerWeb/Calculator.svc"
|
||||
binding="basicHttpBinding" bindingConfiguration="basicHttpBinding1"
|
||||
contract="Spring.WcfQuickStart.ICalculator" />
|
||||
<endpoint name="serverAppCalculatorEndpoint"
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
|
||||
<!-- returns ChannelFactory<ICalculator>("calculatorEndpoint").CreateChannel() -->
|
||||
<object id="webCalculator"
|
||||
<object id="serverWebCalculator"
|
||||
type="Spring.WcfQuickStart.ICalculator, Spring.WcfQuickStart.ClientApp"
|
||||
factory-object="webCalculatorChannelFactory"
|
||||
factory-object="serverWebCalculatorChannelFactory"
|
||||
factory-method="CreateChannel" />
|
||||
<object id="webCalculatorChannelFactory"
|
||||
<object id="serverWebCalculatorChannelFactory"
|
||||
type="System.ServiceModel.ChannelFactory<Spring.WcfQuickStart.ICalculator>, System.ServiceModel">
|
||||
<constructor-arg name="endpointConfigurationName" value="webCalculatorEndpoint" />
|
||||
<constructor-arg name="endpointConfigurationName" value="serverWebCalculatorEndpoint" />
|
||||
</object>
|
||||
|
||||
</objects>
|
||||
@@ -72,7 +72,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<EmbeddedResource Include="Config\Web.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Config\ServerApp.xml" />
|
||||
@@ -94,6 +93,9 @@
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Config\ServerWeb.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<OldToolsVersion>2.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v3.0</TargetFrameworkVersion>
|
||||
<PublishUrl>http://localhost/Spring.WcfQuickStart.ServerApp/</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Web</InstallFrom>
|
||||
@@ -62,9 +62,6 @@
|
||||
<HintPath>..\..\..\..\..\bin\net\3.0\debug\Spring.Services.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" />
|
||||
<Reference Include="System.Xml" />
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Spring.WcfQuickStart.ServerWeb")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Spring.WcfQuickStart.ServerWeb")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,88 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{EEC5B531-104B-44E6-975B-44C0C8973405}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Spring.WcfQuickStart</RootNamespace>
|
||||
<AssemblyName>Spring.WcfQuickStart.ServerWeb</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Spring.Core, Version=1.2.0.20313, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\bin\net\2.0\debug\Spring.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Spring.Services, Version=1.2.0.30313, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\bin\net\3.0\debug\Spring.Services.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.ServiceModel">
|
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Web.Services" />
|
||||
<Reference Include="System.EnterpriseServices" />
|
||||
<Reference Include="System.Web.Mobile" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CalculatorService.cs" />
|
||||
<Compile Include="ICalculator.cs" />
|
||||
<Content Include="Calculator.svc" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>False</AutoAssignPort>
|
||||
<DevelopmentServerPort>2637</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/Spring.WcfQuickStart.ServerWeb/</DevelopmentServerVPath>
|
||||
<IISUrl>
|
||||
</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -0,0 +1,75 @@
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="spring">
|
||||
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
|
||||
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<spring>
|
||||
|
||||
<context>
|
||||
<resource uri="config://spring/objects"/>
|
||||
</context>
|
||||
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
<!-- Service definition -->
|
||||
<object id="calculator" type="Spring.WcfQuickStart.CalculatorService, Spring.WcfQuickStart.ServerWeb"
|
||||
singleton="false">
|
||||
<property name="SleepInSeconds" value="1"/>
|
||||
</object>
|
||||
</objects>
|
||||
|
||||
</spring>
|
||||
|
||||
<system.serviceModel>
|
||||
<services>
|
||||
<service name="calculator" behaviorConfiguration="DefaultBehavior">
|
||||
<endpoint address="" binding="basicHttpBinding" contract="Spring.WcfQuickStart.ICalculator"/>
|
||||
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
|
||||
</service>
|
||||
</services>
|
||||
<behaviors>
|
||||
<serviceBehaviors>
|
||||
<behavior name="DefaultBehavior">
|
||||
<serviceMetadata httpGetEnabled="True"/>
|
||||
<serviceDebug includeExceptionDetailInFaults="True"/>
|
||||
</behavior>
|
||||
</serviceBehaviors>
|
||||
</behaviors>
|
||||
</system.serviceModel>
|
||||
|
||||
<appSettings/>
|
||||
|
||||
<connectionStrings/>
|
||||
|
||||
<system.web>
|
||||
<!--
|
||||
Set compilation debug="true" to insert debugging
|
||||
symbols into the compiled page. Because this
|
||||
affects performance, set this value to true only
|
||||
during development.
|
||||
-->
|
||||
<compilation debug="true">
|
||||
|
||||
</compilation>
|
||||
<!--
|
||||
The <authentication> section enables configuration
|
||||
of the security authentication mode used by
|
||||
ASP.NET to identify an incoming user.
|
||||
-->
|
||||
<authentication mode="Windows"/>
|
||||
<!--
|
||||
The <customErrors> section enables configuration
|
||||
of what to do if/when an unhandled error occurs
|
||||
during the execution of a request. Specifically,
|
||||
it enables developers to configure html error pages
|
||||
to be displayed in place of a error stack trace.
|
||||
|
||||
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
|
||||
<error statusCode="403" redirect="NoAccess.htm" />
|
||||
<error statusCode="404" redirect="FileNotFound.htm" />
|
||||
</customErrors>
|
||||
-->
|
||||
</system.web>
|
||||
</configuration>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Note: As an alternative to hand editing this file you can use the
|
||||
web admin tool to configure settings for your application. Use
|
||||
the Website->Asp.Net Configuration option in Visual Studio.
|
||||
A full list of settings and comments can be found in
|
||||
machine.config.comments usually located in
|
||||
\Windows\Microsoft.Net\Framework\v2.x\Config
|
||||
-->
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="spring">
|
||||
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
|
||||
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
|
||||
</sectionGroup>
|
||||
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
|
||||
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
|
||||
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
|
||||
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
|
||||
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/></sectionGroup></sectionGroup></sectionGroup></configSections>
|
||||
<spring>
|
||||
<context>
|
||||
<resource uri="config://spring/objects"/>
|
||||
</context>
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
<!-- Service definition -->
|
||||
<object id="calculator" type="Spring.WcfQuickStart.CalculatorService, App_Code" singleton="false">
|
||||
<property name="SleepInSeconds" value="1"/>
|
||||
</object>
|
||||
</objects>
|
||||
</spring>
|
||||
<system.serviceModel>
|
||||
<services>
|
||||
<service name="calculator" behaviorConfiguration="DefaultBehavior">
|
||||
<endpoint address="" binding="basicHttpBinding" contract="Spring.WcfQuickStart.ICalculator"/>
|
||||
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
|
||||
</service>
|
||||
</services>
|
||||
<behaviors>
|
||||
<serviceBehaviors>
|
||||
<behavior name="DefaultBehavior">
|
||||
<serviceMetadata httpGetEnabled="True"/>
|
||||
<serviceDebug includeExceptionDetailInFaults="True"/>
|
||||
</behavior>
|
||||
</serviceBehaviors>
|
||||
</behaviors>
|
||||
</system.serviceModel>
|
||||
<appSettings/>
|
||||
<connectionStrings/>
|
||||
<system.web>
|
||||
<!--
|
||||
Set compilation debug="true" to insert debugging
|
||||
symbols into the compiled page. Because this
|
||||
affects performance, set this value to true only
|
||||
during development.
|
||||
-->
|
||||
<compilation debug="true">
|
||||
<assemblies>
|
||||
<add assembly="System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
|
||||
<add assembly="Microsoft.Transactions.Bridge, Version=3.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
|
||||
<add assembly="SMDiagnostics, Version=3.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.IdentityModel.Selectors, Version=3.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.Messaging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
|
||||
<add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
|
||||
<add assembly="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.Web.RegularExpressions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
|
||||
<add assembly="System.ServiceProcess, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
|
||||
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/></assemblies>
|
||||
</compilation>
|
||||
<!--
|
||||
The <authentication> section enables configuration
|
||||
of the security authentication mode used by
|
||||
ASP.NET to identify an incoming user.
|
||||
-->
|
||||
<authentication mode="Windows"/>
|
||||
<!--
|
||||
The <customErrors> section enables configuration
|
||||
of what to do if/when an unhandled error occurs
|
||||
during the execution of a request. Specifically,
|
||||
it enables developers to configure html error pages
|
||||
to be displayed in place of a error stack trace.
|
||||
|
||||
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
|
||||
<error statusCode="403" redirect="NoAccess.htm" />
|
||||
<error statusCode="404" redirect="FileNotFound.htm" />
|
||||
</customErrors>
|
||||
-->
|
||||
<pages>
|
||||
<controls>
|
||||
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></controls></pages>
|
||||
<httpHandlers>
|
||||
<remove verb="*" path="*.asmx"/>
|
||||
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
<add verb="GET,HEAD" path="ScriptResource.axd" validate="false" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></httpHandlers>
|
||||
<httpModules>
|
||||
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></httpModules></system.web>
|
||||
<system.codedom>
|
||||
<compilers>
|
||||
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
|
||||
<providerOption name="CompilerVersion" value="v3.5"/>
|
||||
<providerOption name="WarnAsError" value="false"/></compiler>
|
||||
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
|
||||
<providerOption name="CompilerVersion" value="v3.5"/>
|
||||
<providerOption name="OptionInfer" value="true"/>
|
||||
<providerOption name="WarnAsError" value="false"/></compiler></compilers></system.codedom>
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false"/>
|
||||
<modules>
|
||||
<remove name="ScriptModule"/>
|
||||
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></modules>
|
||||
<handlers>
|
||||
<remove name="WebServiceHandlerFactory-Integrated"/>
|
||||
<remove name="ScriptHandlerFactory"/>
|
||||
<remove name="ScriptHandlerFactoryAppServices"/>
|
||||
<remove name="ScriptResource"/>
|
||||
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
<add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></handlers></system.webServer>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/></dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/></dependentAssembly></assemblyBinding></runtime></configuration>
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using Spring.Context;
|
||||
|
||||
using Spring.Objects.Factory;
|
||||
|
||||
#endregion
|
||||
@@ -35,8 +35,7 @@ namespace Spring.ServiceModel.Activation
|
||||
/// to host objects created with Spring's IoC container.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
/// <version>$Id: ServiceHostFactory.cs,v 1.2 2007/05/18 21:04:37 bbaia Exp $</version>
|
||||
public class ServiceHostFactoryObject : IFactoryObject, IApplicationContextAware, IInitializingObject, IDisposable
|
||||
public class ServiceHostFactoryObject : IFactoryObject, IInitializingObject, IObjectFactoryAware, IDisposable
|
||||
{
|
||||
#region Logging
|
||||
|
||||
@@ -48,7 +47,11 @@ namespace Spring.ServiceModel.Activation
|
||||
|
||||
private string _targetName;
|
||||
private Uri[] _baseAddresses = new Uri[] { };
|
||||
private IApplicationContext _applicationContext;
|
||||
|
||||
/// <summary>
|
||||
/// The owning factory.
|
||||
/// </summary>
|
||||
protected IObjectFactory objectFactory;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.ServiceModel.SpringServiceHost" /> instance managed by this factory.
|
||||
@@ -97,38 +100,30 @@ namespace Spring.ServiceModel.Activation
|
||||
|
||||
#endregion
|
||||
|
||||
#region IApplicationContextAware Members
|
||||
#region IObjectFactoryAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="Spring.Context.IApplicationContext"/> that this
|
||||
/// object runs in.
|
||||
/// Callback that supplies the owning factory to an object instance.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
/// <value>
|
||||
/// Owning <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// (may not be <see langword="null"/>). The object can immediately
|
||||
/// call methods on the factory.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Normally this call will be used to initialize the object.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an
|
||||
/// init callback such as
|
||||
/// <see cref="Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// or a custom init-method. Invoked after the setting of any
|
||||
/// <see cref="Spring.Context.IResourceLoaderAware"/>'s
|
||||
/// <see cref="Spring.Context.IResourceLoaderAware.ResourceLoader"/>
|
||||
/// property.
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="Spring.Context.ApplicationContextException">
|
||||
/// In the case of application context initialization errors.
|
||||
/// </exception>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// If thrown by any application context methods.
|
||||
/// In case of initialization errors.
|
||||
/// </exception>
|
||||
/// <exception cref="Spring.Objects.Factory.ObjectInitializationException"/>
|
||||
public IApplicationContext ApplicationContext
|
||||
public virtual IObjectFactory ObjectFactory
|
||||
{
|
||||
set { _applicationContext = value; }
|
||||
set { this.objectFactory = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -170,13 +165,13 @@ namespace Spring.ServiceModel.Activation
|
||||
#region IInitializingObject Members
|
||||
|
||||
/// <summary>
|
||||
/// Publish the object
|
||||
/// Publish the object.
|
||||
/// </summary>
|
||||
public void AfterPropertiesSet()
|
||||
public virtual void AfterPropertiesSet()
|
||||
{
|
||||
ValidateConfiguration();
|
||||
|
||||
springServiceHost = new SpringServiceHost(TargetName, _applicationContext, BaseAddresses);
|
||||
springServiceHost = new SpringServiceHost(TargetName, objectFactory, BaseAddresses);
|
||||
|
||||
springServiceHost.Open();
|
||||
|
||||
@@ -207,9 +202,12 @@ namespace Spring.ServiceModel.Activation
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
#region Protected Methods
|
||||
|
||||
private void ValidateConfiguration()
|
||||
/// <summary>
|
||||
/// Validates the configuration.
|
||||
/// </summary>
|
||||
protected virtual void ValidateConfiguration()
|
||||
{
|
||||
if (TargetName == null)
|
||||
{
|
||||
|
||||
@@ -1,221 +1,493 @@
|
||||
#if NET_3_0
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2007 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
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using Spring.Util;
|
||||
using Spring.Context;
|
||||
using Spring.Core.TypeResolution;
|
||||
using Spring.Objects;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.ServiceModel.Support;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Proxy;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.ServiceModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers an object type on the server as a WCF service.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class ServiceExporter : IApplicationContextAware, IObjectFactoryAware, IInitializingObject, IDisposable
|
||||
{
|
||||
#region Logging
|
||||
|
||||
private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(ServiceExporter));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
private string targetName;
|
||||
private string[] _contracts;
|
||||
private IList _typeAttributes = new ArrayList();
|
||||
private IDictionary _memberAttributes = new Hashtable();
|
||||
|
||||
private IApplicationContext applicationContext;
|
||||
private AbstractObjectFactory objectFactory;
|
||||
|
||||
private System.ServiceModel.ServiceHost serviceHost;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor(s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ServiceExporter"/> class.
|
||||
/// </summary>
|
||||
public ServiceExporter()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the target object definition.
|
||||
/// </summary>
|
||||
public string TargetName
|
||||
{
|
||||
get { return targetName; }
|
||||
set { targetName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of service contracts.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If not set, all the interfaces implemented or inherited
|
||||
/// by the target type will be used.
|
||||
/// </remarks>
|
||||
/// <value>The interfaces.</value>
|
||||
public string[] Contracts
|
||||
{
|
||||
get { return _contracts; }
|
||||
set { _contracts = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of custom attributes
|
||||
/// that should be applied to the WCF service class.
|
||||
/// </summary>
|
||||
public IList TypeAttributes
|
||||
{
|
||||
get { return _typeAttributes; }
|
||||
set { _typeAttributes = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a dictionary of custom attributes
|
||||
/// that should be applied to the WCF service members.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Dictionary key is an expression that members can be matched against.
|
||||
/// Value is a list of attributes that should be applied
|
||||
/// to each member that matches expression.
|
||||
/// </remarks>
|
||||
public IDictionary MemberAttributes
|
||||
{
|
||||
get { return _memberAttributes; }
|
||||
set { _memberAttributes = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IApplicationContextAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Spring.Context.IApplicationContext"/> that this
|
||||
/// object runs in.
|
||||
/// </summary>
|
||||
public IApplicationContext ApplicationContext
|
||||
{
|
||||
get { return applicationContext; }
|
||||
set { applicationContext = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IObjectFactoryAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Sets object factory to use.
|
||||
/// </summary>
|
||||
public IObjectFactory ObjectFactory
|
||||
{
|
||||
set { objectFactory = (AbstractObjectFactory) value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IInitializingObject Members
|
||||
|
||||
/// <summary>
|
||||
/// Publish the object
|
||||
/// </summary>
|
||||
public void AfterPropertiesSet()
|
||||
{
|
||||
ValidateConfiguration();
|
||||
Export();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Closes the service host.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
serviceHost.Close();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void ValidateConfiguration()
|
||||
{
|
||||
if (TargetName == null)
|
||||
{
|
||||
throw new ArgumentException("The TargetName property is required.");
|
||||
}
|
||||
}
|
||||
|
||||
private void Export()
|
||||
{
|
||||
string contextName = (applicationContext.Name == AbstractApplicationContext.DefaultRootContextName) ? null : applicationContext.Name;
|
||||
Type targetType = objectFactory.GetType(targetName);
|
||||
IProxyTypeBuilder builder = new ServiceProxyTypeBuilder(targetName, applicationContext, targetType);
|
||||
if (Contracts != null && Contracts.Length > 0)
|
||||
{
|
||||
builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(Contracts);
|
||||
}
|
||||
builder.TypeAttributes = TypeAttributes;
|
||||
builder.MemberAttributes = MemberAttributes;
|
||||
|
||||
Type serviceType = builder.BuildProxyType();
|
||||
|
||||
serviceHost = new System.ServiceModel.ServiceHost(serviceType);
|
||||
serviceHost.Open();
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug(String.Format("The service '{0}' is ready and can now be accessed.", targetName));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#if NET_3_0
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2008 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
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.ServiceModel;
|
||||
using System.Net.Security;
|
||||
|
||||
using Spring.Util;
|
||||
using Spring.Context;
|
||||
using Spring.Core.TypeResolution;
|
||||
using Spring.Objects;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Proxy;
|
||||
using Spring.ServiceModel.Support;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.ServiceModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Exports an object as a WCF service.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class ServiceExporter : IFactoryObject, IInitializingObject, IObjectFactoryAware, IObjectNameAware
|
||||
{
|
||||
#region Logging
|
||||
|
||||
private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(ServiceExporter));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
private string _targetName;
|
||||
private Type _contractInterface;
|
||||
private IList _typeAttributes = new ArrayList();
|
||||
private IDictionary _memberAttributes = new Hashtable();
|
||||
|
||||
private string _name;
|
||||
private string _namespace;
|
||||
private string _configurationName;
|
||||
private Type _callbackContract;
|
||||
private ProtectionLevel _protectionLevel;
|
||||
private SessionMode _sessionMode;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the object in the factory.
|
||||
/// </summary>
|
||||
protected string objectName;
|
||||
|
||||
/// <summary>
|
||||
/// The owning factory.
|
||||
/// </summary>
|
||||
protected IObjectFactory objectFactory;
|
||||
|
||||
/// <summary>
|
||||
/// The generated WCF service wrapper type.
|
||||
/// </summary>
|
||||
private Type proxyType;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor(s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ServiceExporter"/> class.
|
||||
/// </summary>
|
||||
public ServiceExporter()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the target object definition.
|
||||
/// </summary>
|
||||
public string TargetName
|
||||
{
|
||||
get { return _targetName; }
|
||||
set { _targetName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service contract interface type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If not set, uses the unique interface implemented or inherited by the target type.
|
||||
/// An error will be thrown if the target type implements more than one interface.
|
||||
/// </remarks>
|
||||
/// <value>The service contract interface type.</value>
|
||||
public Type ContractInterface
|
||||
{
|
||||
get { return _contractInterface; }
|
||||
set { _contractInterface = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of custom attributes
|
||||
/// that should be applied to the WCF service class.
|
||||
/// </summary>
|
||||
public IList TypeAttributes
|
||||
{
|
||||
get { return _typeAttributes; }
|
||||
set { _typeAttributes = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a dictionary of custom attributes
|
||||
/// that should be applied to the WCF service members.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Dictionary key is an expression that members can be matched against.
|
||||
/// Value is a list of attributes that should be applied
|
||||
/// to each member that matches expression.
|
||||
/// </remarks>
|
||||
public IDictionary MemberAttributes
|
||||
{
|
||||
get { return _memberAttributes; }
|
||||
set { _memberAttributes = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name for the <portType> element in
|
||||
/// Web Services Description Language (WSDL).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The default value is the name of the class or interface to which the
|
||||
/// System.ServiceModel.ServiceContractAttribute is applied.
|
||||
/// </value>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the namespace of the <portType> element in
|
||||
/// Web Services Description Language (WSDL).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The WSDL namespace of the <portType> element. The default value is "http://tempuri.org".
|
||||
/// </value>
|
||||
public string Namespace
|
||||
{
|
||||
get { return _namespace; }
|
||||
set { _namespace = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name used to locate the service in an application configuration file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name used to locate the service element in an application configuration file.
|
||||
/// The default is the name of the service implementation class.
|
||||
/// </value>
|
||||
public string ConfigurationName
|
||||
{
|
||||
get { return _configurationName; }
|
||||
set { _configurationName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of callback contract when the contract is a duplex contract.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="System.Type"/> that indicates the callback contract. The default is null.
|
||||
/// </value>
|
||||
public Type CallbackContract
|
||||
{
|
||||
get { return _callbackContract; }
|
||||
set { _callbackContract = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies whether the binding for the contract must support the value of
|
||||
/// the ProtectionLevel property.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// One of the <see cref="System.Net.Security.ProtectionLevel"/> values.
|
||||
/// The default is <see cref="System.Net.Security.ProtectionLevel.None"/>.
|
||||
/// </value>
|
||||
public ProtectionLevel ProtectionLevel
|
||||
{
|
||||
get { return _protectionLevel; }
|
||||
set { _protectionLevel = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether sessions are allowed, not allowed or required.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="System.ServiceModel.SessionMode"/> that indicates whether sessions are allowed,
|
||||
/// not allowed, or required.
|
||||
/// </value>
|
||||
public SessionMode SessionMode
|
||||
{
|
||||
get { return _sessionMode; }
|
||||
set { _sessionMode = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IObjectFactoryAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Callback that supplies the owning factory to an object instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Owning <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// (may not be <see langword="null"/>). The object can immediately
|
||||
/// call methods on the factory.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of initialization errors.
|
||||
/// </exception>
|
||||
public virtual IObjectFactory ObjectFactory
|
||||
{
|
||||
set { this.objectFactory = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IInitializingObject Members
|
||||
|
||||
/// <summary>
|
||||
/// Publish the object
|
||||
/// </summary>
|
||||
public void AfterPropertiesSet()
|
||||
{
|
||||
ValidateConfiguration();
|
||||
GenerateProxy();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IFactoryObject Members
|
||||
|
||||
/// <summary>
|
||||
/// Return an instance (possibly shared or independent) of the object
|
||||
/// managed by this factory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <note type="caution">
|
||||
/// If this method is being called in the context of an enclosing IoC container and
|
||||
/// returns <see langword="null"/>, the IoC container will consider this factory
|
||||
/// object as not being fully initialized and throw a corresponding (and most
|
||||
/// probably fatal) exception.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// An instance (possibly shared or independent) of the object managed by
|
||||
/// this factory.
|
||||
/// </returns>
|
||||
public object GetObject()
|
||||
{
|
||||
return proxyType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the <see cref="System.Type"/> of object that this
|
||||
/// <see cref="Spring.Objects.Factory.IFactoryObject"/> creates, or
|
||||
/// <see langword="null"/> if not known in advance.
|
||||
/// </summary>
|
||||
public Type ObjectType
|
||||
{
|
||||
get { return typeof(Type); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the object managed by this factory a singleton or a prototype?
|
||||
/// </summary>
|
||||
public bool IsSingleton
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IObjectNameAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Set the name of the object in the object factory that created this object.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name of the object in the factory.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="IInitializingObject.AfterPropertiesSet"/>'s
|
||||
/// <see cref="IInitializingObject"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public string ObjectName
|
||||
{
|
||||
set { this.objectName = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Validates the configuration.
|
||||
/// </summary>
|
||||
protected virtual void ValidateConfiguration()
|
||||
{
|
||||
if (TargetName == null)
|
||||
{
|
||||
throw new ArgumentException("The TargetName property is required.");
|
||||
}
|
||||
if (ContractInterface != null && !ContractInterface.IsInterface)
|
||||
{
|
||||
throw new ArgumentException("ContractInterface must be an interface.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the WCF service wrapper type.
|
||||
/// </summary>
|
||||
protected virtual void GenerateProxy()
|
||||
{
|
||||
IProxyTypeBuilder builder = new ConfigurableServiceProxyTypeBuilder(TargetName, this.objectName, objectFactory,
|
||||
Name, Namespace, ConfigurationName, CallbackContract, ProtectionLevel, SessionMode);
|
||||
if (ContractInterface != null)
|
||||
{
|
||||
builder.Interfaces = new Type[] { ContractInterface };
|
||||
}
|
||||
builder.TypeAttributes = TypeAttributes;
|
||||
builder.MemberAttributes = MemberAttributes;
|
||||
|
||||
proxyType = builder.BuildProxyType();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ConfigurableServiceProxyTypeBuilder inner class implementation
|
||||
|
||||
/// <summary>
|
||||
/// Builds a WCF service type.
|
||||
/// </summary>
|
||||
private sealed class ConfigurableServiceProxyTypeBuilder : ServiceProxyTypeBuilder
|
||||
{
|
||||
private CustomAttributeBuilder serviceContractAttribute;
|
||||
|
||||
public ConfigurableServiceProxyTypeBuilder(string targetName, string objectName, IObjectFactory objectFactory,
|
||||
string name, string ns, string configurationName, Type callbackContract, ProtectionLevel protectionLevel, SessionMode sessionMode)
|
||||
: base(targetName, objectName, objectFactory)
|
||||
{
|
||||
if (!StringUtils.HasText(configurationName))
|
||||
{
|
||||
name = this.Interfaces[0].Name;
|
||||
configurationName = this.Interfaces[0].FullName;
|
||||
}
|
||||
|
||||
// Creates a ServiceContractAttribute from configuration info
|
||||
this.serviceContractAttribute = CreateServiceContractAttribute(name, ns, configurationName, callbackContract, protectionLevel, sessionMode);
|
||||
}
|
||||
|
||||
private static CustomAttributeBuilder CreateServiceContractAttribute(string name, string ns, string configurationName,
|
||||
Type callbackContract, ProtectionLevel protectionLevel, SessionMode sessionMode)
|
||||
{
|
||||
ReflectionUtils.CustomAttributeBuilderBuilder scbb =
|
||||
new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(ServiceContractAttribute));
|
||||
if (StringUtils.HasText(name))
|
||||
{
|
||||
scbb.AddPropertyValue("Name", name);
|
||||
}
|
||||
if (StringUtils.HasText(ns))
|
||||
{
|
||||
scbb.AddPropertyValue("Namespace", ns);
|
||||
}
|
||||
if (StringUtils.HasText(configurationName))
|
||||
{
|
||||
scbb.AddPropertyValue("ConfigurationName", configurationName);
|
||||
}
|
||||
if (callbackContract != null)
|
||||
{
|
||||
scbb.AddPropertyValue("CallbackContract", callbackContract);
|
||||
}
|
||||
if (protectionLevel != ProtectionLevel.None)
|
||||
{
|
||||
scbb.AddPropertyValue("ProtectionLevel", protectionLevel);
|
||||
}
|
||||
if (sessionMode != SessionMode.Allowed)
|
||||
{
|
||||
scbb.AddPropertyValue("SessionMode", sessionMode);
|
||||
}
|
||||
return scbb.Build();
|
||||
}
|
||||
|
||||
protected override IList GetTypeAttributes(Type type)
|
||||
{
|
||||
IList attrs = base.GetTypeAttributes(type);
|
||||
|
||||
bool containsServiceContractAttribute = false;
|
||||
|
||||
for (int i = 0; i < attrs.Count; i++)
|
||||
{
|
||||
if (IsAttributeMatchingType(attrs[i], typeof(ServiceContractAttribute)))
|
||||
{
|
||||
// Override existing ServiceContractAttribute
|
||||
containsServiceContractAttribute = true;
|
||||
attrs[i] = serviceContractAttribute;
|
||||
}
|
||||
}
|
||||
|
||||
// Add missing ServiceContractAttribute
|
||||
if (!containsServiceContractAttribute)
|
||||
{
|
||||
attrs.Add(serviceContractAttribute);
|
||||
}
|
||||
|
||||
return attrs;
|
||||
}
|
||||
|
||||
protected override IList GetMethodAttributes(MethodInfo method)
|
||||
{
|
||||
IList attrs = base.GetMethodAttributes(method);
|
||||
|
||||
bool containsOperationContractAttribute = false;
|
||||
foreach (object attr in attrs)
|
||||
{
|
||||
if (IsAttributeMatchingType(attr, typeof(OperationContractAttribute)))
|
||||
{
|
||||
containsOperationContractAttribute = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates default OperationContractAttribute if not set yet
|
||||
if (!containsOperationContractAttribute)
|
||||
{
|
||||
attrs.Add(ReflectionUtils.CreateCustomAttribute(typeof(OperationContractAttribute)));
|
||||
}
|
||||
|
||||
return attrs;
|
||||
}
|
||||
|
||||
protected override Type[] GetProxiableInterfaces(Type[] interfaces)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -27,6 +27,7 @@ using Spring.Util;
|
||||
using Spring.Context;
|
||||
using Spring.Context.Support;
|
||||
using Spring.ServiceModel.Support;
|
||||
using Spring.Objects.Factory;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -65,10 +66,10 @@ namespace Spring.ServiceModel
|
||||
/// Creates a new instance of the <see cref="Spring.ServiceModel.SpringServiceHost"/> class.
|
||||
/// </summary>
|
||||
/// <param name="serviceName">The name of the service within Spring's IoC container.</param>
|
||||
/// <param name="applicationContext">The <see cref="IApplicationContext"/> to use.</param>
|
||||
/// <param name="objectFactory">The <see cref="IObjectFactory"/> to use.</param>
|
||||
/// <param name="baseAddresses">The base addresses for the hosted service.</param>
|
||||
public SpringServiceHost(string serviceName, IApplicationContext applicationContext, params Uri[] baseAddresses)
|
||||
: base(CreateServiceType(serviceName, applicationContext), baseAddresses)
|
||||
public SpringServiceHost(string serviceName, IObjectFactory objectFactory, params Uri[] baseAddresses)
|
||||
: base(CreateServiceType(serviceName, objectFactory), baseAddresses)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -84,16 +85,21 @@ namespace Spring.ServiceModel
|
||||
}
|
||||
}
|
||||
|
||||
private static Type CreateServiceType(string serviceName, IApplicationContext applicationContext)
|
||||
private static Type CreateServiceType(string serviceName, IObjectFactory objectFactory)
|
||||
{
|
||||
if (StringUtils.IsNullOrEmpty(serviceName))
|
||||
{
|
||||
throw new ArgumentException("The service name cannot be null or an empty string.", "serviceName");
|
||||
}
|
||||
|
||||
Type serviceType = applicationContext.GetType(serviceName);
|
||||
|
||||
return new ServiceProxyTypeBuilder(serviceName, applicationContext, serviceType).BuildProxyType();
|
||||
if (objectFactory.IsTypeMatch(serviceName, typeof(Type)))
|
||||
{
|
||||
return objectFactory.GetObject(serviceName) as Type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ServiceProxyTypeBuilder(serviceName, objectFactory).BuildProxyType();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -25,9 +25,8 @@ using System;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
using Spring.Proxy;
|
||||
using Spring.Context;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Proxy;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -44,13 +43,13 @@ namespace Spring.ServiceModel.Support
|
||||
private static readonly MethodInfo GetObject =
|
||||
typeof(IObjectFactory).GetMethod("GetObject", new Type[] { typeof(string) });
|
||||
|
||||
private IApplicationContext applicationContext;
|
||||
private string serviceName;
|
||||
private IObjectFactory objectFactory;
|
||||
private string targetName;
|
||||
|
||||
/// <summary>
|
||||
/// Target instance calls should be delegated to.
|
||||
/// </summary>
|
||||
protected FieldBuilder applicationContextField;
|
||||
protected FieldBuilder objectFactoryField;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -60,16 +59,28 @@ namespace Spring.ServiceModel.Support
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.ServiceModel.Support.ServiceProxyTypeBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="serviceName">The name of the service within Spring's IoC container.</param>
|
||||
/// <param name="applicationContext">The <see cref="IApplicationContext"/> to use.</param>
|
||||
/// <param name="serviceType">The type of the service.</param>
|
||||
public ServiceProxyTypeBuilder(string serviceName, IApplicationContext applicationContext, Type serviceType)
|
||||
/// <param name="targetName">The name of the service within Spring's IoC container.</param>
|
||||
/// <param name="objectFactory">The <see cref="IObjectFactory"/> to use.</param>
|
||||
public ServiceProxyTypeBuilder(string targetName, IObjectFactory objectFactory)
|
||||
: this(targetName, targetName, objectFactory)
|
||||
{
|
||||
this.serviceName = serviceName;
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
this.Name = serviceName;
|
||||
this.TargetType = serviceType;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.ServiceModel.Support.ServiceProxyTypeBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="targetName">The name of the service within Spring's IoC container.</param>
|
||||
/// <param name="serviceTypeName">The name of the generated WCF service <see cref="System.Type"/>.</param>
|
||||
/// <param name="objectFactory">The <see cref="IObjectFactory"/> to use.</param>
|
||||
public ServiceProxyTypeBuilder(string targetName, string serviceTypeName, IObjectFactory objectFactory)
|
||||
{
|
||||
this.targetName = targetName;
|
||||
this.objectFactory = objectFactory;
|
||||
|
||||
this.Name = serviceTypeName;
|
||||
this.TargetType = objectFactory.GetType(targetName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -77,8 +88,8 @@ namespace Spring.ServiceModel.Support
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates a proxy that delegates calls to an instance of the
|
||||
/// target object. This overriden implementation also sets the field __applicationContext.
|
||||
/// Creates a proxy that delegates calls to an instance of the target object.
|
||||
/// This overriden implementation also sets the field __objectFactory.
|
||||
/// </summary>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If the <see cref="IProxyTypeBuilder.TargetType"/>
|
||||
@@ -88,8 +99,8 @@ namespace Spring.ServiceModel.Support
|
||||
{
|
||||
Type proxyType = base.BuildProxyType();
|
||||
|
||||
FieldInfo field = proxyType.GetField("__applicationContext", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
field.SetValue(proxyType, applicationContext);
|
||||
FieldInfo field = proxyType.GetField("__objectFactory", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
field.SetValue(proxyType, objectFactory);
|
||||
|
||||
return proxyType;
|
||||
}
|
||||
@@ -117,8 +128,8 @@ namespace Spring.ServiceModel.Support
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldsfld, applicationContextField);
|
||||
il.Emit(OpCodes.Ldstr, serviceName);
|
||||
il.Emit(OpCodes.Ldsfld, objectFactoryField);
|
||||
il.Emit(OpCodes.Ldstr, targetName);
|
||||
il.EmitCall(OpCodes.Callvirt, GetObject, null);
|
||||
il.Emit(OpCodes.Stfld, targetInstance);
|
||||
|
||||
@@ -135,7 +146,7 @@ namespace Spring.ServiceModel.Support
|
||||
{
|
||||
TypeBuilder typeBuilder = DynamicProxyManager.CreateTypeBuilder(name, baseType);
|
||||
|
||||
applicationContextField = typeBuilder.DefineField("__applicationContext", typeof(IApplicationContext),
|
||||
objectFactoryField = typeBuilder.DefineField("__objectFactory", typeof(IObjectFactory),
|
||||
FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly);
|
||||
|
||||
return typeBuilder;
|
||||
|
||||
@@ -22,10 +22,17 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Net.Security;
|
||||
using System.ServiceModel;
|
||||
|
||||
using NUnit.Framework;
|
||||
using Spring.ServiceModel;
|
||||
using Spring.Core.IO;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -35,47 +42,10 @@ namespace Spring.ServiceModel
|
||||
/// Unit tests for the ServiceExporter class.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
/// <version>$Id: ServiceExporterTests.cs,v 1.1 2007/09/21 14:27:35 bbaia Exp $</version>
|
||||
[TestFixture]
|
||||
public sealed class ServiceExporterTests
|
||||
{
|
||||
|
||||
#region Test classes
|
||||
|
||||
public interface IService
|
||||
{
|
||||
string SomeMethod(int param);
|
||||
}
|
||||
|
||||
[ServiceContract(Namespace = "http://Spring.Services.Tests")]
|
||||
public interface IDecoratedService
|
||||
{
|
||||
[OperationContract]
|
||||
string SomeMethod(int param);
|
||||
}
|
||||
|
||||
public class Service : IDecoratedService
|
||||
{
|
||||
public string SomeMethod(int param)
|
||||
{
|
||||
return param.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
[ServiceContract(Namespace = "http://Spring.Services.Tests")]
|
||||
public class DecoratedService : IService
|
||||
{
|
||||
[OperationContract]
|
||||
public string SomeMethod(int param)
|
||||
{
|
||||
return param.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/*
|
||||
WebServiceExporter wse = null;
|
||||
ServiceExporter se = null;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
@@ -83,177 +53,185 @@ namespace Spring.ServiceModel
|
||||
const string xml =
|
||||
@"<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<objects xmlns='http://www.springframework.net'>
|
||||
<object id='noDecoratedService' type='Spring.Web.Services.WebServiceExporterTests+NoDecoratedService, Spring.Web.Tests'/>
|
||||
<object id='decoratedService' type='Spring.Web.Services.WebServiceExporterTests+DecoratedService, Spring.Web.Tests'/>
|
||||
<object id='service' type='Spring.ServiceModel.ServiceExporterTests+Service, Spring.Services.Tests'/>
|
||||
<object id='decoratedService' type='Spring.ServiceModel.ServiceExporterTests+DecoratedService, Spring.Services.Tests'/>
|
||||
</objects>";
|
||||
Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
|
||||
IObjectFactory objectFactory = new XmlObjectFactory(new InputStreamResource(stream, string.Empty));
|
||||
|
||||
wse = new WebServiceExporter();
|
||||
wse.ObjectFactory = objectFactory;
|
||||
se = new ServiceExporter();
|
||||
se.ObjectFactory = objectFactory;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ArgumentException), "The TargetName property is required.")]
|
||||
[ExpectedException(typeof(ArgumentException), ExpectedMessage = "The TargetName property is required.")]
|
||||
public void NullConfig()
|
||||
{
|
||||
wse.ObjectName = "NullConfig";
|
||||
wse.AfterPropertiesSet();
|
||||
se.ObjectName = "NullConfig";
|
||||
se.AfterPropertiesSet();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ProxiesTargetInterfaces()
|
||||
public void ProxiesContractInterface()
|
||||
{
|
||||
wse.ObjectName = "ProxiesTargetInterfaces";
|
||||
wse.TargetName = "noDecoratedService";
|
||||
wse.AfterPropertiesSet();
|
||||
se.ObjectName = "ProxiesContractInterface";
|
||||
se.TargetName = "service";
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = wse.ObjectType;
|
||||
Assert.IsTrue(typeof(IService).IsAssignableFrom(proxyType));
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
Assert.IsTrue(typeof(IContract).IsAssignableFrom(proxyType));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreatesWebServiceAttributeWithNoDecoratedClassAndMinimalConfig()
|
||||
public void ProxyTypeEqualsObjectName()
|
||||
{
|
||||
wse.ObjectName = "CreatesWebServiceAttributeWithNoDecoratedClassAndMinimalConfig";
|
||||
wse.TargetName = "noDecoratedService";
|
||||
wse.AfterPropertiesSet();
|
||||
se.ObjectName = "ProxyTypeEqualsObjectName";
|
||||
se.TargetName = "service";
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = wse.ObjectType;
|
||||
object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceAttribute), true);
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
Assert.AreEqual("ProxyTypeEqualsObjectName", proxyType.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreatesServiceContractAttributeWithNoDecoratedClassAndMinimalConfig()
|
||||
{
|
||||
se.ObjectName = "CreatesServiceContractAttributeWithNoDecoratedClassAndMinimalConfig";
|
||||
se.TargetName = "service";
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
object[] attrs = proxyType.GetCustomAttributes(typeof(ServiceContractAttribute), true);
|
||||
Assert.IsNotEmpty(attrs);
|
||||
Assert.AreEqual(1, attrs.Length);
|
||||
|
||||
WebServiceAttribute wsa = attrs[0] as WebServiceAttribute;
|
||||
Assert.AreEqual("CreatesWebServiceAttributeWithNoDecoratedClassAndMinimalConfig", wsa.Name);
|
||||
Assert.AreEqual(string.Empty, wsa.Description);
|
||||
Assert.AreEqual(WebServiceAttribute.DefaultNamespace, wsa.Namespace);
|
||||
ServiceContractAttribute sca = attrs[0] as ServiceContractAttribute;
|
||||
Assert.IsNull(sca.CallbackContract);
|
||||
Assert.AreEqual(typeof(IContract).FullName, sca.ConfigurationName);
|
||||
Assert.AreEqual(typeof(IContract).Name, sca.Name);
|
||||
Assert.IsNull(sca.Namespace);
|
||||
Assert.AreEqual(ProtectionLevel.None, sca.ProtectionLevel);
|
||||
Assert.AreEqual(SessionMode.Allowed, sca.SessionMode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreatesWebServiceAttributeWithNoDecoratedClassAndFullConfig()
|
||||
public void CreatesServiceContractAttributeWithNoDecoratedClassAndFullConfig()
|
||||
{
|
||||
wse.ObjectName = "CreatesWebServiceAttributeWithNoDecoratedClassAndFullConfig";
|
||||
wse.TargetName = "noDecoratedService";
|
||||
wse.Name = "My web service name";
|
||||
wse.Description = "My web service description";
|
||||
wse.Namespace = "http://www.springframework.net";
|
||||
wse.AfterPropertiesSet();
|
||||
se.ObjectName = "CreatesServiceContractAttributeWithNoDecoratedClassAndFullConfig";
|
||||
se.TargetName = "service";
|
||||
se.CallbackContract = typeof(IDisposable);
|
||||
se.ConfigurationName = "CustomConfigName";
|
||||
se.Name = "serviceName";
|
||||
se.Namespace = "http://Spring.Services.Tests";
|
||||
se.ProtectionLevel = ProtectionLevel.Sign;
|
||||
se.SessionMode = SessionMode.Required;
|
||||
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = wse.ObjectType;
|
||||
object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceAttribute), true);
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
object[] attrs = proxyType.GetCustomAttributes(typeof(ServiceContractAttribute), true);
|
||||
Assert.IsNotEmpty(attrs);
|
||||
Assert.AreEqual(1, attrs.Length);
|
||||
|
||||
WebServiceAttribute wsa = attrs[0] as WebServiceAttribute;
|
||||
Assert.AreEqual(wse.Name, wsa.Name);
|
||||
Assert.AreEqual(wse.Description, wsa.Description);
|
||||
Assert.AreEqual(wse.Namespace, wsa.Namespace);
|
||||
ServiceContractAttribute sca = attrs[0] as ServiceContractAttribute;
|
||||
Assert.AreEqual(se.CallbackContract, sca.CallbackContract);
|
||||
Assert.AreEqual(se.ConfigurationName, sca.ConfigurationName);
|
||||
Assert.AreEqual(se.Name, sca.Name);
|
||||
Assert.AreEqual(se.Namespace, sca.Namespace);
|
||||
Assert.AreEqual(se.ProtectionLevel, sca.ProtectionLevel);
|
||||
Assert.AreEqual(se.SessionMode, sca.SessionMode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreatesDefaultWebMethodAttributeWithNoDecoratedMethod()
|
||||
public void CreatesDefaultOperationContractAttributeWithNoDecoratedMethod()
|
||||
{
|
||||
wse.ObjectName = "CreatesDefaultWebMethodAttributeWithNoDecoratedMethod";
|
||||
wse.TargetName = "noDecoratedService";
|
||||
wse.AfterPropertiesSet();
|
||||
se.ObjectName = "CreatesDefaultOperationContractAttributeWithNoDecoratedMethod";
|
||||
se.TargetName = "service";
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = wse.ObjectType;
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
MethodInfo method = proxyType.GetMethod("SomeMethod");
|
||||
Assert.IsNotNull(method);
|
||||
|
||||
object[] attrs = method.GetCustomAttributes(typeof(WebMethodAttribute), true);
|
||||
object[] attrs = method.GetCustomAttributes(typeof(OperationContractAttribute), true);
|
||||
Assert.IsNotEmpty(attrs);
|
||||
Assert.AreEqual(1, attrs.Length);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreatesCustomWebMethodAttributeWithNoDecoratedMethod()
|
||||
public void CreatesCustomOperationContractAttributeWithNoDecoratedMethod()
|
||||
{
|
||||
wse.ObjectName = "CreatesCustomWebMethodAttributeWithNoDecoratedMethod";
|
||||
wse.TargetName = "noDecoratedService";
|
||||
wse.MemberAttributes.Add("SomeMethod", new WebMethodAttribute(true)); // default value is false
|
||||
wse.AfterPropertiesSet();
|
||||
OperationContractAttribute oca1 = new OperationContractAttribute();
|
||||
oca1.Name = "MySomeMethod";
|
||||
|
||||
Type proxyType = wse.ObjectType;
|
||||
se.ObjectName = "CreatesCustomOperationContractAttributeWithNoDecoratedMethod";
|
||||
se.TargetName = "service";
|
||||
se.MemberAttributes.Add("SomeMethod", oca1);
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
MethodInfo method = proxyType.GetMethod("SomeMethod");
|
||||
Assert.IsNotNull(method);
|
||||
|
||||
object[] attrs = method.GetCustomAttributes(typeof(WebMethodAttribute), true);
|
||||
object[] attrs = method.GetCustomAttributes(typeof(OperationContractAttribute), true);
|
||||
Assert.IsNotEmpty(attrs);
|
||||
Assert.AreEqual(1, attrs.Length);
|
||||
|
||||
WebMethodAttribute wma = attrs[0] as WebMethodAttribute;
|
||||
Assert.AreEqual(true, wma.EnableSession);
|
||||
OperationContractAttribute oca2 = attrs[0] as OperationContractAttribute;
|
||||
Assert.AreEqual(oca1.Name, oca2.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OverridesExistingWebServiceAttributeWithDecoratedClass()
|
||||
public void OverridesExistingServiceContractAttributeWithDecoratedClass()
|
||||
{
|
||||
wse.ObjectName = "OverridesExistingWebServiceAttributeWithDecoratedClass";
|
||||
wse.TargetName = "decoratedService";
|
||||
wse.AfterPropertiesSet();
|
||||
se.ObjectName = "OverridesExistingServiceContractAttributeWithDecoratedClass";
|
||||
se.TargetName = "decoratedService";
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = wse.ObjectType;
|
||||
object[] attrs = proxyType.GetCustomAttributes(typeof(WebServiceAttribute), true);
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
object[] attrs = proxyType.GetCustomAttributes(typeof(ServiceContractAttribute), true);
|
||||
Assert.IsNotEmpty(attrs);
|
||||
Assert.AreEqual(1, attrs.Length);
|
||||
|
||||
WebServiceAttribute wsa = attrs[0] as WebServiceAttribute;
|
||||
Assert.AreEqual("OverridesExistingWebServiceAttributeWithDecoratedClass", wsa.Name);
|
||||
Assert.AreEqual(string.Empty, wsa.Description);
|
||||
Assert.AreEqual(WebServiceAttribute.DefaultNamespace, wsa.Namespace);
|
||||
ServiceContractAttribute sca = attrs[0] as ServiceContractAttribute;
|
||||
Assert.IsNull(sca.Namespace);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UsesExistingWebMethodAttributeWithDecoratedMethod()
|
||||
public void UsesExistingOperationContractAttributeWithDecoratedMethod()
|
||||
{
|
||||
wse.ObjectName = "UsesExistingWebMethodAttributeWithDecoratedMethod";
|
||||
wse.TargetName = "decoratedService";
|
||||
wse.AfterPropertiesSet();
|
||||
se.ObjectName = "UsesExistingOperationContractAttributeWithDecoratedMethod";
|
||||
se.TargetName = "decoratedService";
|
||||
se.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = wse.ObjectType;
|
||||
Type proxyType = se.GetObject() as Type;
|
||||
Assert.IsNotNull(proxyType);
|
||||
MethodInfo method = proxyType.GetMethod("SomeMethod");
|
||||
Assert.IsNotNull(method);
|
||||
|
||||
object[] attrs = method.GetCustomAttributes(typeof(WebMethodAttribute), true);
|
||||
object[] attrs = method.GetCustomAttributes(typeof(OperationContractAttribute), true);
|
||||
Assert.IsNotEmpty(attrs);
|
||||
Assert.AreEqual(1, attrs.Length);
|
||||
|
||||
WebMethodAttribute wma = attrs[0] as WebMethodAttribute;
|
||||
Assert.AreEqual("SomeMethod description", wma.Description);
|
||||
}
|
||||
|
||||
// TODO : attributes override
|
||||
[Test]
|
||||
[Ignore("Attributes override not implemented.")]
|
||||
public void OverridesExistingWebMethodAttributeWithDecoratedMethod()
|
||||
{
|
||||
wse.ObjectName = "OverridesExistingWebMethodAttributeWithDecoratedMethod";
|
||||
wse.TargetName = "decoratedService";
|
||||
wse.MemberAttributes.Add("SomeMethod", new WebMethodAttribute(true)); // default value is false
|
||||
wse.AfterPropertiesSet();
|
||||
|
||||
Type proxyType = wse.ObjectType;
|
||||
MethodInfo method = proxyType.GetMethod("SomeMethod");
|
||||
Assert.IsNotNull(method);
|
||||
|
||||
object[] attrs = method.GetCustomAttributes(typeof(WebMethodAttribute), true);
|
||||
Assert.IsNotEmpty(attrs);
|
||||
Assert.AreEqual(1, attrs.Length);
|
||||
|
||||
WebMethodAttribute wma = attrs[0] as WebMethodAttribute;
|
||||
Assert.AreEqual(true, wma.EnableSession);
|
||||
OperationContractAttribute oca = attrs[0] as OperationContractAttribute;
|
||||
Assert.AreEqual("MySomeMethod", oca.Name);
|
||||
}
|
||||
|
||||
#region Test classes
|
||||
|
||||
public interface IService
|
||||
public interface IContract
|
||||
{
|
||||
string SomeMethod(int param);
|
||||
}
|
||||
|
||||
public class NoDecoratedService : IService
|
||||
public class Service : IContract
|
||||
{
|
||||
public string SomeMethod(int param)
|
||||
{
|
||||
@@ -261,18 +239,33 @@ namespace Spring.ServiceModel
|
||||
}
|
||||
}
|
||||
|
||||
[WebService(Name = "Decorated service")]
|
||||
public class DecoratedService : IService
|
||||
[ServiceContract(Namespace = "http://Spring.Services.Tests")]
|
||||
public class DecoratedService : IContract
|
||||
{
|
||||
[WebMethod(Description="SomeMethod description")]
|
||||
[OperationContract(Name = "MySomeMethod")]
|
||||
public string SomeMethod(int param)
|
||||
{
|
||||
return param.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
//[ServiceContract(Namespace = "http://Spring.Services.Tests")]
|
||||
//public interface IDecoratedContract
|
||||
//{
|
||||
// [OperationContract]
|
||||
// string SomeMethod(int param);
|
||||
//}
|
||||
|
||||
//public class AnotherService : IDecoratedContract
|
||||
//{
|
||||
// public string SomeMethod(int param)
|
||||
// {
|
||||
// return param.ToString();
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user