resolved SPRNET-1109, SPRNET-1095

This commit is contained in:
eeichinger
2008-11-14 17:50:33 +00:00
parent c0233e9b6f
commit 238a44da8f
27 changed files with 1386 additions and 842 deletions

View File

@@ -2,6 +2,9 @@
<configuration>
<configSections>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
@@ -9,6 +12,14 @@
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging">
<arg key="level" value="ALL" />
</factoryAdapter>
</logging>
</common>
<spring>
<parsers>
@@ -23,7 +34,7 @@
<!-- ================================== -->
<!-- In process (local) implementations -->
<!-- ================================== -->
<resource uri="assembly://Spring.Calculator.ClientApp/Spring.Calculator.ClientApp.Config.InProcess/inProcess.xml" />
<!-- resource uri="assembly://Spring.Calculator.ClientApp/Spring.Calculator.ClientApp.Config.InProcess/inProcess.xml" /-->
<!-- ======================== -->
<!-- Remoting implementations -->
@@ -53,7 +64,7 @@
<!-- EnterpriseService implementations -->
<!-- ================================= -->
<!-- Make sure you register components with 'RegisterComponentServices' console application. -->
<!--<resource uri="assembly://Spring.Calculator.ClientApp/Spring.Calculator.ClientApp.Config.EnterpriseServices/enterpriseServices.xml" />-->
<resource uri="assembly://Spring.Calculator.ClientApp/Spring.Calculator.ClientApp.Config.EnterpriseServices/enterpriseServices.xml" />
</context>

View File

@@ -32,7 +32,7 @@ using System.Reflection;
#endif
[assembly: AssemblyCompany("http://www.springframework.net")]
[assembly: AssemblyProduct("Spring.NET Framework")]
[assembly: AssemblyCopyright("Copyright 2002-2006 Spring.NET Framework Team.")]
[assembly: AssemblyCopyright("Copyright 2002-2008 Spring.NET Framework Team.")]
[assembly: AssemblyTrademark("Apache License, Version 2.0")]
#if STRONG

View File

@@ -2,26 +2,30 @@
<configuration>
<configSections>
<sectionGroup name="spring">
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
<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>
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging">
<arg key="level" value="ALL" />
</factoryAdapter>
</logging>
</common>
<spring>
<context>
<resource uri="config://spring/objects" />
<resource uri="Config/services.xml" />
<resource uri="assembly://Spring.Calculator.RegisterComponentServices/Spring.Calculator.RegisterComponentServices.Config/enterpriseServices.xml" />
</context>
<objects xmlns="http://www.springframework.net">
<description>Definitions of objects to be registered.</description>
<object id="calculatorService" type="Spring.Calculator.Services.AdvancedCalculator, Spring.Calculator.Services" />
</objects>
</spring>
</configuration>

View File

@@ -21,15 +21,41 @@
</property>
</object>
<object id="simpleCalculatorComponent" type="Spring.EnterpriseServices.ServicedComponentExporter, Spring.Services">
<property name="TargetName" value="simpleCalculatorService" />
</object>
<object type="Spring.EnterpriseServices.EnterpriseServicesExporter, Spring.Services">
<property name="ApplicationName">
<value>Spring Calculator Application</value>
</property>
<property name="Description">
<value>Spring Calculator application.</value>
<!-- assembly name to generated - will generate 'Spring.Calculator.EnterpriseServices.dll' -->
<property name="Assembly" value="Spring.Calculator.EnterpriseServices" />
<!--
use Spring's ContextRegistry for managing services. if true,
requires a file 'Spring.Calculator.EnterpriseServices.dll.spring-context.xml'
containing a <context /> section placed next to the generated assembly
-->
<property name="UseSpring" value="true" />
<property name="ApplicationName" value="Spring Calculator Application" />
<property name="ActivationMode" value="Library" />
<property name="Description" value="Spring Calculator application" />
<property name="Components">
<list>
<ref object="calculatorComponent" />
<ref object="simpleCalculatorComponent" />
</list>
</property>
<property name="AccessControl">
<object type="System.EnterpriseServices.ApplicationAccessControlAttribute, System.EnterpriseServices">
<property name="Value">
<value>false</value>
</property>
</object>
</property>
<!--
<property name="AccessControl">
<object type="System.EnterpriseServices.ApplicationAccessControlAttribute, System.EnterpriseServices">
<property name="Value">
<value>true</value>
</property>
<property name="AccessChecksLevel">
<value>ApplicationComponent</value>
</property>
@@ -42,14 +68,7 @@
<value>Manager : Administrator role</value>
</list>
</property>
<property name="Components">
<list>
<ref object="calculatorComponent" />
</list>
</property>
<property name="Assembly">
<value>Spring.Calculator.EnterpriseServices</value>
</property>
-->
</object>
</objects>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
<description>Definitions of objects to be registered.</description>
<object id="calculatorService" type="Spring.Calculator.Services.AdvancedCalculator, Spring.Calculator.Services" />
<object id="simpleCalculatorService" type="Spring.Calculator.Services.Calculator, Spring.Calculator.Services" />
</objects>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<context>
<resource uri="Config/services.xml" />
</context>

View File

@@ -17,9 +17,9 @@
DelaySign = "false"
OutputType = "Exe"
PreBuildEvent = ""
PostBuildEvent = ""
PostBuildEvent = "xcopy $(ProjectDir)Spring.Calculator.EnterpriseServices.dll.spring-context.xml $(TargetDir) /Y /F&#xd;&#xa;xcopy $(ProjectDir)Config\*.* $(TargetDir)Config /S /Y /F /I"
RootNamespace = "Spring.Calculator.RegisterComponentServices"
RunPostBuildEvent = "OnBuildSuccess"
RunPostBuildEvent = "Always"
StartupObject = ""
>
<Config
@@ -102,10 +102,18 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Spring.Calculator.EnterpriseServices.dll.spring-context.xml"
BuildAction = "Content"
/>
<File
RelPath = "Config\enterpriseServices.xml"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "Config\services.xml"
BuildAction = "Content"
/>
</Include>
</Files>
</CSHARP>

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <20> 2002-2006 the original author or authors.
* 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.
@@ -20,59 +20,66 @@
#region Imports
using System;
using System.Reflection;
using Common.Logging;
using Spring.Calculator.Interfaces;
#endregion
namespace Spring.Calculator.Services
{
/// <summary>
/// An advanced calculator service.
/// </summary>
/// <summary>
/// An advanced calculator service.
/// </summary>
/// <author>Bruno Baia</author>
/// <version>$Id: AdvancedCalculator.cs,v 1.2 2006/12/04 01:38:42 bbaia Exp $</version>
public class AdvancedCalculator : Calculator, IAdvancedCalculator
{
#region Fields
#region Fields
private int memoryStore = 0;
private int memoryStore = 0;
#endregion
#endregion
#region Constructor(s) / Destructor
#region Constructor(s) / Destructor
public AdvancedCalculator()
{}
public AdvancedCalculator()
: this(0)
{ }
public AdvancedCalculator(int initialMemory)
{
memoryStore = initialMemory;
}
public AdvancedCalculator(int initialMemory)
{
memoryStore = initialMemory;
}
#endregion
#endregion
#region IAdvancedCalculator Members
#region IAdvancedCalculator Members
public int GetMemory()
{
return memoryStore;
}
public int GetMemory()
{
Log.Debug(string.Format("GetMemory: IsInTransaction={0}, at {1}", System.EnterpriseServices.ContextUtil.IsInTransaction, new System.Diagnostics.StackTrace()));
return memoryStore;
}
public void SetMemory(int memoryValue)
{
memoryStore = memoryValue;
}
public void SetMemory(int memoryValue)
{
Log.Debug("SetMemory");
memoryStore = memoryValue;
}
public void MemoryClear()
{
memoryStore = 0;
}
public void MemoryClear()
{
Log.Debug("MemoryClear");
memoryStore = 0;
}
public void MemoryAdd(int num)
{
memoryStore += num;
}
public void MemoryAdd(int num)
{
Log.Debug("MemoryAdd");
memoryStore += num;
}
#endregion
#endregion
}
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <20> 2002-2006 the original author or authors.
* 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.
@@ -20,6 +20,10 @@
#region Imports
using System;
using System.Diagnostics;
using System.Reflection;
using Common.Logging;
using Spring.Calculator.Domain;
using Spring.Calculator.Interfaces;
@@ -31,12 +35,37 @@ namespace Spring.Calculator.Services
/// A calculator service.
/// </summary>
/// <author>Bruno Baia</author>
/// <version>$Id: Calculator.cs,v 1.1 2006/10/29 18:39:13 bbaia Exp $</version>
public class Calculator : ICalculator
{
// SimpleCalculator prints out this value to proof, that they are running within the same AppDomain.
public static volatile int instanceCount;
static Calculator()
{
instanceCount = 0;
ILog log = LogManager.GetLogger(MethodInfo.GetCurrentMethod().DeclaringType);
log.Debug(
string.Format("Initialized Type in AppDomain {0}, ConfigFile={1}, BaseDirectory={2}, CurrentDirectory={3}, ExecutingAssembly={4}, EntryAssembly={5}"
, AppDomain.CurrentDomain.GetHashCode()
, AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
, AppDomain.CurrentDomain.BaseDirectory
, Environment.CurrentDirectory
, Assembly.GetExecutingAssembly().Location
, Assembly.GetEntryAssembly().Location
));
}
#region ICalculator Members
public int Add(int n1, int n2)
protected readonly ILog Log = LogManager.GetLogger(MethodInfo.GetCurrentMethod().DeclaringType);
public Calculator()
{
Log.Debug(string.Format("Initialized Instance in AppDomain {0}, #{0} at {1}", AppDomain.CurrentDomain.GetHashCode(), instanceCount, new System.Diagnostics.StackTrace()));
instanceCount++;
}
public int Add(int n1, int n2)
{
return n1 + n2;
}

View File

@@ -69,6 +69,16 @@
Project = "{284C0873-BBB4-4399-B6F7-CB7EDBD001C7}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
<Reference
Name = "Common.Logging"
AssemblyName = "Common.Logging"
HintPath = "..\..\..\..\..\lib\Net\1.1\Common.Logging.dll"
/>
<Reference
Name = "System.EnterpriseServices"
AssemblyName = "System.EnterpriseServices"
HintPath = "..\..\..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.EnterpriseServices.dll"
/>
</References>
</Build>
<Files>

View File

@@ -18,6 +18,7 @@
<warning number="${nowarn.numbers}" />
</nowarn>
<references basedir="${current.bin.dir}">
<include name="Common.Logging.dll" />
<include name="Spring.Calculator.Contract.dll" />
</references>
</csc>

View File

@@ -11,8 +11,7 @@
<AssemblyKeyContainerName>
</AssemblyKeyContainerName>
<AssemblyName>Spring.Core</AssemblyName>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyFile>..\..\..\Spring.Net.snk</AssemblyOriginatorKeyFile>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
@@ -22,6 +21,7 @@
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<StartupObject>
</StartupObject>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2005\Spring.Core\Debug\</OutputPath>

View File

@@ -46,7 +46,7 @@
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG;NET_2_0;DEBUG_DYNAMIC</DefineConstants>
<DefineConstants>TRACE;DEBUG;NET_2_0;DEBUG_DYNAMICX</DefineConstants>
<DocumentationFile>Spring.Core.xml</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>

View File

@@ -1,229 +1,229 @@
#region License
/*
* Copyright 2002-2004 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.Configuration;
using System.Xml;
#endregion
namespace Spring.Util
{
/// <summary>
/// Utility class for .NET configuration files management.
/// </summary>
/// <author>Aleksandar Seovic</author>
public class ConfigurationUtils
{
/// <summary>
/// Parses the configuration section.
/// </summary>
/// <remarks>
/// <p>
/// Primary purpose of this method is to allow us to parse and
/// load configuration sections using the same API regardless
/// of the .NET framework version.
/// </p>
/// <p>
/// If Microsoft paid a bit more attention to preserving backwards
/// compatibility we would not even need it, but... :(
/// </p>
/// </remarks>
/// <param name="sectionName">Name of the configuration section.</param>
/// <returns>Object created by a corresponding <see cref="IConfigurationSectionHandler"/>.</returns>
public static object GetSection(string sectionName)
{
#if !NET_2_0
return ConfigurationSettings.GetConfig(sectionName.TrimEnd('/'));
#else
return ConfigurationManager.GetSection(sectionName.TrimEnd('/'));
#endif
}
/// <summary>
/// Refresh the configuration section.
/// </summary>
/// <remarks>
/// <p>
/// Primary purpose of this method is to allow us to parse and
/// load configuration sections using the same API regardless
/// of the .NET framework version.
/// </p>
/// <p>
/// If Microsoft paid a bit more attention to preserving backwards
/// compatibility we would not even need it, but... :(
/// </p>
/// </remarks>
/// <param name="sectionName">Name of the configuration section.</param>
public static void RefreshSection(string sectionName)
{
#if !NET_2_0
// TODO : Add support for .NET 1.x
#else
ConfigurationManager.RefreshSection(sectionName);
#endif
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="inner">The inner exception.</param>
/// <param name="fileName">Name of the configuration file.</param>
/// <param name="line">The line where exception occured.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, Exception inner, string fileName, int line)
{
#if !NET_2_0
return new ConfigurationException(message, inner, fileName, line);
#else
return new ConfigurationErrorsException(message, inner, fileName, line);
#endif
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="fileName">Name of the configuration file.</param>
/// <param name="line">The line where exception occured.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, string fileName, int line)
{
return CreateConfigurationException(message, null, fileName, line);
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="inner">The inner exception.</param>
/// <param name="node">XML node where exception occured.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, Exception inner, XmlNode node)
{
#if !NET_2_0
return new ConfigurationException(message, inner, node);
#else
return new ConfigurationErrorsException(message, inner, node);
#endif
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="node">XML node where exception occured.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, XmlNode node)
{
return CreateConfigurationException(message, null, node);
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="inner">The inner exception.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, Exception inner)
{
#if !NET_2_0
return new ConfigurationException(message, inner);
#else
return new ConfigurationErrorsException(message, inner);
#endif
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message)
{
return CreateConfigurationException(message, (Exception) null);
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException()
{
return CreateConfigurationException(null, (Exception) null);
}
/// <summary>
/// Determines whether the specified exception is configuration exception.
/// </summary>
/// <param name="exception">The exception to check.</param>
/// <returns>
/// <c>true</c> if the specified exception is configuration exception; otherwise, <c>false</c>.
/// </returns>
public static bool IsConfigurationException(Exception exception)
{
#if !NET_2_0
return exception is ConfigurationException;
#else
return exception is ConfigurationErrorsException;
#endif
}
/// <summary>
/// Returns the line number of the specified node.
/// </summary>
/// <param name="node">Node to get the line number for.</param>
/// <returns>The line number of the specified node.</returns>
public static int GetLineNumber(XmlNode node)
{
if (node is ITextPosition)
#region License
/*
* Copyright 2002-2004 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.Configuration;
using System.Xml;
#endregion
namespace Spring.Util
{
/// <summary>
/// Utility class for .NET configuration files management.
/// </summary>
/// <author>Aleksandar Seovic</author>
public class ConfigurationUtils
{
/// <summary>
/// Parses the configuration section.
/// </summary>
/// <remarks>
/// <p>
/// Primary purpose of this method is to allow us to parse and
/// load configuration sections using the same API regardless
/// of the .NET framework version.
/// </p>
/// <p>
/// If Microsoft paid a bit more attention to preserving backwards
/// compatibility we would not even need it, but... :(
/// </p>
/// </remarks>
/// <param name="sectionName">Name of the configuration section.</param>
/// <returns>Object created by a corresponding <see cref="IConfigurationSectionHandler"/>.</returns>
public static object GetSection(string sectionName)
{
#if !NET_2_0
return ConfigurationSettings.GetConfig(sectionName.TrimEnd('/'));
#else
return ConfigurationManager.GetSection(sectionName.TrimEnd('/'));
#endif
}
/// <summary>
/// Refresh the configuration section.
/// </summary>
/// <remarks>
/// <p>
/// Primary purpose of this method is to allow us to parse and
/// load configuration sections using the same API regardless
/// of the .NET framework version.
/// </p>
/// <p>
/// If Microsoft paid a bit more attention to preserving backwards
/// compatibility we would not even need it, but... :(
/// </p>
/// </remarks>
/// <param name="sectionName">Name of the configuration section.</param>
public static void RefreshSection(string sectionName)
{
#if !NET_2_0
// TODO : Add support for .NET 1.x
#else
ConfigurationManager.RefreshSection(sectionName);
#endif
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="inner">The inner exception.</param>
/// <param name="fileName">Name of the configuration file.</param>
/// <param name="line">The line where exception occured.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, Exception inner, string fileName, int line)
{
#if !NET_2_0
return new ConfigurationException(message, inner, fileName, line);
#else
return new ConfigurationErrorsException(message, inner, fileName, line);
#endif
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="fileName">Name of the configuration file.</param>
/// <param name="line">The line where exception occured.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, string fileName, int line)
{
return CreateConfigurationException(message, null, fileName, line);
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="inner">The inner exception.</param>
/// <param name="node">XML node where exception occured.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, Exception inner, XmlNode node)
{
#if !NET_2_0
return new ConfigurationException(message, inner, node);
#else
return new ConfigurationErrorsException(message, inner, node);
#endif
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="node">XML node where exception occured.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, XmlNode node)
{
return CreateConfigurationException(message, null, node);
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <param name="inner">The inner exception.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message, Exception inner)
{
#if !NET_2_0
return new ConfigurationException(message, inner);
#else
return new ConfigurationErrorsException(message, inner);
#endif
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <param name="message">The message to display to the client when the exception is thrown.</param>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException(string message)
{
return CreateConfigurationException(message, (Exception) null);
}
/// <summary>
/// Creates the configuration exception.
/// </summary>
/// <returns>Configuration exception.</returns>
public static Exception CreateConfigurationException()
{
return CreateConfigurationException(null, (Exception) null);
}
/// <summary>
/// Determines whether the specified exception is configuration exception.
/// </summary>
/// <param name="exception">The exception to check.</param>
/// <returns>
/// <c>true</c> if the specified exception is configuration exception; otherwise, <c>false</c>.
/// </returns>
public static bool IsConfigurationException(Exception exception)
{
#if !NET_2_0
return exception is ConfigurationException;
#else
return exception is ConfigurationErrorsException;
#endif
}
/// <summary>
/// Returns the line number of the specified node.
/// </summary>
/// <param name="node">Node to get the line number for.</param>
/// <returns>The line number of the specified node.</returns>
public static int GetLineNumber(XmlNode node)
{
if (node is ITextPosition)
{
return ((ITextPosition)node).LineNumber;
}
#if !NET_2_0
return ConfigurationException.GetXmlNodeLineNumber(node);
#else
return ConfigurationErrorsException.GetLineNumber(node);
#endif
}
/// <summary>
/// Returns the name of the file specified node is defined in.
/// </summary>
/// <param name="node">Node to get the file name for.</param>
/// <returns>The name of the file specified node is defined in.</returns>
public static string GetFileName(XmlNode node)
{
if (node is ITextPosition)
}
#if !NET_2_0
return ConfigurationException.GetXmlNodeLineNumber(node);
#else
return ConfigurationErrorsException.GetLineNumber(node);
#endif
}
/// <summary>
/// Returns the name of the file specified node is defined in.
/// </summary>
/// <param name="node">Node to get the file name for.</param>
/// <returns>The name of the file specified node is defined in.</returns>
public static string GetFileName(XmlNode node)
{
if (node is ITextPosition)
{
return ((ITextPosition)node).Filename;
}
#if !NET_2_0
return ConfigurationException.GetXmlNodeFilename(node);
#else
return ConfigurationErrorsException.GetFilename(node);
#endif
}
}
}
#if !NET_2_0
return ConfigurationException.GetXmlNodeFilename(node);
#else
return ConfigurationErrorsException.GetFilename(node);
#endif
}
}
}

View File

@@ -1,317 +1,457 @@
#region License
/*
* Copyright 2002-2006 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
#if (!NET_1_0 && !MONO)
#region Imports
using System;
using System.Collections;
using System.EnterpriseServices;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using Spring.Objects.Factory;
using Spring.Util;
#endregion
namespace Spring.EnterpriseServices
{
/// <summary>
/// Exports specified components as ServicedComponents.
/// </summary>
/// <remarks>
/// <p>
/// This class will create ServicedComponent wrapper for each of the
/// specified components and register them with the Component Services.
/// </p>
/// </remarks>
/// <author>Aleksandar Seovic</author>
public class EnterpriseServicesExporter : IInitializingObject, IObjectFactoryAware
{
#region Fields
private IObjectFactory objectFactory;
private IList components = new ArrayList();
private string applicationName;
private string applicationId;
private ActivationOption activationMode = ActivationOption.Library;
private string description;
private ApplicationAccessControlAttribute accessControl;
private ApplicationQueuingAttribute applicationQueuing;
private IList roles;
private string assemblyName;
#endregion
#region Constructor(s) / Destructor
/// <summary>
/// Creates new enterprise services exporter.
/// </summary>
public EnterpriseServicesExporter()
{
}
#endregion
#region Properties
/// <summary>
/// Gets or sets list of components to export.
/// </summary>
public IList Components
{
get { return components; }
set { components = value; }
}
/// <summary>
/// Gets or sets COM+ application name.
/// </summary>
public string ApplicationName
{
get { return applicationName; }
set { applicationName = value; }
}
/// <summary>
/// Gets or sets application identifier (GUID). Defaults to generated GUID if not specified.
/// </summary>
public string ApplicationId
{
get { return applicationId; }
set { applicationId = value; }
}
/// <summary>
/// Gets or sets application activation mode, which can be either <b>Server</b> or <b>Library</b> (default).
/// </summary>
public ActivationOption ActivationMode
{
get { return activationMode; }
set { activationMode = value; }
}
/// <summary>
/// Gets or sets application description.
/// </summary>
public string Description
{
get { return description; }
set { description = value; }
}
/// <summary>
/// Gets or sets access control attribute.
/// </summary>
public ApplicationAccessControlAttribute AccessControl
{
get { return accessControl; }
set { accessControl = value; }
}
/// <summary>
/// Gets or sets application queuing attribute.
/// </summary>
public ApplicationQueuingAttribute ApplicationQueuing
{
get { return applicationQueuing; }
set { applicationQueuing = value; }
}
/// <summary>
/// Gets or sets application roles.
/// </summary>
public IList Roles
{
get { return roles; }
set { roles = value; }
}
/// <summary>
/// Gets or sets name of the generated assembly that will contain serviced components.
/// </summary>
public string Assembly
{
get { return assemblyName; }
set { assemblyName = value; }
}
#endregion
#region IInitializingObject Members
/// <summary>
/// Called by Spring container after object is configured in order to initialize it.
/// </summary>
public void AfterPropertiesSet()
{
if (roles != null && roles.Count > 0)
{
RefreshRoles();
}
Export();
}
#endregion
#region IObjectFactoryAware Members
/// <summary>
/// Sets object factory instance.
/// </summary>
public IObjectFactory ObjectFactory
{
set { objectFactory = value; }
}
#endregion
#region Public Methods
/// <summary>
/// Creates ServicedComponent wrappers for the specified components and registers
/// them with COM+ Component Services.
/// </summary>
public virtual void Export()
{
AssemblyName an = new AssemblyName();
an.Name = assemblyName;
an.Version = new Version("1.0.0.0");
an.KeyPair = new StrongNameKeyPair(GetKeyPair());
AssemblyBuilder proxyAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder module = proxyAssembly.DefineDynamicModule(assemblyName, assemblyName + ".dll", true);
ApplyAssemblyAttributes(proxyAssembly);
foreach (ServicedComponentExporter definition in components)
{
definition.CreateWrapperType(module, objectFactory);
}
proxyAssembly.Save(assemblyName + ".dll");
RegistrationConfig config = new RegistrationConfig();
config.Application = applicationName;
config.AssemblyFile = AppDomain.CurrentDomain.DynamicDirectory + assemblyName + ".dll";
config.InstallationFlags = InstallationFlags.FindOrCreateTargetApplication;
RegistrationHelper regHelper = new RegistrationHelper();
regHelper.InstallAssemblyFromConfig(ref config);
}
#endregion
#region Private Methods
/// <summary>
/// Reads key pair from embedded resource.
/// </summary>
/// <returns>Key pair as a byte array.</returns>
private byte[] GetKeyPair()
{
using (Stream keys = GetType().Assembly.GetManifestResourceStream("Spring.EnterpriseServices.EnterpriseServices.keys"))
{
byte[] bytes = new byte[keys.Length];
keys.Read(bytes, 0, (int) keys.Length);
return bytes;
}
}
/// <summary>
/// Applies custom attributes to generated assembly.
/// </summary>
/// <param name="assembly">Dynamic assembly to apply attributes to.</param>
private void ApplyAssemblyAttributes(AssemblyBuilder assembly)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationNameAttribute), applicationName));
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationActivationAttribute), activationMode));
if (applicationId != null)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationIDAttribute), applicationId));
}
if (description != null)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(DescriptionAttribute), description));
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(AssemblyDescriptionAttribute), description));
}
if (accessControl != null)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(accessControl));
}
if (applicationQueuing != null)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(applicationQueuing));
}
if (roles != null)
{
foreach (SecurityRoleAttribute role in roles)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(SecurityRoleAttribute),
new object[] {role.Role}, role));
}
}
}
/// <summary>
/// Replaces roles expressed using string with appropriate SecurityRoleAttribute instance.
/// </summary>
private void RefreshRoles()
{
for (int i = 0; i < roles.Count; i++)
{
object role = roles[i];
if (role is string)
{
roles[i] = ParseRole((string) role);
}
}
}
/// <summary>
/// Parses string representation of SecurityRoleAttribute.
/// </summary>
/// <param name="roleString">Role definition string.</param>
/// <returns>Configured SecurityRoleAttribute instance.</returns>
private SecurityRoleAttribute ParseRole(string roleString)
{
string[] parts = roleString.Split(':');
SecurityRoleAttribute role = new SecurityRoleAttribute(parts[0].Trim());
if (parts.Length > 1)
{
role.Description = parts[1].Trim();
}
if (parts.Length > 2)
{
role.SetEveryoneAccess = bool.Parse(parts[2].Trim());
}
return role;
}
#endregion
}
}
#endif // (!NET_1_0)
#region License
/*
* Copyright 2002-2006 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
#if (!NET_1_0 && !MONO)
#region Imports
using System;
using System.Collections;
using System.Diagnostics;
using System.EnterpriseServices;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using Spring.Objects.Factory;
using Spring.Util;
#endregion
namespace Spring.EnterpriseServices
{
/// <summary>
/// Exports specified components as ServicedComponents.
/// </summary>
/// <remarks>
/// <p>
/// This class will create ServicedComponent wrapper for each of the
/// specified components and register them with the Component Services.
/// </p>
/// </remarks>
/// <author>Aleksandar Seovic</author>
public class EnterpriseServicesExporter : IInitializingObject, IObjectFactoryAware
{
#region Fields
private IObjectFactory objectFactory;
private IList components = new ArrayList();
private string applicationName;
private string applicationId;
private ActivationOption activationMode = ActivationOption.Library;
private string description;
private ApplicationAccessControlAttribute accessControl;
private ApplicationQueuingAttribute applicationQueuing;
private IList roles;
private string assemblyName;
private bool useSpring;
#endregion
#region Constructor(s) / Destructor
/// <summary>
/// Creates new enterprise services exporter.
/// </summary>
public EnterpriseServicesExporter()
{
}
#endregion
#region Properties
/// <summary>
/// Gets or sets list of components to export.
/// </summary>
public IList Components
{
get { return components; }
set { components = value; }
}
/// <summary>
/// Gets or sets COM+ application name.
/// </summary>
public string ApplicationName
{
get { return applicationName; }
set { applicationName = value; }
}
/// <summary>
/// Gets or sets application identifier (GUID). Defaults to generated GUID if not specified.
/// </summary>
public string ApplicationId
{
get { return applicationId; }
set { applicationId = value; }
}
/// <summary>
/// Gets or sets application activation mode, which can be either <b>Server</b> or <b>Library</b> (default).
/// </summary>
public ActivationOption ActivationMode
{
get { return activationMode; }
set { activationMode = value; }
}
/// <summary>
/// Gets or sets application description.
/// </summary>
public string Description
{
get { return description; }
set { description = value; }
}
/// <summary>
/// Gets or sets access control attribute.
/// </summary>
public ApplicationAccessControlAttribute AccessControl
{
get { return accessControl; }
set { accessControl = value; }
}
/// <summary>
/// Gets or sets application queuing attribute.
/// </summary>
public ApplicationQueuingAttribute ApplicationQueuing
{
get { return applicationQueuing; }
set { applicationQueuing = value; }
}
/// <summary>
/// Gets or sets application roles.
/// </summary>
public IList Roles
{
get { return roles; }
set { roles = value; }
}
/// <summary>
/// Gets or sets name of the generated assembly that will contain serviced components.
/// </summary>
public string Assembly
{
get { return assemblyName; }
set { assemblyName = value; }
}
///<summary>
/// Use Spring context to configure the serviced components.
///</summary>
public bool UseSpring
{
get { return useSpring; }
set { useSpring = value; }
}
#endregion
#region IInitializingObject Members
/// <summary>
/// Called by Spring container after object is configured in order to initialize it.
/// </summary>
public void AfterPropertiesSet()
{
if (roles != null && roles.Count > 0)
{
RefreshRoles();
}
Export();
}
#endregion
#region IObjectFactoryAware Members
/// <summary>
/// Sets object factory instance.
/// </summary>
public IObjectFactory ObjectFactory
{
set { objectFactory = value; }
}
#endregion
#region Public Methods
/// <summary>
/// Creates ServicedComponent wrappers for the specified components and registers
/// them with COM+ Component Services.
/// </summary>
public virtual void Export()
{
AssemblyName an = new AssemblyName();
an.Name = assemblyName;
an.Version = new Version("1.0.0.0");
an.KeyPair = new StrongNameKeyPair(GetKeyPair());
AssemblyBuilder proxyAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder module = proxyAssembly.DefineDynamicModule(assemblyName, assemblyName + ".dll", true);
ApplyAssemblyAttributes(proxyAssembly);
Type baseType = typeof(ServicedComponent);
if (UseSpring)
{
baseType = CreateSpringServicedComponentType(module);
}
foreach (ServicedComponentExporter definition in components)
{
definition.CreateWrapperType(module, baseType, objectFactory, UseSpring);
}
proxyAssembly.Save(assemblyName + ".dll");
RegistrationConfig config = new RegistrationConfig();
config.Application = applicationName;
config.AssemblyFile = AppDomain.CurrentDomain.DynamicDirectory + assemblyName + ".dll";
config.InstallationFlags = InstallationFlags.ReportWarningsToConsole | InstallationFlags.FindOrCreateTargetApplication | InstallationFlags.ReconfigureExistingApplication;
RegistrationHelper regHelper = new RegistrationHelper();
regHelper.InstallAssemblyFromConfig(ref config);
}
#endregion
#region Private Methods
/// <summary>
/// Reads key pair from embedded resource.
/// </summary>
/// <returns>Key pair as a byte array.</returns>
private byte[] GetKeyPair()
{
using (Stream keys = GetType().Assembly.GetManifestResourceStream("Spring.EnterpriseServices.EnterpriseServices.keys"))
{
byte[] bytes = new byte[keys.Length];
keys.Read(bytes, 0, (int)keys.Length);
return bytes;
}
}
/// <summary>
/// Applies custom attributes to generated assembly.
/// </summary>
/// <param name="assembly">Dynamic assembly to apply attributes to.</param>
private void ApplyAssemblyAttributes(AssemblyBuilder assembly)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationNameAttribute), applicationName));
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationActivationAttribute), activationMode));
if (applicationId != null)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationIDAttribute), applicationId));
}
if (description != null)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(DescriptionAttribute), description));
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(AssemblyDescriptionAttribute), description));
}
if (accessControl != null)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(accessControl));
}
if (applicationQueuing != null)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(applicationQueuing));
}
if (roles != null)
{
foreach (SecurityRoleAttribute role in roles)
{
assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(SecurityRoleAttribute),
new object[] { role.Role }, role));
}
}
}
/// <summary>
/// Replaces roles expressed using string with appropriate SecurityRoleAttribute instance.
/// </summary>
private void RefreshRoles()
{
for (int i = 0; i < roles.Count; i++)
{
object role = roles[i];
if (role is string)
{
roles[i] = ParseRole((string)role);
}
}
}
/// <summary>
/// Parses string representation of SecurityRoleAttribute.
/// </summary>
/// <param name="roleString">Role definition string.</param>
/// <returns>Configured SecurityRoleAttribute instance.</returns>
private SecurityRoleAttribute ParseRole(string roleString)
{
string[] parts = roleString.Split(':');
SecurityRoleAttribute role = new SecurityRoleAttribute(parts[0].Trim());
if (parts.Length > 1)
{
role.Description = parts[1].Trim();
}
if (parts.Length > 2)
{
role.SetEveryoneAccess = bool.Parse(parts[2].Trim());
}
return role;
}
#endregion
#region SpringServicedComponent generation
/// <summary>
/// Creates the SpringServicedComponent base class to derive all <see cref="ServicedComponent"/>s from.
/// </summary>
/// <example>
/// <code>
/// internal class SpringServicedComponent
/// {
/// protected delegate object GetObjectHandler(ServicedComponent servicedComponent, string targetName);
///
/// protected static readonly GetObjectHandler getObjectRef;
///
/// static SpringServicedComponent()
/// {
/// // first look for a local copy
/// System.Reflection.Assembly servicesAssembly;
/// string servicesAssemblyPath = Path.Combine(
/// new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName
/// , &quot;Spring.Services.dll&quot; );
/// servicesAssembly = System.Reflection.Assembly.LoadFrom(servicesAssemblyPath);
/// if (servicesAssembly == null)
/// {
/// // then let the normal loader handle the typeload
/// servicesAssembly = System.Reflection.Assembly.Load(&quot;Spring.Services, culture=neutral, version=x.x.x.x, publicKey=xxxxxxxx&quot;);
/// }
/// Type componentHelperType = servicesAssembly.GetType(&quot;Spring.EnterpriseServices.ServicedComponentHelper&quot;);
/// getObjectRef = (GetObjectHandler) Delegate.CreateDelegate(typeof(GetObjectHandler)
/// , componentHelperType.GetMethod(&quot;GetObject&quot;));
/// }
/// }
///
/// </code>
/// </example>
private Type CreateSpringServicedComponentType(ModuleBuilder module)
{
Type delegateType = DefineDelegate(module);
TypeBuilder typeBuilder = module.DefineType("SpringServicedComponent", System.Reflection.TypeAttributes.Public, typeof(ServicedComponent));
ILGenerator il = null;
FieldBuilder getObjectRef = typeBuilder.DefineField("getObject", delegateType, FieldAttributes.Family | FieldAttributes.Static);
// MethodBuilder assemblyResolveHandler = GenerateOnAssemblyResolve(typeBuilder);
// static SpringServicedComponent() {
// }
ConstructorBuilder typeCtor = typeBuilder.DefineTypeInitializer();
il = typeCtor.GetILGenerator();
Label methodEnd = il.DefineLabel();
Label loadType = il.DefineLabel();
Label tryBegin = il.BeginExceptionBlock();
LocalBuilder fldAssembly = il.DeclareLocal(typeof(Assembly));
LocalBuilder fldType = il.DeclareLocal(typeof(Type));
il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("GetExecutingAssembly"));
il.Emit(OpCodes.Callvirt, typeof(Assembly).GetProperty("Location").GetGetMethod());
il.Emit(OpCodes.Newobj, typeof(FileInfo).GetConstructor(new Type[] {typeof(string)}));
il.Emit(OpCodes.Call, typeof(FileInfo).GetProperty("DirectoryName").GetGetMethod());
il.Emit(OpCodes.Ldstr, new FileInfo(typeof(ServicedComponentHelper).Assembly.Location).Name);
il.Emit(OpCodes.Call, typeof(Path).GetMethod("Combine", new Type[] { typeof(string), typeof(string) }));
il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("LoadFrom", new Type[] { typeof(string)}));
il.Emit(OpCodes.Stloc, fldAssembly);
il.Emit(OpCodes.Ldloc, fldAssembly);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ceq);
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Ceq);
il.Emit(OpCodes.Brtrue_S, loadType);
il.Emit(OpCodes.Ldstr, typeof(ServicedComponentHelper).Assembly.FullName);
il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("Load", new Type[] { typeof(string) }));
il.Emit(OpCodes.Stloc, fldAssembly);
il.MarkLabel(loadType);
il.Emit(OpCodes.Ldloc, fldAssembly);
il.Emit(OpCodes.Ldstr, typeof(ServicedComponentHelper).FullName);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("GetType", new Type[] { typeof(string), typeof(bool) }));
il.Emit(OpCodes.Stloc, fldType);
il.Emit(OpCodes.Ldtoken, delegateType);
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
il.Emit(OpCodes.Ldloc, fldType);
il.Emit(OpCodes.Ldstr, "GetObject");
il.Emit(OpCodes.Callvirt, typeof(Type).GetMethod("GetMethod", new Type[] { typeof(string) }));
il.Emit(OpCodes.Call, typeof(Delegate).GetMethod("CreateDelegate", new Type[] { typeof(Type), typeof(MethodInfo) }));
il.Emit(OpCodes.Castclass, delegateType);
il.Emit(OpCodes.Stsfld, getObjectRef);
il.Emit(OpCodes.Leave_S, methodEnd);
il.BeginCatchBlock(typeof(Exception));
il.Emit(OpCodes.Call, typeof(Trace).GetMethod("WriteLine", new Type[] { typeof(object) }));
il.EndExceptionBlock();
il.MarkLabel(methodEnd);
il.Emit(OpCodes.Ret);
return typeBuilder.CreateType();
}
private static readonly MethodAttributes ConstructorAttributes = MethodAttributes.Public |
MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
private Type DefineDelegate(ModuleBuilder module)
{
MethodAttributes methodAtts = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual;
TypeBuilder typeBuilder = module.DefineType("GetObjectHandler", TypeAttributes.Public | TypeAttributes.Sealed, typeof(MulticastDelegate));
ConstructorBuilder cb = typeBuilder.DefineConstructor(ConstructorAttributes, CallingConventions.Standard, new Type[] { typeof(object), typeof(IntPtr) });
cb.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.Runtime);
MethodBuilder mb1 = typeBuilder.DefineMethod("BeginInvoke", methodAtts, CallingConventions.Standard, typeof(IAsyncResult)
, new Type[] { typeof(ServicedComponent), typeof(string), typeof(AsyncCallback), typeof(object) });
mb1.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.Runtime);
MethodBuilder mb2 = typeBuilder.DefineMethod("EndInvoke", methodAtts, CallingConventions.Standard, typeof(object)
, new Type[] { typeof(IAsyncResult) });
mb2.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.Runtime);
MethodBuilder mb3 = typeBuilder.DefineMethod("Invoke", methodAtts, CallingConventions.Standard, typeof(object)
, new Type[] { typeof(ServicedComponent), typeof(string) });
mb3.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.Runtime);
return typeBuilder.CreateType();
}
#endregion
}
}
#endif // (!NET_1_0)

View File

@@ -0,0 +1,10 @@
using Spring.Context.Support;
namespace Spring.EnterpriseServices
{
/// <summary>
///
/// </summary>
public class ServicedComponentContextHandler : ContextHandler
{}
}

View File

@@ -1,224 +1,310 @@
#region License
/*
* Copyright 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
#if (!NET_1_0 && !MONO)
#region Imports
using System;
using System.Collections;
using System.EnterpriseServices;
using System.Reflection.Emit;
using Spring.Core.TypeResolution;
using Spring.Objects.Factory;
using Spring.Proxy;
using Spring.Util;
#endregion
namespace Spring.EnterpriseServices
{
/// <summary>
/// Encapsulates information necessary to create ServicedComponent
/// wrapper around target class.
/// </summary>
/// <remarks>
/// <p>
/// Instances of this class should be used as elements in the Components
/// list of the <see cref="EnterpriseServicesExporter"/> class, which will
/// register them with COM+ Services.
/// </p>
/// </remarks>
/// <author>Aleksandar Seovic</author>
public class ServicedComponentExporter : IInitializingObject, IObjectNameAware
{
#region Fields
private string _objectName;
private string _targetName;
private string[] _interfaces;
private IList _typeAttributes = new ArrayList();
private IDictionary _memberAttributes = new Hashtable();
#endregion
#region Constructor(s) / Destructor
/// <summary>
/// Creates a new instance of the
/// <see cref="ServicedComponentExporter"/> class.
/// </summary>
public ServicedComponentExporter()
{}
#endregion
#region Properties
/// <summary>
/// Gets or sets name of the target object that should be exposed as a serviced component.
/// </summary>
public string TargetName
{
get { return _targetName; }
set { _targetName = value; }
}
/// <summary>
/// Gets or sets the list of interfaces whose methods should be exported.
/// </summary>
/// <remarks>
/// The default value of this property is all the interfaces
/// implemented or inherited by the target type.
/// </remarks>
/// <value>The interfaces to export.</value>
public string[] Interfaces
{
get { return _interfaces; }
set { _interfaces = value; }
}
/// <summary>
/// Gets or sets a list of custom attributes
/// that should be applied to a proxy 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 proxy members.
/// </summary>
/// <remarks>
/// Map 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 IInitializingObject Members
/// <summary>
/// Validate configuration.
/// </summary>
public void AfterPropertiesSet()
{
ValidateConfiguration();
}
#endregion
#region IObjectNameAware Members
/// <summary>
/// Set the name of the object in the object factory
/// that created this object.
/// </summary>
public string ObjectName
{
set { _objectName = value; }
}
#endregion
#region Methods
private void ValidateConfiguration()
{
if (TargetName == null)
{
throw new ArgumentException("The TargetName property is required.");
}
}
/// <summary>
/// Creates ServicedComponent wrapper around target class.
/// </summary>
/// <param name="module">Dynamic module builder to use</param>
/// <param name="objectFactory">Object factory to get target from.</param>
internal Type CreateWrapperType(ModuleBuilder module, IObjectFactory objectFactory)
{
// create wrapper using appropriate proxy builder
IProxyTypeBuilder proxyBuilder = new ServicedComponentProxyTypeBuilder(module);
proxyBuilder.Name = _objectName;
proxyBuilder.TargetType = objectFactory.GetType(TargetName);
if (_interfaces != null && _interfaces.Length > 0)
{
proxyBuilder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(_interfaces);
}
proxyBuilder.TypeAttributes = TypeAttributes;
proxyBuilder.MemberAttributes = MemberAttributes;
Type componentType = proxyBuilder.BuildProxyType();
// create and register client-side proxy factory for component
return componentType;
}
#endregion
#region ServicedComponentProxyTypeBuilder inner class definition
private sealed class ServicedComponentProxyTypeBuilder : CompositionProxyTypeBuilder
{
#region Fields
private ModuleBuilder module;
#endregion
#region Constructor(s) / Destructor
public ServicedComponentProxyTypeBuilder(ModuleBuilder module)
{
this.module = module;
BaseType = typeof(ServicedComponent);
}
#endregion
#region Protected Methods
protected override TypeBuilder CreateTypeBuilder(string name, Type baseType)
{
return module.DefineType(name,
System.Reflection.TypeAttributes.BeforeFieldInit | System.Reflection.TypeAttributes.Public,
baseType);
}
#endregion
}
#endregion
}
}
#endif // (!NET_1_0)
#region License
/*
* Copyright 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
#if (!NET_1_0 && !MONO)
#region Imports
using System;
using System.Collections;
using System.EnterpriseServices;
using System.Reflection;
using System.Reflection.Emit;
using Spring.Core.TypeResolution;
using Spring.Objects.Factory;
using Spring.Proxy;
#endregion
namespace Spring.EnterpriseServices
{
/// <summary>
/// Encapsulates information necessary to create ServicedComponent
/// wrapper around target class.
/// </summary>
/// <remarks>
/// <p>
/// Instances of this class should be used as elements in the Components
/// list of the <see cref="EnterpriseServicesExporter"/> class, which will
/// register them with COM+ Services.
/// </p>
/// </remarks>
/// <author>Aleksandar Seovic</author>
public class ServicedComponentExporter : IInitializingObject, IObjectNameAware
{
#region Fields
private string _objectName;
private string _targetName;
private string[] _interfaces;
private IList _typeAttributes = new ArrayList();
private IDictionary _memberAttributes = new Hashtable();
#endregion
#region Constructor(s) / Destructor
/// <summary>
/// Creates a new instance of the
/// <see cref="ServicedComponentExporter"/> class.
/// </summary>
public ServicedComponentExporter()
{}
#endregion
#region Properties
/// <summary>
/// Gets or sets name of the target object that should be exposed as a serviced component.
/// </summary>
public string TargetName
{
get { return _targetName; }
set { _targetName = value; }
}
/// <summary>
/// Gets or sets the list of interfaces whose methods should be exported.
/// </summary>
/// <remarks>
/// The default value of this property is all the interfaces
/// implemented or inherited by the target type.
/// </remarks>
/// <value>The interfaces to export.</value>
public string[] Interfaces
{
get { return _interfaces; }
set { _interfaces = value; }
}
/// <summary>
/// Gets or sets a list of custom attributes
/// that should be applied to a proxy 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 proxy members.
/// </summary>
/// <remarks>
/// Map 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 IInitializingObject Members
/// <summary>
/// Validate configuration.
/// </summary>
public void AfterPropertiesSet()
{
ValidateConfiguration();
}
#endregion
#region IObjectNameAware Members
/// <summary>
/// Set the name of the object in the object factory
/// that created this object.
/// </summary>
public string ObjectName
{
set { _objectName = value; }
}
#endregion
#region Methods
private void ValidateConfiguration()
{
if (TargetName == null)
{
throw new ArgumentException("The TargetName property is required.");
}
}
/// <summary>
/// Creates ServicedComponent wrapper around target class.
/// </summary>
/// <param name="module">Dynamic module builder to use</param>
/// <param name="baseType"></param>
/// <param name="objectFactory">Object factory to get target from.</param>
/// <param name="useSpring">whether to generated ApplicationContext lookups or use static target instances</param>
public Type CreateWrapperType(ModuleBuilder module, Type baseType, IObjectFactory objectFactory, bool useSpring)
{
ValidateConfiguration();
// create wrapper using appropriate proxy builder
IProxyTypeBuilder proxyBuilder;
if (useSpring)
{
proxyBuilder = new SpringManagedServicedComponentProxyTypeBuilder(module, baseType, this);
}
else
{
proxyBuilder = new SimpleServicedComponentProxyTypeBuilder(module);
}
proxyBuilder.Name = _objectName;
proxyBuilder.TargetType = objectFactory.GetType(TargetName);
if (_interfaces != null && _interfaces.Length > 0)
{
proxyBuilder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(_interfaces);
}
proxyBuilder.TypeAttributes = TypeAttributes;
proxyBuilder.MemberAttributes = MemberAttributes;
Type componentType = proxyBuilder.BuildProxyType();
// create and register client-side proxy factory for component
return componentType;
}
#endregion
#region ServicedComponentProxyTypeBuilder inner class definition
private sealed class SimpleServicedComponentProxyTypeBuilder : CompositionProxyTypeBuilder
{
private readonly ModuleBuilder module;
#region Constructor(s) / Destructor
public SimpleServicedComponentProxyTypeBuilder(ModuleBuilder module)
{
this.module = module;
BaseType = typeof(ServicedComponent);
}
#endregion
#region Protected Methods
protected override TypeBuilder CreateTypeBuilder(string name, Type baseType)
{
return module.DefineType(name, System.Reflection.TypeAttributes.Public, baseType);
}
#endregion
}
private sealed class SpringManagedServicedComponentProxyTypeBuilder : CompositionProxyTypeBuilder
{
#region Fields
private delegate object GetTargetDelegate(ServicedComponent component, string name);
private static readonly MethodInfo ServicedComponentExporter_GetTarget = new GetTargetDelegate(ServicedComponentHelper.GetObject).Method;
#endregion
#region Fields
private readonly ServicedComponentExporter exporter;
private readonly ModuleBuilder module;
#endregion
#region Constructor(s) / Destructor
public SpringManagedServicedComponentProxyTypeBuilder(ModuleBuilder module, Type baseType, ServicedComponentExporter exporter)
{
this.module = module;
this.exporter = exporter;
BaseType = baseType;
}
#endregion
#region Protected Methods
protected override TypeBuilder CreateTypeBuilder(string name, Type baseType)
{
return module.DefineType(name, System.Reflection.TypeAttributes.Public, baseType);
}
protected override void DeclareTargetInstanceField(TypeBuilder builder)
{
//base.DeclareTargetInstanceField(builder);
}
#endregion
#region IProxyTypeGenerator Members
/// <summary>
/// Implements constructors for the proxy class.
/// </summary>
/// <param name="builder">
/// The <see cref="System.Reflection.Emit.TypeBuilder"/> to use.
/// </param>
protected override void ImplementConstructors( TypeBuilder builder )
{
MethodAttributes attributes = MethodAttributes.Public |
MethodAttributes.HideBySig | MethodAttributes.SpecialName |
MethodAttributes.RTSpecialName;
ConstructorBuilder cb = builder.DefineConstructor( attributes,
CallingConventions.Standard, Type.EmptyTypes );
ILGenerator il = cb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, builder.BaseType.GetConstructor(Type.EmptyTypes));
il.Emit( OpCodes.Ret );
}
/// <summary>
/// Generates the IL instructions that pushes
/// the target instance on which calls should be delegated to.
/// </summary>
/// <param name="il">The IL generator to use.</param>
public override void PushTarget( ILGenerator il )
{
FieldInfo getObjectRef = BaseType.GetField("getObject", BindingFlags.NonPublic|BindingFlags.Static);
il.Emit(OpCodes.Ldsfld, getObjectRef);
il.Emit(OpCodes.Ldarg_0);
il.Emit( OpCodes.Ldstr, this.exporter.TargetName );
il.Emit( OpCodes.Callvirt, getObjectRef.FieldType.GetMethod("Invoke"));
}
#endregion
}
#endregion
}
}
#endif // (!NET_1_0)

View File

@@ -0,0 +1,104 @@
#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.Configuration;
using System.EnterpriseServices;
using System.IO;
using System.Reflection;
using System.Xml;
using Spring.Context;
using Spring.Context.Support;
using Spring.Reflection.Dynamic;
using ConfigXmlDocument = Spring.Util.ConfigXmlDocument;
#endregion
namespace Spring.EnterpriseServices
{
/// <summary>
///
/// </summary>
/// <author>Erich Eichinger</author>
public class ServicedComponentHelper
{
private static bool isInitialized;
private static string componentDirectory;
static ServicedComponentHelper()
{
isInitialized = false;
}
///<summary>
///</summary>
///<param name="component"></param>
private static void EnsureComponentContextRegistryInitialized(ServicedComponent component)
{
if (isInitialized) return;
lock (typeof(ServicedComponentHelper))
{
if (isInitialized) return;
isInitialized = true;
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
FileInfo componentAssemblyFile = new FileInfo(component.GetType().Assembly.Location);
componentDirectory = componentAssemblyFile.Directory.FullName;
Environment.CurrentDirectory = componentDirectory;
ConfigXmlDocument configDoc = new ConfigXmlDocument();
FileInfo configFile = new FileInfo(componentAssemblyFile.FullName + ".spring-context.xml");
if (configFile.Exists)
{
configDoc.Load(configFile.FullName);
XmlNode configNode = configDoc.SelectSingleNode("//context");
ServicedComponentContextHandler handler = new ServicedComponentContextHandler();
lock (ContextRegistry.SyncRoot)
{
ContextRegistry.Clear();
handler.Create(null, null, configNode);
}
}
}
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string name = args.Name.Split(',')[0];
Assembly assembly = Assembly.LoadFrom(Path.Combine(componentDirectory, name + ".dll"));
return assembly;
}
///<summary>
///</summary>
///<param name="sender"></param>
///<param name="targetName"></param>
///<returns></returns>
public static object GetObject(ServicedComponent sender, string targetName)
{
EnsureComponentContextRegistryInitialized(sender);
return ContextRegistry.GetContext().GetObject(targetName);
// return null;
}
}
}

View File

@@ -1,7 +1,7 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.3077"
ProductVersion = "7.10.6030"
SchemaVersion = "2.0"
ProjectGuid = "{B58E34CF-6E70-481D-AC87-1BC2D13C21FB}"
>
@@ -127,6 +127,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "EnterpriseServices\ServicedComponentContextHandler.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "EnterpriseServices\ServicedComponentExporter.cs"
SubType = "Code"
@@ -137,6 +142,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "EnterpriseServices\ServicedComponentHelper.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Remoting\CaoExporter.cs"
SubType = "Code"

View File

@@ -11,8 +11,7 @@
<AssemblyKeyContainerName>
</AssemblyKeyContainerName>
<AssemblyName>Spring.Services</AssemblyName>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyFile>..\..\..\Spring.Net.snk</AssemblyOriginatorKeyFile>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
@@ -22,6 +21,7 @@
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<StartupObject>
</StartupObject>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2005\Spring.Services\Debug\</OutputPath>
@@ -80,6 +80,7 @@
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.configuration" />
<Reference Include="System.Data">
<Name>System.Data</Name>
</Reference>
@@ -101,6 +102,8 @@
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="EnterpriseServices\EnterpriseServicesExporter.cs" />
<Compile Include="EnterpriseServices\ServicedComponentHelper.cs" />
<Compile Include="EnterpriseServices\ServicedComponentContextHandler.cs" />
<Compile Include="EnterpriseServices\ServicedComponentExporter.cs" />
<Compile Include="EnterpriseServices\ServicedComponentFactory.cs" />
<Compile Include="Remoting\CaoExporter.cs">

View File

@@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -99,8 +99,10 @@
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="EnterpriseServices\EnterpriseServicesExporter.cs" />
<Compile Include="EnterpriseServices\ServicedComponentContextHandler.cs" />
<Compile Include="EnterpriseServices\ServicedComponentExporter.cs" />
<Compile Include="EnterpriseServices\ServicedComponentFactory.cs" />
<Compile Include="EnterpriseServices\ServicedComponentHelper.cs" />
<Compile Include="Remoting\CaoExporter.cs">
<SubType>Code</SubType>
</Compile>

View File

@@ -0,0 +1,79 @@
#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.Diagnostics;
using System.EnterpriseServices;
using System.IO;
using System.Reflection;
using System.Xml;
using Spring.Context.Support;
using Spring.Objects;
using Spring.Util;
#endregion
/*
The code below is only for reverse engineering generated code in reflector
*/
namespace Spring.EnterpriseServices
{
internal interface ITestInterface
{
void Method();
}
internal delegate object GetObjectHandler(ServicedComponent component, string targetName);
internal class ExportedServicedComponentSample : ServicedComponent, ITestInterface
{
protected static GetObjectHandler getObject;
static ExportedServicedComponentSample()
{
try
{
// in case we're dealing w/ unsigned assemblies, that is the way to go...
string path = Path.Combine( new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName, "Spring.Services.dll");
Assembly a = Assembly.LoadFrom(path);
if (a == null)
{
a = Assembly.Load("Spring.Services, Version=1.2.0.20001, Culture=neutral, PublicKeyToken=null");
}
Type t = a.GetType("Spring.EnterpriseServices.ServicedComponentHelper", true);
getObject = (GetObjectHandler) Delegate.CreateDelegate(typeof(GetObjectHandler), t.GetMethod("GetObject"));
}
catch(Exception ex)
{
Trace.WriteLine(ex);
throw;
}
}
public void Method()
{
ITestInterface targetInstance = (ITestInterface) getObject(null, "name");
targetInstance.Method();
}
}
}

View File

@@ -71,11 +71,10 @@ namespace Spring.EnterpriseServices
#region Private helpers classes
// private delegate Type CreateWrapperTypeHandler(ModuleBuilder module, Type baseType, IObjectFactory objectFactory, bool useSpring);
private Type CreateWrapperType(ServicedComponentExporter exporter, Type type)
{
MethodInfo createWrapperTypeMethodInfo = typeof(ServicedComponentExporter).GetMethod("CreateWrapperType", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.IsNotNull(createWrapperTypeMethodInfo);
AssemblyName an = new AssemblyName();
an.Name = "Spring.EnterpriseServices.Tests";
AssemblyBuilder proxyAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
@@ -84,7 +83,7 @@ namespace Spring.EnterpriseServices
IDynamicMock mockObjectFactory = new DynamicMock(typeof(IObjectFactory));
mockObjectFactory.ExpectAndReturn("GetType", type, new object[]{ exporter.TargetName });
object result = createWrapperTypeMethodInfo.Invoke(exporter, new object[] { module, mockObjectFactory.Object });
object result = exporter.CreateWrapperType(module, typeof(ServicedComponent), (IObjectFactory) mockObjectFactory.Object, false); //createWrapperTypeMethodInfo.Invoke(exporter, new object[] { module, mockObjectFactory.Object });
Assert.IsNotNull(result);
Assert.IsTrue(result is Type);

View File

@@ -1,7 +1,7 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.3077"
ProductVersion = "7.10.6030"
SchemaVersion = "2.0"
ProjectGuid = "{EB2687B7-8B26-4FBC-852A-4128D5CACAFC}"
>
@@ -178,6 +178,10 @@
RelPath = "Data\Spring\Remoting\saoSingleton-aop.xml"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "Data\Spring\Remoting\saoSingleton-autowired.xml"
BuildAction = "Content"
/>
<File
RelPath = "Data\Spring\Web\Services\configurableFactory.xml"
BuildAction = "EmbeddedResource"
@@ -202,6 +206,11 @@
RelPath = "Data\Spring\Web\Services\Service.cs.fyi"
BuildAction = "None"
/>
<File
RelPath = "EnterpriseServices\ExportedServicedComponentSample.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "EnterpriseServices\ServicedComponentExporterTests.cs"
SubType = "Code"

View File

@@ -96,6 +96,7 @@
<Compile Include="AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="EnterpriseServices\ExportedServicedComponentSample.cs" />
<Compile Include="EnterpriseServices\ServicedComponentExporterTests.cs" />
<Compile Include="Remoting\BaseRemotingTestFixture.cs" />
<Compile Include="Remoting\CaoExporterTests.cs">