From 238a44da8f800a53052ec93a13764ff1d0f37e4e Mon Sep 17 00:00:00 2001 From: eeichinger Date: Fri, 14 Nov 2008 17:50:33 +0000 Subject: [PATCH] resolved SPRNET-1109, SPRNET-1095 --- .../Spring.Calculator.ClientApp/App.config | 15 +- .../AssemblyInfo.cs | 2 +- .../Spring.Calculator.snk | Bin 596 -> 0 bytes .../App.config | 24 +- .../Config/enterpriseServices.xml | 45 +- .../Config/services.xml | 8 + ....EnterpriseServices.dll.spring-context.xml | 4 + ...ator.RegisterComponentServices.2003.csproj | 12 +- .../Services/AdvancedCalculator.cs | 75 +- .../Services/Calculator.cs | 35 +- .../Spring.Calculator.Services.2003.csproj | 10 + .../Spring.Calculator.Services.build | 1 + .../Spring.Calculator.snk | Bin 596 -> 0 bytes .../Spring.Core/Spring.Core.2005.csproj | 4 +- .../Spring.Core/Spring.Core.2008.csproj | 2 +- .../Spring.Core/Util/ConfigurationUtils.cs | 448 +++++----- .../EnterpriseServicesExporter.cs | 774 +++++++++++------- .../ServicedComponentContextHandler.cs | 10 + .../ServicedComponentExporter.cs | 534 +++++++----- .../ServicedComponentHelper.cs | 104 +++ .../Spring.Services.2003.csproj | 12 +- .../Spring.Services.2005.csproj | 7 +- .../Spring.Services.2008.csproj | 4 +- .../ExportedServicedComponentSample.cs | 79 ++ .../ServicedComponentExporterTests.cs | 7 +- .../Spring.Services.Tests.2003.csproj | 11 +- .../Spring.Services.Tests.2005.csproj | 1 + 27 files changed, 1386 insertions(+), 842 deletions(-) delete mode 100644 examples/Spring/Spring.Calculator/src/Spring.Calculator.Contract/Spring.Calculator.snk create mode 100644 examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Config/services.xml create mode 100644 examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Spring.Calculator.EnterpriseServices.dll.spring-context.xml delete mode 100644 examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.snk create mode 100644 src/Spring/Spring.Services/EnterpriseServices/ServicedComponentContextHandler.cs create mode 100644 src/Spring/Spring.Services/EnterpriseServices/ServicedComponentHelper.cs create mode 100644 test/Spring/Spring.Services.Tests/EnterpriseServices/ExportedServicedComponentSample.cs diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.ClientApp/App.config b/examples/Spring/Spring.Calculator/src/Spring.Calculator.ClientApp/App.config index a6b8fefc..fe1598fd 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.ClientApp/App.config +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.ClientApp/App.config @@ -2,6 +2,9 @@ + +
+
@@ -9,6 +12,14 @@ + + + + + + + + @@ -23,7 +34,7 @@ - + @@ -53,7 +64,7 @@ - + diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Contract/AssemblyInfo.cs b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Contract/AssemblyInfo.cs index 2aaea54d..9558ea1c 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Contract/AssemblyInfo.cs +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Contract/AssemblyInfo.cs @@ -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 diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Contract/Spring.Calculator.snk b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Contract/Spring.Calculator.snk deleted file mode 100644 index a1ab9f359471a6da2c57a7b331cb5c298739deef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096WZ5+wHC^zL}VQuiO~`P67GkrzC(jbhQ8B`v_QXs z1bxbpF?5Cpua8?Cuma;q0e#*w!SEdc$Ad%q^tB9JaT~+5-%(!m&!@{?;MvT#fnTm>sI~-2I)cubdJvDK_%T_+ao;v*BF|$rzZ5n zm5eJM!M*r{sJnsZE#6OSFoIE`J!OwafP+-Xn$R zU(8RqhAj(k{asPJst@`-A4-q^1A;Bu_=Vo45mmZY-IC#R7yyjQu<3XM2_+dwU~8-S zymN&0q!rUXO%1gGH^@5izWK4`=8J`HA|#nsx^cZIr1or!NM~oMq@7;ez58q5J$jSU zOF#elrPa7vc9^fRG301jF&5=Y2kPW#RZ<^=m>|Sads@GpV1(XIP=O)bGb%`}6T81o zva6>LzC8v3rVQ_iW(QG_dcgAphKns_8I`XdMb7-lY~inZA^}(|x`WB?n~5PF&qH>? z3j@h%f%Q%UNXh8Hb_I;3?#^&KE;V!m@7t{|7I7w4MO}#0N~oBc6a|N|tzt>{sC1UZ i5!NonUY^q_dP!J)Cgbl(1jR^+|C5QOew;pjU>^YZwj_c8 diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/App.config b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/App.config index 890db9c6..6f9879ea 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/App.config +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/App.config @@ -2,26 +2,30 @@ - + +
+ +
- + + + + + + + + + - + - - Definitions of objects to be registered. - - - - - \ No newline at end of file diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Config/enterpriseServices.xml b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Config/enterpriseServices.xml index 74f6f0f0..648c6568 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Config/enterpriseServices.xml +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Config/enterpriseServices.xml @@ -21,15 +21,41 @@ + + + + - - Spring Calculator Application - - - Spring Calculator application. + + + + + + + + + + + + + + + + + false + + + \ No newline at end of file diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Config/services.xml b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Config/services.xml new file mode 100644 index 00000000..6e325dd6 --- /dev/null +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Config/services.xml @@ -0,0 +1,8 @@ + + + Definitions of objects to be registered. + + + + + diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Spring.Calculator.EnterpriseServices.dll.spring-context.xml b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Spring.Calculator.EnterpriseServices.dll.spring-context.xml new file mode 100644 index 00000000..565b4226 --- /dev/null +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Spring.Calculator.EnterpriseServices.dll.spring-context.xml @@ -0,0 +1,4 @@ + + + + diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Spring.Calculator.RegisterComponentServices.2003.csproj b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Spring.Calculator.RegisterComponentServices.2003.csproj index 4fa08513..7903a35f 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Spring.Calculator.RegisterComponentServices.2003.csproj +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.RegisterComponentServices/Spring.Calculator.RegisterComponentServices.2003.csproj @@ -17,9 +17,9 @@ DelaySign = "false" OutputType = "Exe" PreBuildEvent = "" - PostBuildEvent = "" + PostBuildEvent = "xcopy $(ProjectDir)Spring.Calculator.EnterpriseServices.dll.spring-context.xml $(TargetDir) /Y /F xcopy $(ProjectDir)Config\*.* $(TargetDir)Config /S /Y /F /I" RootNamespace = "Spring.Calculator.RegisterComponentServices" - RunPostBuildEvent = "OnBuildSuccess" + RunPostBuildEvent = "Always" StartupObject = "" > + + diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Services/AdvancedCalculator.cs b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Services/AdvancedCalculator.cs index 0fe3687b..4dc0c6f7 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Services/AdvancedCalculator.cs +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Services/AdvancedCalculator.cs @@ -1,7 +1,7 @@ #region License /* - * Copyright © 2002-2006 the original author or authors. + * Copyright © 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 { - /// - /// An advanced calculator service. - /// + /// + /// An advanced calculator service. + /// /// Bruno Baia - /// $Id: AdvancedCalculator.cs,v 1.2 2006/12/04 01:38:42 bbaia Exp $ 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 } } \ No newline at end of file diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Services/Calculator.cs b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Services/Calculator.cs index 36c84a7a..ffa5f112 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Services/Calculator.cs +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Services/Calculator.cs @@ -1,7 +1,7 @@ #region License /* - * Copyright © 2002-2006 the original author or authors. + * Copyright © 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. /// /// Bruno Baia - /// $Id: Calculator.cs,v 1.1 2006/10/29 18:39:13 bbaia Exp $ 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; } diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.Services.2003.csproj b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.Services.2003.csproj index 770667cf..587b01b5 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.Services.2003.csproj +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.Services.2003.csproj @@ -69,6 +69,16 @@ Project = "{284C0873-BBB4-4399-B6F7-CB7EDBD001C7}" Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" /> + + diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.Services.build b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.Services.build index c8b9a8ed..338d8264 100644 --- a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.Services.build +++ b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.Services.build @@ -18,6 +18,7 @@ + diff --git a/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.snk b/examples/Spring/Spring.Calculator/src/Spring.Calculator.Services/Spring.Calculator.snk deleted file mode 100644 index a1ab9f359471a6da2c57a7b331cb5c298739deef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096WZ5+wHC^zL}VQuiO~`P67GkrzC(jbhQ8B`v_QXs z1bxbpF?5Cpua8?Cuma;q0e#*w!SEdc$Ad%q^tB9JaT~+5-%(!m&!@{?;MvT#fnTm>sI~-2I)cubdJvDK_%T_+ao;v*BF|$rzZ5n zm5eJM!M*r{sJnsZE#6OSFoIE`J!OwafP+-Xn$R zU(8RqhAj(k{asPJst@`-A4-q^1A;Bu_=Vo45mmZY-IC#R7yyjQu<3XM2_+dwU~8-S zymN&0q!rUXO%1gGH^@5izWK4`=8J`HA|#nsx^cZIr1or!NM~oMq@7;ez58q5J$jSU zOF#elrPa7vc9^fRG301jF&5=Y2kPW#RZ<^=m>|Sads@GpV1(XIP=O)bGb%`}6T81o zva6>LzC8v3rVQ_iW(QG_dcgAphKns_8I`XdMb7-lY~inZA^}(|x`WB?n~5PF&qH>? z3j@h%f%Q%UNXh8Hb_I;3?#^&KE;V!m@7t{|7I7w4MO}#0N~oBc6a|N|tzt>{sC1UZ i5!NonUY^q_dP!J)Cgbl(1jR^+|C5QOew;pjU>^YZwj_c8 diff --git a/src/Spring/Spring.Core/Spring.Core.2005.csproj b/src/Spring/Spring.Core/Spring.Core.2005.csproj index 27f9f1c4..f029b170 100644 --- a/src/Spring/Spring.Core/Spring.Core.2005.csproj +++ b/src/Spring/Spring.Core/Spring.Core.2005.csproj @@ -11,8 +11,7 @@ Spring.Core - - + ..\..\..\Spring.Net.snk JScript Grid IE50 @@ -22,6 +21,7 @@ OnBuildSuccess + false ..\..\..\build\VS.Net.2005\Spring.Core\Debug\ diff --git a/src/Spring/Spring.Core/Spring.Core.2008.csproj b/src/Spring/Spring.Core/Spring.Core.2008.csproj index fbacbc45..42fbc7f5 100644 --- a/src/Spring/Spring.Core/Spring.Core.2008.csproj +++ b/src/Spring/Spring.Core/Spring.Core.2008.csproj @@ -46,7 +46,7 @@ false - TRACE;DEBUG;NET_2_0;DEBUG_DYNAMIC + TRACE;DEBUG;NET_2_0;DEBUG_DYNAMICX Spring.Core.xml true 4096 diff --git a/src/Spring/Spring.Core/Util/ConfigurationUtils.cs b/src/Spring/Spring.Core/Util/ConfigurationUtils.cs index 07919497..71f022f0 100644 --- a/src/Spring/Spring.Core/Util/ConfigurationUtils.cs +++ b/src/Spring/Spring.Core/Util/ConfigurationUtils.cs @@ -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 -{ - /// - /// Utility class for .NET configuration files management. - /// - /// Aleksandar Seovic - public class ConfigurationUtils - { - /// - /// Parses the configuration section. - /// - /// - ///

- /// 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. - ///

- ///

- /// If Microsoft paid a bit more attention to preserving backwards - /// compatibility we would not even need it, but... :( - ///

- ///
- /// Name of the configuration section. - /// Object created by a corresponding . - public static object GetSection(string sectionName) - { -#if !NET_2_0 - return ConfigurationSettings.GetConfig(sectionName.TrimEnd('/')); -#else - return ConfigurationManager.GetSection(sectionName.TrimEnd('/')); -#endif - } - - /// - /// Refresh the configuration section. - /// - /// - ///

- /// 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. - ///

- ///

- /// If Microsoft paid a bit more attention to preserving backwards - /// compatibility we would not even need it, but... :( - ///

- ///
- /// Name of the configuration section. - public static void RefreshSection(string sectionName) - { -#if !NET_2_0 - // TODO : Add support for .NET 1.x -#else - ConfigurationManager.RefreshSection(sectionName); -#endif - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// The inner exception. - /// Name of the configuration file. - /// The line where exception occured. - /// Configuration exception. - 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 - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// Name of the configuration file. - /// The line where exception occured. - /// Configuration exception. - public static Exception CreateConfigurationException(string message, string fileName, int line) - { - return CreateConfigurationException(message, null, fileName, line); - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// The inner exception. - /// XML node where exception occured. - /// Configuration exception. - 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 - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// XML node where exception occured. - /// Configuration exception. - public static Exception CreateConfigurationException(string message, XmlNode node) - { - return CreateConfigurationException(message, null, node); - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// The inner exception. - /// Configuration exception. - public static Exception CreateConfigurationException(string message, Exception inner) - { -#if !NET_2_0 - return new ConfigurationException(message, inner); -#else - return new ConfigurationErrorsException(message, inner); -#endif - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// Configuration exception. - public static Exception CreateConfigurationException(string message) - { - return CreateConfigurationException(message, (Exception) null); - } - - /// - /// Creates the configuration exception. - /// - /// Configuration exception. - public static Exception CreateConfigurationException() - { - return CreateConfigurationException(null, (Exception) null); - } - - /// - /// Determines whether the specified exception is configuration exception. - /// - /// The exception to check. - /// - /// true if the specified exception is configuration exception; otherwise, false. - /// - public static bool IsConfigurationException(Exception exception) - { -#if !NET_2_0 - return exception is ConfigurationException; -#else - return exception is ConfigurationErrorsException; -#endif - } - - /// - /// Returns the line number of the specified node. - /// - /// Node to get the line number for. - /// The line number of the specified node. - 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 +{ + /// + /// Utility class for .NET configuration files management. + /// + /// Aleksandar Seovic + public class ConfigurationUtils + { + /// + /// Parses the configuration section. + /// + /// + ///

+ /// 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. + ///

+ ///

+ /// If Microsoft paid a bit more attention to preserving backwards + /// compatibility we would not even need it, but... :( + ///

+ ///
+ /// Name of the configuration section. + /// Object created by a corresponding . + public static object GetSection(string sectionName) + { +#if !NET_2_0 + return ConfigurationSettings.GetConfig(sectionName.TrimEnd('/')); +#else + return ConfigurationManager.GetSection(sectionName.TrimEnd('/')); +#endif + } + + /// + /// Refresh the configuration section. + /// + /// + ///

+ /// 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. + ///

+ ///

+ /// If Microsoft paid a bit more attention to preserving backwards + /// compatibility we would not even need it, but... :( + ///

+ ///
+ /// Name of the configuration section. + public static void RefreshSection(string sectionName) + { +#if !NET_2_0 + // TODO : Add support for .NET 1.x +#else + ConfigurationManager.RefreshSection(sectionName); +#endif + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// The inner exception. + /// Name of the configuration file. + /// The line where exception occured. + /// Configuration exception. + 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 + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// Name of the configuration file. + /// The line where exception occured. + /// Configuration exception. + public static Exception CreateConfigurationException(string message, string fileName, int line) + { + return CreateConfigurationException(message, null, fileName, line); + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// The inner exception. + /// XML node where exception occured. + /// Configuration exception. + 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 + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// XML node where exception occured. + /// Configuration exception. + public static Exception CreateConfigurationException(string message, XmlNode node) + { + return CreateConfigurationException(message, null, node); + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// The inner exception. + /// Configuration exception. + public static Exception CreateConfigurationException(string message, Exception inner) + { +#if !NET_2_0 + return new ConfigurationException(message, inner); +#else + return new ConfigurationErrorsException(message, inner); +#endif + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// Configuration exception. + public static Exception CreateConfigurationException(string message) + { + return CreateConfigurationException(message, (Exception) null); + } + + /// + /// Creates the configuration exception. + /// + /// Configuration exception. + public static Exception CreateConfigurationException() + { + return CreateConfigurationException(null, (Exception) null); + } + + /// + /// Determines whether the specified exception is configuration exception. + /// + /// The exception to check. + /// + /// true if the specified exception is configuration exception; otherwise, false. + /// + public static bool IsConfigurationException(Exception exception) + { +#if !NET_2_0 + return exception is ConfigurationException; +#else + return exception is ConfigurationErrorsException; +#endif + } + + /// + /// Returns the line number of the specified node. + /// + /// Node to get the line number for. + /// The line number of the specified node. + 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 - } - - /// - /// Returns the name of the file specified node is defined in. - /// - /// Node to get the file name for. - /// The name of the file specified node is defined in. - public static string GetFileName(XmlNode node) - { - if (node is ITextPosition) + } +#if !NET_2_0 + return ConfigurationException.GetXmlNodeLineNumber(node); +#else + return ConfigurationErrorsException.GetLineNumber(node); +#endif + } + + /// + /// Returns the name of the file specified node is defined in. + /// + /// Node to get the file name for. + /// The name of the file specified node is defined in. + 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 + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs b/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs index ce01fa70..fb712b2b 100644 --- a/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs +++ b/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs @@ -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 -{ - /// - /// Exports specified components as ServicedComponents. - /// - /// - ///

- /// This class will create ServicedComponent wrapper for each of the - /// specified components and register them with the Component Services. - ///

- ///
- /// Aleksandar Seovic - 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 - - /// - /// Creates new enterprise services exporter. - /// - public EnterpriseServicesExporter() - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets list of components to export. - /// - public IList Components - { - get { return components; } - set { components = value; } - } - - /// - /// Gets or sets COM+ application name. - /// - public string ApplicationName - { - get { return applicationName; } - set { applicationName = value; } - } - - /// - /// Gets or sets application identifier (GUID). Defaults to generated GUID if not specified. - /// - public string ApplicationId - { - get { return applicationId; } - set { applicationId = value; } - } - - /// - /// Gets or sets application activation mode, which can be either Server or Library (default). - /// - public ActivationOption ActivationMode - { - get { return activationMode; } - set { activationMode = value; } - } - - /// - /// Gets or sets application description. - /// - public string Description - { - get { return description; } - set { description = value; } - } - - /// - /// Gets or sets access control attribute. - /// - public ApplicationAccessControlAttribute AccessControl - { - get { return accessControl; } - set { accessControl = value; } - } - - /// - /// Gets or sets application queuing attribute. - /// - public ApplicationQueuingAttribute ApplicationQueuing - { - get { return applicationQueuing; } - set { applicationQueuing = value; } - } - - /// - /// Gets or sets application roles. - /// - public IList Roles - { - get { return roles; } - set { roles = value; } - } - - /// - /// Gets or sets name of the generated assembly that will contain serviced components. - /// - public string Assembly - { - get { return assemblyName; } - set { assemblyName = value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Called by Spring container after object is configured in order to initialize it. - /// - public void AfterPropertiesSet() - { - if (roles != null && roles.Count > 0) - { - RefreshRoles(); - } - Export(); - } - - #endregion - - #region IObjectFactoryAware Members - - /// - /// Sets object factory instance. - /// - public IObjectFactory ObjectFactory - { - set { objectFactory = value; } - } - - #endregion - - #region Public Methods - - /// - /// Creates ServicedComponent wrappers for the specified components and registers - /// them with COM+ Component Services. - /// - 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 - - /// - /// Reads key pair from embedded resource. - /// - /// Key pair as a byte array. - 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; - } - } - - /// - /// Applies custom attributes to generated assembly. - /// - /// Dynamic assembly to apply attributes to. - 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)); - } - } - } - - /// - /// Replaces roles expressed using string with appropriate SecurityRoleAttribute instance. - /// - private void RefreshRoles() - { - for (int i = 0; i < roles.Count; i++) - { - object role = roles[i]; - if (role is string) - { - roles[i] = ParseRole((string) role); - } - } - } - - /// - /// Parses string representation of SecurityRoleAttribute. - /// - /// Role definition string. - /// Configured SecurityRoleAttribute instance. - 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 +{ + /// + /// Exports specified components as ServicedComponents. + /// + /// + ///

+ /// This class will create ServicedComponent wrapper for each of the + /// specified components and register them with the Component Services. + ///

+ ///
+ /// Aleksandar Seovic + 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 + + /// + /// Creates new enterprise services exporter. + /// + public EnterpriseServicesExporter() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets list of components to export. + /// + public IList Components + { + get { return components; } + set { components = value; } + } + + /// + /// Gets or sets COM+ application name. + /// + public string ApplicationName + { + get { return applicationName; } + set { applicationName = value; } + } + + /// + /// Gets or sets application identifier (GUID). Defaults to generated GUID if not specified. + /// + public string ApplicationId + { + get { return applicationId; } + set { applicationId = value; } + } + + /// + /// Gets or sets application activation mode, which can be either Server or Library (default). + /// + public ActivationOption ActivationMode + { + get { return activationMode; } + set { activationMode = value; } + } + + /// + /// Gets or sets application description. + /// + public string Description + { + get { return description; } + set { description = value; } + } + + /// + /// Gets or sets access control attribute. + /// + public ApplicationAccessControlAttribute AccessControl + { + get { return accessControl; } + set { accessControl = value; } + } + + /// + /// Gets or sets application queuing attribute. + /// + public ApplicationQueuingAttribute ApplicationQueuing + { + get { return applicationQueuing; } + set { applicationQueuing = value; } + } + + /// + /// Gets or sets application roles. + /// + public IList Roles + { + get { return roles; } + set { roles = value; } + } + + /// + /// Gets or sets name of the generated assembly that will contain serviced components. + /// + public string Assembly + { + get { return assemblyName; } + set { assemblyName = value; } + } + + /// + /// Use Spring context to configure the serviced components. + /// + public bool UseSpring + { + get { return useSpring; } + set { useSpring = value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Called by Spring container after object is configured in order to initialize it. + /// + public void AfterPropertiesSet() + { + if (roles != null && roles.Count > 0) + { + RefreshRoles(); + } + Export(); + } + + #endregion + + #region IObjectFactoryAware Members + + /// + /// Sets object factory instance. + /// + public IObjectFactory ObjectFactory + { + set { objectFactory = value; } + } + + #endregion + + #region Public Methods + + /// + /// Creates ServicedComponent wrappers for the specified components and registers + /// them with COM+ Component Services. + /// + 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 + + /// + /// Reads key pair from embedded resource. + /// + /// Key pair as a byte array. + 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; + } + } + + /// + /// Applies custom attributes to generated assembly. + /// + /// Dynamic assembly to apply attributes to. + 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)); + } + } + } + + /// + /// Replaces roles expressed using string with appropriate SecurityRoleAttribute instance. + /// + private void RefreshRoles() + { + for (int i = 0; i < roles.Count; i++) + { + object role = roles[i]; + if (role is string) + { + roles[i] = ParseRole((string)role); + } + } + } + + /// + /// Parses string representation of SecurityRoleAttribute. + /// + /// Role definition string. + /// Configured SecurityRoleAttribute instance. + 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 + + /// + /// Creates the SpringServicedComponent base class to derive all s from. + /// + /// + /// + /// 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 + /// , "Spring.Services.dll" ); + /// servicesAssembly = System.Reflection.Assembly.LoadFrom(servicesAssemblyPath); + /// if (servicesAssembly == null) + /// { + /// // then let the normal loader handle the typeload + /// servicesAssembly = System.Reflection.Assembly.Load("Spring.Services, culture=neutral, version=x.x.x.x, publicKey=xxxxxxxx"); + /// } + /// Type componentHelperType = servicesAssembly.GetType("Spring.EnterpriseServices.ServicedComponentHelper"); + /// getObjectRef = (GetObjectHandler) Delegate.CreateDelegate(typeof(GetObjectHandler) + /// , componentHelperType.GetMethod("GetObject")); + /// } + /// } + /// + /// + /// + 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) diff --git a/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentContextHandler.cs b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentContextHandler.cs new file mode 100644 index 00000000..200467d1 --- /dev/null +++ b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentContextHandler.cs @@ -0,0 +1,10 @@ +using Spring.Context.Support; + +namespace Spring.EnterpriseServices +{ + /// + /// + /// + public class ServicedComponentContextHandler : ContextHandler + {} +} \ No newline at end of file diff --git a/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentExporter.cs b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentExporter.cs index 4723df47..152df1fa 100644 --- a/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentExporter.cs +++ b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentExporter.cs @@ -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 -{ - /// - /// Encapsulates information necessary to create ServicedComponent - /// wrapper around target class. - /// - /// - ///

- /// Instances of this class should be used as elements in the Components - /// list of the class, which will - /// register them with COM+ Services. - ///

- ///
- /// Aleksandar Seovic - 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 - - /// - /// Creates a new instance of the - /// class. - /// - public ServicedComponentExporter() - {} - - #endregion - - #region Properties - - /// - /// Gets or sets name of the target object that should be exposed as a serviced component. - /// - public string TargetName - { - get { return _targetName; } - set { _targetName = value; } - } - - /// - /// Gets or sets the list of interfaces whose methods should be exported. - /// - /// - /// The default value of this property is all the interfaces - /// implemented or inherited by the target type. - /// - /// The interfaces to export. - public string[] Interfaces - { - get { return _interfaces; } - set { _interfaces = value; } - } - - /// - /// Gets or sets a list of custom attributes - /// that should be applied to a proxy class. - /// - public IList TypeAttributes - { - get { return _typeAttributes; } - set { _typeAttributes = value; } - } - - /// - /// Gets or sets a dictionary of custom attributes - /// that should be applied to proxy members. - /// - /// - /// 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. - /// - public IDictionary MemberAttributes - { - get { return _memberAttributes; } - set { _memberAttributes = value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Validate configuration. - /// - public void AfterPropertiesSet() - { - ValidateConfiguration(); - } - - #endregion - - #region IObjectNameAware Members - - /// - /// Set the name of the object in the object factory - /// that created this object. - /// - public string ObjectName - { - set { _objectName = value; } - } - - #endregion - - #region Methods - - private void ValidateConfiguration() - { - if (TargetName == null) - { - throw new ArgumentException("The TargetName property is required."); - } - } - - /// - /// Creates ServicedComponent wrapper around target class. - /// - /// Dynamic module builder to use - /// Object factory to get target from. - 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 +{ + /// + /// Encapsulates information necessary to create ServicedComponent + /// wrapper around target class. + /// + /// + ///

+ /// Instances of this class should be used as elements in the Components + /// list of the class, which will + /// register them with COM+ Services. + ///

+ ///
+ /// Aleksandar Seovic + 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 + + /// + /// Creates a new instance of the + /// class. + /// + public ServicedComponentExporter() + {} + + #endregion + + #region Properties + + /// + /// Gets or sets name of the target object that should be exposed as a serviced component. + /// + public string TargetName + { + get { return _targetName; } + set { _targetName = value; } + } + + /// + /// Gets or sets the list of interfaces whose methods should be exported. + /// + /// + /// The default value of this property is all the interfaces + /// implemented or inherited by the target type. + /// + /// The interfaces to export. + public string[] Interfaces + { + get { return _interfaces; } + set { _interfaces = value; } + } + + /// + /// Gets or sets a list of custom attributes + /// that should be applied to a proxy class. + /// + public IList TypeAttributes + { + get { return _typeAttributes; } + set { _typeAttributes = value; } + } + + /// + /// Gets or sets a dictionary of custom attributes + /// that should be applied to proxy members. + /// + /// + /// 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. + /// + public IDictionary MemberAttributes + { + get { return _memberAttributes; } + set { _memberAttributes = value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Validate configuration. + /// + public void AfterPropertiesSet() + { + ValidateConfiguration(); + } + + #endregion + + #region IObjectNameAware Members + + /// + /// Set the name of the object in the object factory + /// that created this object. + /// + public string ObjectName + { + set { _objectName = value; } + } + + #endregion + + #region Methods + + private void ValidateConfiguration() + { + if (TargetName == null) + { + throw new ArgumentException("The TargetName property is required."); + } + } + + /// + /// Creates ServicedComponent wrapper around target class. + /// + /// Dynamic module builder to use + /// + /// Object factory to get target from. + /// whether to generated ApplicationContext lookups or use static target instances + 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 + + /// + /// Implements constructors for the proxy class. + /// + /// + /// The to use. + /// + 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 ); + } + + /// + /// Generates the IL instructions that pushes + /// the target instance on which calls should be delegated to. + /// + /// The IL generator to use. + 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) diff --git a/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentHelper.cs b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentHelper.cs new file mode 100644 index 00000000..91e43353 --- /dev/null +++ b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentHelper.cs @@ -0,0 +1,104 @@ +#region License + +/* + * Copyright © 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 +{ + /// + /// + /// + /// Erich Eichinger + public class ServicedComponentHelper + { + private static bool isInitialized; + private static string componentDirectory; + + static ServicedComponentHelper() + { + isInitialized = false; + } + + /// + /// + /// + 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; + } + + /// + /// + /// + /// + /// + public static object GetObject(ServicedComponent sender, string targetName) + { + EnsureComponentContextRegistryInitialized(sender); + return ContextRegistry.GetContext().GetObject(targetName); + // return null; + } + + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Services/Spring.Services.2003.csproj b/src/Spring/Spring.Services/Spring.Services.2003.csproj index 9942bbd7..29ba0255 100644 --- a/src/Spring/Spring.Services/Spring.Services.2003.csproj +++ b/src/Spring/Spring.Services/Spring.Services.2003.csproj @@ -1,7 +1,7 @@ @@ -127,6 +127,11 @@ SubType = "Code" BuildAction = "Compile" /> + + Spring.Services - - + ..\..\..\Spring.Net.snk JScript Grid IE50 @@ -22,6 +21,7 @@ OnBuildSuccess + false
..\..\..\build\VS.Net.2005\Spring.Services\Debug\ @@ -80,6 +80,7 @@ System + System.Data @@ -101,6 +102,8 @@ + + diff --git a/src/Spring/Spring.Services/Spring.Services.2008.csproj b/src/Spring/Spring.Services/Spring.Services.2008.csproj index 2dac5743..a78a4d3a 100644 --- a/src/Spring/Spring.Services/Spring.Services.2008.csproj +++ b/src/Spring/Spring.Services/Spring.Services.2008.csproj @@ -1,7 +1,7 @@  Local - 9.0.21022 + 9.0.30729 2.0 {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Debug @@ -99,8 +99,10 @@ + + Code diff --git a/test/Spring/Spring.Services.Tests/EnterpriseServices/ExportedServicedComponentSample.cs b/test/Spring/Spring.Services.Tests/EnterpriseServices/ExportedServicedComponentSample.cs new file mode 100644 index 00000000..ae687813 --- /dev/null +++ b/test/Spring/Spring.Services.Tests/EnterpriseServices/ExportedServicedComponentSample.cs @@ -0,0 +1,79 @@ +#region License + +/* + * Copyright © 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(); + } + } +} \ No newline at end of file diff --git a/test/Spring/Spring.Services.Tests/EnterpriseServices/ServicedComponentExporterTests.cs b/test/Spring/Spring.Services.Tests/EnterpriseServices/ServicedComponentExporterTests.cs index fd1c83f4..d0837eaa 100644 --- a/test/Spring/Spring.Services.Tests/EnterpriseServices/ServicedComponentExporterTests.cs +++ b/test/Spring/Spring.Services.Tests/EnterpriseServices/ServicedComponentExporterTests.cs @@ -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); diff --git a/test/Spring/Spring.Services.Tests/Spring.Services.Tests.2003.csproj b/test/Spring/Spring.Services.Tests/Spring.Services.Tests.2003.csproj index 32f72256..50f340c5 100644 --- a/test/Spring/Spring.Services.Tests/Spring.Services.Tests.2003.csproj +++ b/test/Spring/Spring.Services.Tests/Spring.Services.Tests.2003.csproj @@ -1,7 +1,7 @@ @@ -178,6 +178,10 @@ RelPath = "Data\Spring\Remoting\saoSingleton-aop.xml" BuildAction = "EmbeddedResource" /> + + Code +