diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EmployeeInfo/Default.aspx.cs b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EmployeeInfo/Default.aspx.cs
index d54b3009..c517c8b0 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EmployeeInfo/Default.aspx.cs
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EmployeeInfo/Default.aspx.cs
@@ -21,19 +21,19 @@ public partial class DataBinding_EmployeeInfo_Default : Spring.Web.UI.Page
///
protected override void InitializeDataBindings()
{
- BindingManager.AddBinding("txtId.Text", "Employee.Id");
- BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
- BindingManager.AddBinding("txtLastName.Text", "Employee.LastName");
- BindingManager.AddBinding("txtDOB.Text", "Employee.DateOfBirth");
- BindingManager.AddBinding("txtSalary.Text", "Employee.Salary");
- BindingManager.AddBinding("rbgGender.Value", "Employee.Gender");
- BindingManager.AddBinding("ddlAddressType.SelectedValue", "Employee.MailingAddress.AddressType");
- BindingManager.AddBinding("txtStreet1.Text", "Employee.MailingAddress.Street1");
- BindingManager.AddBinding("txtStreet2.Text", "Employee.MailingAddress.Street2");
- BindingManager.AddBinding("txtCity.Text", "Employee.MailingAddress.City");
- BindingManager.AddBinding("txtState.Text", "Employee.MailingAddress.State");
- BindingManager.AddBinding("txtPostalCode.Text", "Employee.MailingAddress.PostalCode");
- BindingManager.AddBinding("txtCountry.Text", "Employee.MailingAddress.Country");
+ BindingManager.AddBinding("FindControl('txtId').Text", "Employee.Id");
+ BindingManager.AddBinding("FindControl('txtFirstName').Text", "Employee.FirstName");
+ BindingManager.AddBinding("FindControl('txtLastName').Text", "Employee.LastName");
+ BindingManager.AddBinding("FindControl('txtDOB').Text", "Employee.DateOfBirth");
+ BindingManager.AddBinding("FindControl('txtSalary').Text", "Employee.Salary");
+ BindingManager.AddBinding("FindControl('rbgGender').Value", "Employee.Gender");
+ BindingManager.AddBinding("FindControl('ddlAddressType').SelectedValue", "Employee.MailingAddress.AddressType");
+ BindingManager.AddBinding("FindControl('txtStreet1').Text", "Employee.MailingAddress.Street1");
+ BindingManager.AddBinding("FindControl('txtStreet2').Text", "Employee.MailingAddress.Street2");
+ BindingManager.AddBinding("FindControl('txtCity').Text", "Employee.MailingAddress.City");
+ BindingManager.AddBinding("FindControl('txtState').Text", "Employee.MailingAddress.State");
+ BindingManager.AddBinding("FindControl('txtPostalCode').Text", "Employee.MailingAddress.PostalCode");
+ BindingManager.AddBinding("FindControl('txtCountry').Text", "Employee.MailingAddress.Country");
}
protected void Page_Load(object sender, EventArgs e)
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EventHandling/Default.aspx b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EventHandling/Default.aspx
index b513448c..74781fba 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EventHandling/Default.aspx
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EventHandling/Default.aspx
@@ -1,4 +1,4 @@
-<%@ Page Language="C#" EnableViewState="false" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="DataBinding_EventHandling_Default" %>
+<%@ Page Language="C#" Debug="true" EnableViewState="false" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="DataBinding_EventHandling_Default" %>
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EventHandling/Default.aspx.cs b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EventHandling/Default.aspx.cs
index 18614799..5e7a00a9 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EventHandling/Default.aspx.cs
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/EventHandling/Default.aspx.cs
@@ -1,4 +1,5 @@
using System;
+using System.Web.UI.WebControls;
using Spring.DataBinding;
///
@@ -22,8 +23,8 @@ public partial class DataBinding_EventHandling_Default : Spring.Web.UI.Page
///
protected override void InitializeDataBindings()
{
- BindingManager.AddBinding("txtName.Text", "Name");
- BindingManager.AddBinding("lblName.Text", "Name", BindingDirection.TargetToSource);
+ BindingManager.AddBinding("FindControl('txtName').Text", "Name");
+ BindingManager.AddBinding("FindControl('lblName').Text", "Name", BindingDirection.TargetToSource);
}
protected void Page_Load(object sender, EventArgs e)
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/HelloWorld/Default.aspx.cs b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/HelloWorld/Default.aspx.cs
index b53707b3..638c485a 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/HelloWorld/Default.aspx.cs
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/HelloWorld/Default.aspx.cs
@@ -22,8 +22,8 @@ public partial class DataBinding_HelloWorld_Default : Spring.Web.UI.Page
///
protected override void InitializeDataBindings()
{
- BindingManager.AddBinding("txtName.Text", "Name");
- BindingManager.AddBinding("lblName.Text", "Name", BindingDirection.TargetToSource);
+ BindingManager.AddBinding("FindControl('txtName').Text", "Name");
+ BindingManager.AddBinding("FindControl('lblName').Text", "Name", BindingDirection.TargetToSource);
}
protected void Page_Load(object sender, EventArgs e)
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/Lists/Default.aspx.cs b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/Lists/Default.aspx.cs
index ea80d961..d8bce27a 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/Lists/Default.aspx.cs
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/Lists/Default.aspx.cs
@@ -26,19 +26,19 @@ public partial class DataBinding_Lists_Default : Page
///
protected override void InitializeDataBindings()
{
- BindingManager.AddBinding("txtId.Text", "Employee.Id");
- BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
+ BindingManager.AddBinding("FindControl('txtId').Text", "Employee.Id");
+ BindingManager.AddBinding("FindControl('txtFirstName').Text", "Employee.FirstName");
// this is rather verbose to show how it works
// the formatter must convert between ListControl values and domain objects identified by these values (e.g. a key)
IFormatter dsFormatter = new DataSourceItemFormatter("DataSource", "DataValueField");
// bind the lstHobbies control to Employee.Hobbies IList
- MultipleSelectionListControlBinding listBinding = new MultipleSelectionListControlBinding("lstHobbies", "Employee.Hobbies", BindingDirection.Bidirectional, dsFormatter);
+ MultipleSelectionListControlBinding listBinding = new MultipleSelectionListControlBinding("FindControl('lstHobbies')", "Employee.Hobbies", BindingDirection.Bidirectional, dsFormatter);
BindingManager.AddBinding(listBinding);
// use simple name=value binding
- BindingManager.AddBinding(new MultipleSelectionListControlBinding("lstFavoriteFood", "Employee.FavoriteFood", BindingDirection.Bidirectional, new NullFormatter()));
+ BindingManager.AddBinding(new MultipleSelectionListControlBinding("FindControl('lstFavoriteFood')", "Employee.FavoriteFood", BindingDirection.Bidirectional, new NullFormatter()));
}
protected override void OnInitializeControls(EventArgs e)
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/NestedEmployeeInfo/EmployeeInfoEditor.ascx.cs b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/NestedEmployeeInfo/EmployeeInfoEditor.ascx.cs
index 7c78020a..6e1df6b6 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/NestedEmployeeInfo/EmployeeInfoEditor.ascx.cs
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/NestedEmployeeInfo/EmployeeInfoEditor.ascx.cs
@@ -18,22 +18,22 @@ public partial class EmployeeInfoEditor : Spring.Web.UI.UserControl
///
protected override void InitializeDataBindings()
{
- BindingManager.AddBinding("txtId.Text", "Employee.Id")
+ BindingManager.AddBinding("FindControl('txtId').Text", "Employee.Id")
.SetErrorMessage("ID has to be an integer", "id.errors", "summary");
- BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
- BindingManager.AddBinding("txtLastName.Text", "Employee.LastName");
- BindingManager.AddBinding("txtDOB.Text", "Employee.DateOfBirth")
+ BindingManager.AddBinding("FindControl('txtFirstName').Text", "Employee.FirstName");
+ BindingManager.AddBinding("FindControl('txtLastName').Text", "Employee.LastName");
+ BindingManager.AddBinding("FindControl('txtDOB').Text", "Employee.DateOfBirth")
.SetErrorMessage("Invalid date value", "dob.errors", "summary");
- BindingManager.AddBinding("txtSalary.Text", "Employee.Salary", new CurrencyFormatter())
+ BindingManager.AddBinding("FindControl('txtSalary').Text", "Employee.Salary", new CurrencyFormatter())
.SetErrorMessage("Salary must be a valid currency value.", "salary.errors", "summary");
- BindingManager.AddBinding("rbgGender.Value", "Employee.Gender");
- BindingManager.AddBinding("ddlAddressType.SelectedValue", "Employee.MailingAddress.AddressType");
- BindingManager.AddBinding("txtStreet1.Text", "Employee.MailingAddress.Street1");
- BindingManager.AddBinding("txtStreet2.Text", "Employee.MailingAddress.Street2");
- BindingManager.AddBinding("txtCity.Text", "Employee.MailingAddress.City");
- BindingManager.AddBinding("txtState.Text", "Employee.MailingAddress.State");
- BindingManager.AddBinding("txtPostalCode.Text", "Employee.MailingAddress.PostalCode");
- BindingManager.AddBinding("txtCountry.Text", "Employee.MailingAddress.Country");
+ BindingManager.AddBinding("FindControl('rbgGender').Value", "Employee.Gender");
+ BindingManager.AddBinding("FindControl('ddlAddressType').SelectedValue", "Employee.MailingAddress.AddressType");
+ BindingManager.AddBinding("FindControl('txtStreet1').Text", "Employee.MailingAddress.Street1");
+ BindingManager.AddBinding("FindControl('txtStreet2').Text", "Employee.MailingAddress.Street2");
+ BindingManager.AddBinding("FindControl('txtCity').Text", "Employee.MailingAddress.City");
+ BindingManager.AddBinding("FindControl('txtState').Text", "Employee.MailingAddress.State");
+ BindingManager.AddBinding("FindControl('txtPostalCode').Text", "Employee.MailingAddress.PostalCode");
+ BindingManager.AddBinding("FindControl('txtCountry').Text", "Employee.MailingAddress.Country");
}
protected void btnSave_Click(object sender, EventArgs e)
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/RobustEmployeeInfo/Default.aspx b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/RobustEmployeeInfo/Default.aspx
index 9b5ef98f..737bce8b 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/RobustEmployeeInfo/Default.aspx
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/RobustEmployeeInfo/Default.aspx
@@ -34,7 +34,7 @@
so you can see how Employee object was populated by the framework.
-
+
| Employee ID: |
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/RobustEmployeeInfo/Default.aspx.cs b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/RobustEmployeeInfo/Default.aspx.cs
index a03a0b11..7866b1c4 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/RobustEmployeeInfo/Default.aspx.cs
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/DataBinding/RobustEmployeeInfo/Default.aspx.cs
@@ -22,22 +22,26 @@ public partial class DataBinding_RobustEmployeeInfo_Default : Spring.Web.UI.Page
///
protected override void InitializeDataBindings()
{
- BindingManager.AddBinding("txtId.Text", "Employee.Id")
+ // the line below would also work in full trusted environments due to control members
+ // being generated as protected members by ASP.NET:
+ // BindingManager.AddBinding("txtId.Text", "Employee.Id")
+
+ BindingManager.AddBinding("FindControl('txtId').Text", "Employee.Id")
.SetErrorMessage("ID has to be an integer", "id.errors"); // send msg to "id.errors" provider
- BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
- BindingManager.AddBinding("txtLastName.Text", "Employee.LastName");
- BindingManager.AddBinding("txtDOB.Text", "Employee.DateOfBirth")
+ BindingManager.AddBinding("FindControl('txtFirstName').Text", "Employee.FirstName");
+ BindingManager.AddBinding("FindControl('txtLastName').Text", "Employee.LastName");
+ BindingManager.AddBinding("FindControl('txtDOB').Text", "Employee.DateOfBirth")
.SetErrorMessage("Invalid date value", "dob.errors");
- BindingManager.AddBinding("txtSalary.Text", "Employee.Salary", new CurrencyFormatter())
+ BindingManager.AddBinding("FindControl('txtSalary').Text", "Employee.Salary", new CurrencyFormatter())
.SetErrorMessage("Salary must be a valid currency value.", "salary.errors");
- BindingManager.AddBinding("rbgGender.Value", "Employee.Gender");
- BindingManager.AddBinding("ddlAddressType.SelectedValue", "Employee.MailingAddress.AddressType");
- BindingManager.AddBinding("txtStreet1.Text", "Employee.MailingAddress.Street1");
- BindingManager.AddBinding("txtStreet2.Text", "Employee.MailingAddress.Street2");
- BindingManager.AddBinding("txtCity.Text", "Employee.MailingAddress.City");
- BindingManager.AddBinding("txtState.Text", "Employee.MailingAddress.State");
- BindingManager.AddBinding("txtPostalCode.Text", "Employee.MailingAddress.PostalCode");
- BindingManager.AddBinding("txtCountry.Text", "Employee.MailingAddress.Country");
+ BindingManager.AddBinding("FindControl('rbgGender').Value", "Employee.Gender");
+ BindingManager.AddBinding("FindControl('ddlAddressType').SelectedValue", "Employee.MailingAddress.AddressType");
+ BindingManager.AddBinding("FindControl('txtStreet1').Text", "Employee.MailingAddress.Street1");
+ BindingManager.AddBinding("FindControl('txtStreet2').Text", "Employee.MailingAddress.Street2");
+ BindingManager.AddBinding("FindControl('txtCity').Text", "Employee.MailingAddress.City");
+ BindingManager.AddBinding("FindControl('txtState').Text", "Employee.MailingAddress.State");
+ BindingManager.AddBinding("FindControl('txtPostalCode').Text", "Employee.MailingAddress.PostalCode");
+ BindingManager.AddBinding("FindControl('txtCountry').Text", "Employee.MailingAddress.Country");
}
protected void Page_Load(object sender, EventArgs e)
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/Navigation/Default.aspx b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/Navigation/Default.aspx
index 9c0aaf0b..338a65e8 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/Navigation/Default.aspx
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/Navigation/Default.aspx
@@ -7,7 +7,7 @@
Spring.Web allows for "symbolic" names for navigation targets and navigate to such a target by
calling SetResult( symbolicName ) on the page object.
-
+
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/Web.Config b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/Web.Config
index 909cd73b..797b7f55 100644
--- a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/Web.Config
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/Web.Config
@@ -2,11 +2,11 @@
-
-
+
+
-
+
@@ -18,6 +18,13 @@
+
+
+
+
+
+
+
@@ -31,9 +38,9 @@
-->
-
-
-
+
+
+
diff --git a/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/web_mediumtrust.config b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/web_mediumtrust.config
new file mode 100644
index 00000000..0cae3044
--- /dev/null
+++ b/examples/Spring/Spring.WebQuickStart/src/Spring.WebQuickStart.2005/web_mediumtrust.config
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Spring/Spring.Core/AssemblyInfo.cs b/src/Spring/Spring.Core/AssemblyInfo.cs
index 7282cf2a..74041e7b 100644
--- a/src/Spring/Spring.Core/AssemblyInfo.cs
+++ b/src/Spring/Spring.Core/AssemblyInfo.cs
@@ -18,9 +18,10 @@
#endregion
+using System;
using System.Reflection;
using System.Runtime.InteropServices;
-using System.Security.Permissions;
+using System.Security;
[assembly: ComVisible(false)]
[assembly: AssemblyTitle("Spring.Core")]
@@ -29,7 +30,24 @@ using System.Security.Permissions;
//
// Security Permissions
//
-// we need full, unrestricted access to reflection metadata...
-[assembly: ReflectionPermission(SecurityAction.RequestMinimum, Unrestricted=true)]
+// we need full, unrestricted access to reflection metadata...
+//[assembly: ReflectionPermission(SecurityAction.RequestMinimum, Unrestricted = true)]
//[assembly: AssemblyKeyFile(@"C:\users\aseovic\projects\OpenSource\Spring.Net\Spring.Net.PrivateKey.keys")]
-//[assembly: AssemblyKeyFile(@"C:\projects\Spring.Net\Spring.Net.snk")]
\ No newline at end of file
+//[assembly: AssemblyKeyFile(@"C:\projects\Spring.Net\Spring.Net.snk")]
+[assembly: AllowPartiallyTrustedCallers]
+
+[assembly: SecurityCritical]
+
+#if NET_1_0 || NET_1_1
+namespace System.Security
+{
+ ///
+ ///
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method)]
+ internal class SecurityCriticalAttribute : Attribute
+ { }
+ [AttributeUsage(AttributeTargets.Method)]
+ internal class SecurityTreatAsSafeAttribute : Attribute
+ { }
+}
+#endif
diff --git a/src/Spring/Spring.Core/Core/IO/ResourceHandlerRegistry.cs b/src/Spring/Spring.Core/Core/IO/ResourceHandlerRegistry.cs
index fcf3698c..20ff9f92 100644
--- a/src/Spring/Spring.Core/Core/IO/ResourceHandlerRegistry.cs
+++ b/src/Spring/Spring.Core/Core/IO/ResourceHandlerRegistry.cs
@@ -1,5 +1,5 @@
-#region License
-
+#region License
+
/*
* Copyright 2002-2004 the original author or authors.
*
@@ -14,273 +14,277 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-
-#endregion
-
-using System;
-using System.Collections;
-using System.Reflection;
-
-using Spring.Context.Support;
-using Spring.Core.TypeResolution;
-using Spring.Util;
-using Spring.Reflection.Dynamic;
-
-namespace Spring.Core.IO
-{
- ///
- /// Registry class that allows users to register and retrieve protocol handlers.
- ///
- ///
- ///
- /// Resource handler is an implementation of interface
- /// that should be used to process resources with the specified protocol.
- ///
- ///
- /// They are used throughout the framework to access resources from various
- /// sources. For example, application context loads object definitions from the resources
- /// that are processed using one of the registered resource handlers.
- ///
- /// Following resource handlers are registered by default:
- ///
- ///
- /// Protocol
- /// Handler Type
- /// Description
- ///
- /// -
- /// config
- ///
- /// Resolves the resources by loading specified configuration section from the standard .NET config file.
- ///
- /// -
- /// file
- ///
- /// Resolves filesystem resources.
- ///
- /// -
- /// http
- ///
- /// Resolves remote web resources.
- ///
- /// -
- /// https
- ///
- /// Resolves remote web resources via HTTPS.
- ///
- /// -
- /// ftp
- ///
- /// Resolves ftp resources.
- ///
- /// -
- /// assembly
- ///
- /// Resolves resources that are embedded into an assembly.
- ///
- /// -
- /// web
- /// Spring.Core.IO.WebResource, Spring.Web*
- /// Resolves resources relative to the web application's virtual directory.
- ///
- ///
- /// * only available in web applications.
- ///
- /// Users can create and register their own protocol handlers by implementing interface
- /// and mapping custom protocol name to that implementation. See for details
- /// on how to register custom protocol handler.
- ///
- ///
- /// Aleksandar Seovic
- public class ResourceHandlerRegistry
- {
- ///
- /// Name of the .Net config section that contains definitions
- /// for custom resource handlers.
- ///
- private const string ResourcesSectionName = "spring/resourceHandlers";
-
- private static IDictionary resourceHandlers = new Hashtable();
-
- ///
- /// Registers standard and user-configured resource handlers.
- ///
- static ResourceHandlerRegistry()
- {
- lock (resourceHandlers.SyncRoot)
- {
- RegisterResourceHandler("config", typeof(ConfigSectionResource));
- RegisterResourceHandler("file", typeof(FileSystemResource));
- RegisterResourceHandler("http", typeof(UrlResource));
- RegisterResourceHandler("https", typeof(UrlResource));
-#if NET_2_0
- RegisterResourceHandler("ftp", typeof(UrlResource));
-#endif
- RegisterResourceHandler("assembly", typeof(AssemblyResource));
-
- // register custom resource handlers
- ConfigurationUtils.GetSection(ResourcesSectionName);
- }
- }
-
- ///
- /// Returns resource handler for the specified protocol name.
- ///
- ///
- ///
- /// This method returns object that should be used
- /// to create an instance of the -derived type by passing
- /// resource location as a parameter.
- ///
- ///
- /// Name of the protocol to get the handler for.
- /// Resource handler constructor for the specified protocol name.
- /// If is null.
- public static IDynamicConstructor GetResourceHandler(string protocolName)
- {
- AssertUtils.ArgumentNotNull(protocolName, "protocolName");
- return (IDynamicConstructor) resourceHandlers[protocolName];
- }
-
- ///
- /// Returns true if a handler is registered for the specified protocol,
- /// false otherwise.
- ///
- /// Name of the protocol.
- ///
- /// true if a handler is registered for the specified protocol, false otherwise.
- ///
- /// If is null.
- public static bool IsHandlerRegistered(string protocolName)
- {
- return resourceHandlers.Contains(protocolName);
- }
-
- ///
- /// Registers resource handler and maps it to the specified protocol name.
- ///
- ///
- ///
- /// If the mapping already exists, the existing mapping will be
- /// silently overwritten with the new mapping.
- ///
- ///
- ///
- /// The protocol to add (or override).
- ///
- ///
- /// The type name of the concrete implementation of the
- /// interface that will handle
- /// the specified protocol.
- ///
- ///
- /// If the supplied is
- /// or contains only whitespace character(s); or
- /// if the supplied is
- /// .
- ///
- ///
- /// If the supplied is not a
- /// that derives from the
- /// interface; or (having passed
- /// this first check), the supplied
- /// does not expose a constructor that takes a single
- /// parameter.
- ///
- public static void RegisterResourceHandler(string protocolName, string handlerTypeName)
- {
- AssertUtils.ArgumentHasText(protocolName, "protocolName");
- AssertUtils.ArgumentHasText(handlerTypeName, "handlerTypeName");
-
- Type handlerType = TypeResolutionUtils.ResolveType(handlerTypeName);
- RegisterResourceHandler(protocolName, handlerType);
- }
-
- ///
- /// Registers resource handler and maps it to the specified protocol name.
- ///
- ///
- ///
- /// If the mapping already exists, the existing mapping will be
- /// silently overwritten with the new mapping.
- ///
- ///
- ///
- /// The protocol to add (or override).
- ///
- ///
- /// The concrete implementation of the
- /// interface that will handle
- /// the specified protocol.
- ///
- ///
- /// If the supplied is
- /// or contains only whitespace character(s); or
- /// if the supplied is
- /// .
- ///
- ///
- /// If the supplied is not a
- /// that derives from the
- /// interface; or (having passed
- /// this first check), the supplied
- /// does not expose a constructor that takes a single
- /// parameter.
- ///
- public static void RegisterResourceHandler(string protocolName, Type handlerType)
- {
- #region Sanity Checks
-
- AssertUtils.ArgumentHasText(protocolName, "protocolName");
- AssertUtils.ArgumentNotNull(handlerType, "handlerType");
- if (!typeof(IResource).IsAssignableFrom(handlerType))
- {
- throw new ArgumentException(
- string.Format("[{0}] does not implement [{1}] interface (it must).", handlerType.FullName, typeof(IResource).FullName));
- }
-
- #endregion
-
- lock (resourceHandlers.SyncRoot)
- {
-#if NET_2_0
- // register generic uri parser for this scheme
- if (!UriParser.IsKnownScheme(protocolName))
+ */
+
+#endregion
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Security;
+using System.Security.Permissions;
+using Spring.Context.Support;
+using Spring.Core.TypeResolution;
+using Spring.Util;
+using Spring.Reflection.Dynamic;
+
+namespace Spring.Core.IO
+{
+ ///
+ /// Registry class that allows users to register and retrieve protocol handlers.
+ ///
+ ///
+ ///
+ /// Resource handler is an implementation of interface
+ /// that should be used to process resources with the specified protocol.
+ ///
+ ///
+ /// They are used throughout the framework to access resources from various
+ /// sources. For example, application context loads object definitions from the resources
+ /// that are processed using one of the registered resource handlers.
+ ///
+ /// Following resource handlers are registered by default:
+ ///
+ ///
+ /// Protocol
+ /// Handler Type
+ /// Description
+ ///
+ /// -
+ /// config
+ ///
+ /// Resolves the resources by loading specified configuration section from the standard .NET config file.
+ ///
+ /// -
+ /// file
+ ///
+ /// Resolves filesystem resources.
+ ///
+ /// -
+ /// http
+ ///
+ /// Resolves remote web resources.
+ ///
+ /// -
+ /// https
+ ///
+ /// Resolves remote web resources via HTTPS.
+ ///
+ /// -
+ /// ftp
+ ///
+ /// Resolves ftp resources.
+ ///
+ /// -
+ /// assembly
+ ///
+ /// Resolves resources that are embedded into an assembly.
+ ///
+ /// -
+ /// web
+ /// Spring.Core.IO.WebResource, Spring.Web*
+ /// Resolves resources relative to the web application's virtual directory.
+ ///
+ ///
+ /// * only available in web applications.
+ ///
+ /// Users can create and register their own protocol handlers by implementing interface
+ /// and mapping custom protocol name to that implementation. See for details
+ /// on how to register custom protocol handler.
+ ///
+ ///
+ /// Aleksandar Seovic
+ public class ResourceHandlerRegistry
+ {
+ ///
+ /// Name of the .Net config section that contains definitions
+ /// for custom resource handlers.
+ ///
+ private const string ResourcesSectionName = "spring/resourceHandlers";
+
+ private static IDictionary resourceHandlers = new Hashtable();
+
+ ///
+ /// Registers standard and user-configured resource handlers.
+ ///
+ static ResourceHandlerRegistry()
+ {
+ lock (resourceHandlers.SyncRoot)
+ {
+ RegisterResourceHandler("config", typeof(ConfigSectionResource));
+ RegisterResourceHandler("file", typeof(FileSystemResource));
+ RegisterResourceHandler("http", typeof(UrlResource));
+ RegisterResourceHandler("https", typeof(UrlResource));
+#if NET_2_0
+ RegisterResourceHandler("ftp", typeof(UrlResource));
+#endif
+ RegisterResourceHandler("assembly", typeof(AssemblyResource));
+
+ // register custom resource handlers
+ ConfigurationUtils.GetSection(ResourcesSectionName);
+ }
+ }
+
+ ///
+ /// Returns resource handler for the specified protocol name.
+ ///
+ ///
+ ///
+ /// This method returns object that should be used
+ /// to create an instance of the -derived type by passing
+ /// resource location as a parameter.
+ ///
+ ///
+ /// Name of the protocol to get the handler for.
+ /// Resource handler constructor for the specified protocol name.
+ /// If is null.
+ public static IDynamicConstructor GetResourceHandler(string protocolName)
+ {
+ AssertUtils.ArgumentNotNull(protocolName, "protocolName");
+ return (IDynamicConstructor)resourceHandlers[protocolName];
+ }
+
+ ///
+ /// Returns true if a handler is registered for the specified protocol,
+ /// false otherwise.
+ ///
+ /// Name of the protocol.
+ ///
+ /// true if a handler is registered for the specified protocol, false otherwise.
+ ///
+ /// If is null.
+ public static bool IsHandlerRegistered(string protocolName)
+ {
+ return resourceHandlers.Contains(protocolName);
+ }
+
+ ///
+ /// Registers resource handler and maps it to the specified protocol name.
+ ///
+ ///
+ ///
+ /// If the mapping already exists, the existing mapping will be
+ /// silently overwritten with the new mapping.
+ ///
+ ///
+ ///
+ /// The protocol to add (or override).
+ ///
+ ///
+ /// The type name of the concrete implementation of the
+ /// interface that will handle
+ /// the specified protocol.
+ ///
+ ///
+ /// If the supplied is
+ /// or contains only whitespace character(s); or
+ /// if the supplied is
+ /// .
+ ///
+ ///
+ /// If the supplied is not a
+ /// that derives from the
+ /// interface; or (having passed
+ /// this first check), the supplied
+ /// does not expose a constructor that takes a single
+ /// parameter.
+ ///
+ public static void RegisterResourceHandler(string protocolName, string handlerTypeName)
+ {
+ AssertUtils.ArgumentHasText(protocolName, "protocolName");
+ AssertUtils.ArgumentHasText(handlerTypeName, "handlerTypeName");
+
+ Type handlerType = TypeResolutionUtils.ResolveType(handlerTypeName);
+ RegisterResourceHandler(protocolName, handlerType);
+ }
+
+ ///
+ /// Registers resource handler and maps it to the specified protocol name.
+ ///
+ ///
+ ///
+ /// If the mapping already exists, the existing mapping will be
+ /// silently overwritten with the new mapping.
+ ///
+ ///
+ ///
+ /// The protocol to add (or override).
+ ///
+ ///
+ /// The concrete implementation of the
+ /// interface that will handle
+ /// the specified protocol.
+ ///
+ ///
+ /// If the supplied is
+ /// or contains only whitespace character(s); or
+ /// if the supplied is
+ /// .
+ ///
+ ///
+ /// If the supplied is not a
+ /// that derives from the
+ /// interface; or (having passed
+ /// this first check), the supplied
+ /// does not expose a constructor that takes a single
+ /// parameter.
+ ///
+ public static void RegisterResourceHandler(string protocolName, Type handlerType)
+ {
+ #region Sanity Checks
+
+ AssertUtils.ArgumentHasText(protocolName, "protocolName");
+ AssertUtils.ArgumentNotNull(handlerType, "handlerType");
+ if (!typeof(IResource).IsAssignableFrom(handlerType))
+ {
+ throw new ArgumentException(
+ string.Format("[{0}] does not implement [{1}] interface (it must).", handlerType.FullName, typeof(IResource).FullName));
+ }
+
+ #endregion
+
+ lock (resourceHandlers.SyncRoot)
+ {
+#if NET_2_0
+ SecurityCritical.ExecutePrivileged( new SecurityPermission(SecurityPermissionFlag.Infrastructure), delegate
{
- UriParser.Register(new TolerantUriParser(), protocolName, 0);
- }
-#endif
- IDynamicConstructor ctor = GetResourceConstructor(handlerType);
- resourceHandlers[protocolName] = ctor;
- }
- }
-
-#if NET_2_0
+ // register generic uri parser for this scheme
+ if (!UriParser.IsKnownScheme(protocolName))
+ {
+ UriParser.Register(new TolerantUriParser(), protocolName, 0);
+ }
+ });
+#endif
+ IDynamicConstructor ctor = GetResourceConstructor(handlerType);
+ resourceHandlers[protocolName] = ctor;
+ }
+ }
+
+#if NET_2_0
///
/// Allows to create any arbitrary Url format
- ///
- private class TolerantUriParser : GenericUriParser
+ ///
+ private class TolerantUriParser : GenericUriParser
{
private const GenericUriParserOptions DefaultOptions = GenericUriParserOptions.Default
- |GenericUriParserOptions.GenericAuthority
- |GenericUriParserOptions.AllowEmptyAuthority;
+ | GenericUriParserOptions.GenericAuthority
+ | GenericUriParserOptions.AllowEmptyAuthority;
- public TolerantUriParser()
+ public TolerantUriParser()
: base(DefaultOptions)
- {}
- }
-#endif
-
- private static IDynamicConstructor GetResourceConstructor(Type handlerType)
- {
- ConstructorInfo ctor = handlerType.GetConstructor(new Type[] {typeof(string)});
- if (ctor == null)
- {
- throw new ArgumentException(
- string.Format("[{0}] does not have a constructor that takes a single string as an argument (it must).", handlerType.FullName));
- }
- return DynamicConstructor.Create(ctor);
- }
- }
+ { }
+ }
+#endif
+
+ private static IDynamicConstructor GetResourceConstructor(Type handlerType)
+ {
+ ConstructorInfo ctor = handlerType.GetConstructor(new Type[] { typeof(string) });
+ if (ctor == null)
+ {
+ throw new ArgumentException(
+ string.Format("[{0}] does not have a constructor that takes a single string as an argument (it must).", handlerType.FullName));
+ }
+ return new SafeConstructor(ctor);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Spring/Spring.Core/DataBinding/AbstractSimpleBinding.cs b/src/Spring/Spring.Core/DataBinding/AbstractSimpleBinding.cs
index e3a02573..f87f6d84 100644
--- a/src/Spring/Spring.Core/DataBinding/AbstractSimpleBinding.cs
+++ b/src/Spring/Spring.Core/DataBinding/AbstractSimpleBinding.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections;
+using System.Reflection;
+using Common.Logging;
using Spring.Globalization;
using Spring.Validation;
@@ -13,6 +15,7 @@ namespace Spring.DataBinding
{
#region Fields
+ private readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IFormatter formatter;
#endregion
@@ -132,8 +135,9 @@ namespace Spring.DataBinding
{
DoBindTargetToSource(source, target, variables);
}
- catch (Exception)
+ catch (Exception ex)
{
+ log.Warn(string.Format("Failed binding[{0}]:{1}", this.Id, ex));
if (!SetInvalid(validationErrors)) throw;
}
}
diff --git a/src/Spring/Spring.Core/Expressions/IndexerNode.cs b/src/Spring/Spring.Core/Expressions/IndexerNode.cs
index e1ce7367..7bf94bec 100644
--- a/src/Spring/Spring.Core/Expressions/IndexerNode.cs
+++ b/src/Spring/Spring.Core/Expressions/IndexerNode.cs
@@ -273,16 +273,21 @@ namespace Spring.Expressions
{
if (indexer == null)
{
+ Type contextType = context.GetType();
Type[] argTypes = ReflectionUtils.GetTypes(indices);
- PropertyInfo indexerProperty = context.GetType().GetProperty("Item", BINDING_FLAGS, null, null, argTypes, null);
+ string defaultMember = "Item";
+ object[] atts = contextType.GetCustomAttributes(typeof(DefaultMemberAttribute), true);
+ if (atts != null && atts.Length > 0)
+ {
+ defaultMember = ((DefaultMemberAttribute) atts[0]).MemberName;
+ }
+ PropertyInfo indexerProperty = contextType.GetProperty(defaultMember, BINDING_FLAGS, null, null, argTypes, null);
if (indexerProperty == null)
{
throw new ArgumentException("Indexer property with specified number and types of arguments does not exist.");
}
- else
- {
- indexer = new SafeProperty(indexerProperty);
- }
+
+ indexer = new SafeProperty(indexerProperty);
}
}
}
diff --git a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs
index 1a847528..214142e4 100644
--- a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs
+++ b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs
@@ -25,6 +25,9 @@ using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.Security.Permissions;
using Spring.Util;
#if NET_2_0
@@ -40,14 +43,14 @@ namespace Spring.Reflection.Dynamic
///
/// the target instance when calling an instance method
/// the value return by the Get method
- public delegate object FieldGetterDelegate( object target );
+ public delegate object FieldGetterDelegate(object target);
///
/// Represents a Set method
///
/// the target instance when calling an instance method
/// the value to be set
- public delegate void FieldSetterDelegate( object target, object value );
+ public delegate void FieldSetterDelegate(object target, object value);
///
/// Represents an Indexer Get method
@@ -55,7 +58,7 @@ namespace Spring.Reflection.Dynamic
/// the target instance when calling an instance method
///
/// the value return by the Get method
- public delegate object PropertyGetterDelegate( object target, params object[] index );
+ public delegate object PropertyGetterDelegate(object target, params object[] index);
///
/// Represents a Set method
@@ -63,7 +66,7 @@ namespace Spring.Reflection.Dynamic
/// the target instance when calling an instance method
/// the value to be set
///
- public delegate void PropertySetterDelegate( object target, object value, params object[] index );
+ public delegate void PropertySetterDelegate(object target, object value, params object[] index);
///
/// Represents a method
@@ -71,35 +74,35 @@ namespace Spring.Reflection.Dynamic
/// the target instance when calling an instance method
/// arguments to be passed to the method
/// the value return by the method. null when calling a void method
- public delegate object FunctionDelegate( object target, params object[] args );
+ public delegate object FunctionDelegate(object target, params object[] args);
///
/// Represents a constructor
///
/// arguments to be passed to the method
/// the new object instance
- public delegate object ConstructorDelegate( params object[] args );
+ public delegate object ConstructorDelegate(params object[] args);
///
/// Represents a callback method used to create an from a instance.
///
- internal delegate IDynamicProperty CreatePropertyCallback( PropertyInfo property );
+ internal delegate IDynamicProperty CreatePropertyCallback(PropertyInfo property);
///
/// Represents a callback method used to create an from a instance.
///
- internal delegate IDynamicField CreateFieldCallback( FieldInfo property );
+ internal delegate IDynamicField CreateFieldCallback(FieldInfo property);
///
/// Represents a callback method used to create an from a instance.
///
- internal delegate IDynamicMethod CreateMethodCallback( MethodInfo method );
+ internal delegate IDynamicMethod CreateMethodCallback(MethodInfo method);
///
/// Represents a callback method used to create an from a instance.
///
- internal delegate IDynamicConstructor CreateConstructorCallback( ConstructorInfo constructor );
+ internal delegate IDynamicConstructor CreateConstructorCallback(ConstructorInfo constructor);
///
/// Represents a callback method used to create an from a instance.
///
- internal delegate IDynamicIndexer CreateIndexerCallback( PropertyInfo indexer );
+ internal delegate IDynamicIndexer CreateIndexerCallback(PropertyInfo indexer);
///
/// Allows easy access to existing and creation of new dynamic relection members.
@@ -156,14 +159,14 @@ namespace Spring.Reflection.Dynamic
/// The base name to use for the reflection type name.
///
/// The type builder to use.
- internal static TypeBuilder CreateTypeBuilder( string name )
+ internal static TypeBuilder CreateTypeBuilder(string name)
{
// Generates type name
- string typeName = String.Format( "{0}.{1}_{2}",
- ASSEMBLY_NAME, name, Guid.NewGuid().ToString( "N" ) );
+ string typeName = String.Format("{0}.{1}_{2}",
+ ASSEMBLY_NAME, name, Guid.NewGuid().ToString("N"));
- ModuleBuilder module = DynamicCodeManager.GetModuleBuilder( ASSEMBLY_NAME );
- return module.DefineType( typeName, TYPE_ATTRIBUTES );
+ ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(ASSEMBLY_NAME);
+ return module.DefineType(typeName, TYPE_ATTRIBUTES);
}
///
@@ -172,14 +175,14 @@ namespace Spring.Reflection.Dynamic
/// Property to look up.
/// callback function that will be called to create the dynamic property
/// An for the given property info.
- internal static IDynamicProperty GetDynamicProperty( PropertyInfo property, CreatePropertyCallback createCallback )
+ internal static IDynamicProperty GetDynamicProperty(PropertyInfo property, CreatePropertyCallback createCallback)
{
lock (propertyCache.SyncRoot)
{
IDynamicProperty dynamicProperty = (IDynamicProperty)propertyCache[property];
if (dynamicProperty == null)
{
- dynamicProperty = createCallback( property );
+ dynamicProperty = createCallback(property);
propertyCache[property] = dynamicProperty;
}
return dynamicProperty;
@@ -192,14 +195,14 @@ namespace Spring.Reflection.Dynamic
/// Field to look up.
/// callback function that will be called to create the dynamic field
/// An for the given field info.
- internal static IDynamicField GetDynamicField( FieldInfo field, CreateFieldCallback createCallback )
+ internal static IDynamicField GetDynamicField(FieldInfo field, CreateFieldCallback createCallback)
{
lock (fieldCache.SyncRoot)
{
IDynamicField dynamicField = (IDynamicField)fieldCache[field];
if (dynamicField == null)
{
- dynamicField = createCallback( field );
+ dynamicField = createCallback(field);
fieldCache[field] = dynamicField;
}
return dynamicField;
@@ -212,14 +215,14 @@ namespace Spring.Reflection.Dynamic
/// Indexer to look up.
/// callback function that will be called to create the dynamic indexer
/// An for the given indexer.
- internal static IDynamicIndexer GetDynamicIndexer( PropertyInfo indexer, CreateIndexerCallback createCallback )
+ internal static IDynamicIndexer GetDynamicIndexer(PropertyInfo indexer, CreateIndexerCallback createCallback)
{
lock (indexerCache.SyncRoot)
{
IDynamicIndexer dynamicIndexer = (IDynamicIndexer)indexerCache[indexer];
if (dynamicIndexer == null)
{
- dynamicIndexer = createCallback( indexer );
+ dynamicIndexer = createCallback(indexer);
indexerCache[indexer] = dynamicIndexer;
}
return dynamicIndexer;
@@ -232,14 +235,14 @@ namespace Spring.Reflection.Dynamic
/// Method to look up.
/// callback function that will be called to create the dynamic method
/// An for the given method.
- internal static IDynamicMethod GetDynamicMethod( MethodInfo method, CreateMethodCallback createCallback )
+ internal static IDynamicMethod GetDynamicMethod(MethodInfo method, CreateMethodCallback createCallback)
{
lock (methodCache.SyncRoot)
{
IDynamicMethod dynamicMethod = (IDynamicMethod)methodCache[method];
if (dynamicMethod == null)
{
- dynamicMethod = createCallback( method );
+ dynamicMethod = createCallback(method);
methodCache[method] = dynamicMethod;
}
return dynamicMethod;
@@ -252,14 +255,14 @@ namespace Spring.Reflection.Dynamic
/// Constructor to look up.
/// callback function that will be called to create the dynamic constructor
/// An for the given constructor.
- internal static IDynamicConstructor GetDynamicConstructor( ConstructorInfo constructor, CreateConstructorCallback createCallback )
+ internal static IDynamicConstructor GetDynamicConstructor(ConstructorInfo constructor, CreateConstructorCallback createCallback)
{
lock (constructorCache.SyncRoot)
{
IDynamicConstructor dynamicConstructor = (IDynamicConstructor)constructorCache[constructor];
if (dynamicConstructor == null)
{
- dynamicConstructor = createCallback( constructor );
+ dynamicConstructor = createCallback(constructor);
constructorCache[constructor] = dynamicConstructor;
}
return dynamicConstructor;
@@ -270,10 +273,10 @@ namespace Spring.Reflection.Dynamic
/// Saves dynamically generated assembly to disk.
/// Can only be called in DEBUG mode, per ConditionalAttribute rules.
///
- [Conditional( "DEBUG_DYNAMIC" )]
+ [Conditional("DEBUG_DYNAMIC")]
public static void SaveAssembly()
{
- DynamicCodeManager.SaveAssembly( ASSEMBLY_NAME );
+ DynamicCodeManager.SaveAssembly(ASSEMBLY_NAME);
}
#endregion
@@ -284,14 +287,16 @@ namespace Spring.Reflection.Dynamic
///
/// the field to create the delegate for
/// a delegate that can be used to read the field
- public static FieldGetterDelegate CreateFieldGetter( FieldInfo fieldInfo )
+ public static FieldGetterDelegate CreateFieldGetter(FieldInfo fieldInfo)
{
- AssertUtils.ArgumentNotNull( fieldInfo, "You cannot create a delegate for a null value." );
+ AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value.");
- System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod( "getter", typeof( object ), new Type[] { typeof( object ) }, fieldInfo.DeclaringType.Module, true );
+ bool skipVisibility = !IsPublic(fieldInfo);
+ Type[] argumentTypes = new Type[] { typeof(object) };
+ System.Reflection.Emit.DynamicMethod dmGetter = CreateDynamicMethod("get_" + fieldInfo.Name, typeof(object), argumentTypes, fieldInfo, skipVisibility);
ILGenerator il = dmGetter.GetILGenerator();
- EmitFieldGetter( il, fieldInfo, false );
- return (FieldGetterDelegate)dmGetter.CreateDelegate( typeof( FieldGetterDelegate ) );
+ EmitFieldGetter(il, fieldInfo, false);
+ return (FieldGetterDelegate)dmGetter.CreateDelegate(typeof(FieldGetterDelegate));
}
///
@@ -303,14 +308,15 @@ namespace Spring.Reflection.Dynamic
/// If the field's returns true, the returned method
/// will throw an when called.
///
- public static FieldSetterDelegate CreateFieldSetter( FieldInfo fieldInfo )
+ public static FieldSetterDelegate CreateFieldSetter(FieldInfo fieldInfo)
{
- AssertUtils.ArgumentNotNull( fieldInfo, "You cannot create a delegate for a null value." );
+ AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value.");
- System.Reflection.Emit.DynamicMethod dmSetter = new System.Reflection.Emit.DynamicMethod( "setter", null, new Type[] { typeof( object ), typeof( object ) }, fieldInfo.DeclaringType.Module, true );
+ bool skipVisibility = !IsPublic(fieldInfo);
+ System.Reflection.Emit.DynamicMethod dmSetter = CreateDynamicMethod("set_" + fieldInfo.Name, null, new Type[] { typeof(object), typeof(object) }, fieldInfo, skipVisibility);
ILGenerator il = dmSetter.GetILGenerator();
- EmitFieldSetter( il, fieldInfo, false );
- return (FieldSetterDelegate)dmSetter.CreateDelegate( typeof( FieldSetterDelegate ) );
+ EmitFieldSetter(il, fieldInfo, false);
+ return (FieldSetterDelegate)dmSetter.CreateDelegate(typeof(FieldSetterDelegate));
}
///
@@ -322,14 +328,16 @@ namespace Spring.Reflection.Dynamic
/// If the property's returns false, the returned method
/// will throw an when called.
///
- public static PropertyGetterDelegate CreatePropertyGetter( PropertyInfo propertyInfo )
+ public static PropertyGetterDelegate CreatePropertyGetter(PropertyInfo propertyInfo)
{
- AssertUtils.ArgumentNotNull( propertyInfo, "You cannot create a delegate for a null value." );
+ AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value.");
- NetDynamicMethod dm = new NetDynamicMethod( string.Empty, typeof( object ), new Type[] { typeof( object ), typeof( object[] ) }, propertyInfo.DeclaringType.Module, true );
+ MethodInfo getMethod = propertyInfo.GetGetMethod();
+ bool skipVisibility = (null == getMethod || !IsPublic(getMethod)); // getter is public
+ NetDynamicMethod dm = CreateDynamicMethod("get_" + propertyInfo.Name, typeof(object), new Type[] { typeof(object), typeof(object[]) }, propertyInfo, skipVisibility);
ILGenerator il = dm.GetILGenerator();
- EmitPropertyGetter( il, propertyInfo, false );
- return (PropertyGetterDelegate)dm.CreateDelegate( typeof( PropertyGetterDelegate ) );
+ EmitPropertyGetter(il, propertyInfo, false);
+ return (PropertyGetterDelegate)dm.CreateDelegate(typeof(PropertyGetterDelegate));
}
///
@@ -341,14 +349,17 @@ namespace Spring.Reflection.Dynamic
/// If the property's returns false, the returned method
/// will throw an when called.
///
- public static PropertySetterDelegate CreatePropertySetter( PropertyInfo propertyInfo )
+ public static PropertySetterDelegate CreatePropertySetter(PropertyInfo propertyInfo)
{
- AssertUtils.ArgumentNotNull( propertyInfo, "You cannot create a delegate for a null value." );
+ AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value.");
- NetDynamicMethod dm = new NetDynamicMethod( string.Empty, null, new Type[] { typeof( object ), typeof( object ), typeof( object[] ) }, propertyInfo.DeclaringType.Module, true );
+ MethodInfo setMethod = propertyInfo.GetSetMethod();
+ bool skipVisibility = (null == setMethod || !IsPublic(setMethod)); // setter is public
+ Type[] argumentTypes = new Type[] { typeof(object), typeof(object), typeof(object[]) };
+ NetDynamicMethod dm = CreateDynamicMethod("set_" + propertyInfo.Name, null, argumentTypes, propertyInfo, skipVisibility);
ILGenerator il = dm.GetILGenerator();
- EmitPropertySetter( il, propertyInfo, false );
- return (PropertySetterDelegate)dm.CreateDelegate( typeof( PropertySetterDelegate ) );
+ EmitPropertySetter(il, propertyInfo, false);
+ return (PropertySetterDelegate)dm.CreateDelegate(typeof(PropertySetterDelegate));
}
///
@@ -356,14 +367,15 @@ namespace Spring.Reflection.Dynamic
///
/// the method to create the delegate for
/// a delegate that can be used to invoke the method.
- public static FunctionDelegate CreateMethod( MethodInfo methodInfo )
+ public static FunctionDelegate CreateMethod(MethodInfo methodInfo)
{
- AssertUtils.ArgumentNotNull( methodInfo, "You cannot create a delegate for a null value." );
+ AssertUtils.ArgumentNotNull(methodInfo, "You cannot create a delegate for a null value.");
- NetDynamicMethod dm = new NetDynamicMethod( string.Empty, typeof( object ), new Type[] { typeof( object ), typeof( object[] ) }, methodInfo.DeclaringType.Module, true );
+ bool skipVisibility = !IsPublic(methodInfo);
+ NetDynamicMethod dm = CreateDynamicMethod(methodInfo.Name, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo, skipVisibility);
ILGenerator il = dm.GetILGenerator();
- EmitInvokeMethod( il, methodInfo, false );
- return (FunctionDelegate)dm.CreateDelegate( typeof( FunctionDelegate ) );
+ EmitInvokeMethod(il, methodInfo, false);
+ return (FunctionDelegate)dm.CreateDelegate(typeof(FunctionDelegate));
}
///
@@ -371,45 +383,140 @@ namespace Spring.Reflection.Dynamic
///
///the constructor to create the delegate for
///delegate that can be used to invoke the constructor.
- public static ConstructorDelegate CreateConstructor(ConstructorInfo constructorInfo)
+ public static ConstructorDelegate CreateConstructor(ConstructorInfo constructorInfo)
{
- AssertUtils.ArgumentNotNull(constructorInfo, "You cannot create a dynamic constructor for a null value.");
+ AssertUtils.ArgumentNotNull(constructorInfo, "You cannot create a dynamic constructor for a null value.");
- System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod( string.Empty, typeof( object ), new Type[] { typeof( object[] ) }, constructorInfo.DeclaringType.Module, true );
+ bool skipVisibility = !IsPublic(constructorInfo);
+ System.Reflection.Emit.DynamicMethod dmGetter;
+ Type[] argumentTypes = new Type[] { typeof(object[]) };
+ dmGetter = CreateDynamicMethod(constructorInfo.Name, typeof(object), argumentTypes, constructorInfo, skipVisibility);
ILGenerator il = dmGetter.GetILGenerator();
- EmitInvokeConstructor( il, constructorInfo, false );
- ConstructorDelegate ctor = (ConstructorDelegate)dmGetter.CreateDelegate( typeof( ConstructorDelegate ) );
+ EmitInvokeConstructor(il, constructorInfo, false);
+ ConstructorDelegate ctor = (ConstructorDelegate)dmGetter.CreateDelegate(typeof(ConstructorDelegate));
return ctor;
}
+
+ ///
+ /// Creates a instance with the highest possible code access security.
+ ///
+ ///
+ /// If allowed by security policy, associates the method with the s declaring type.
+ /// Otherwise associates the dynamic method with .
+ ///
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static NetDynamicMethod CreateDynamicMethod(string methodName, Type returnType, Type[] argumentTypes, MemberInfo member, bool skipVisibility)
+ {
+ NetDynamicMethod dmGetter = null;
+ methodName = "_dynamic_" + member.DeclaringType.Name + "." + methodName;
+ try
+ {
+ new PermissionSet(PermissionState.Unrestricted).Demand();
+ dmGetter = CreateDynamicMethodInternal(methodName, returnType, argumentTypes, member, skipVisibility);
+ }
+ catch(SecurityException)
+ {
+ dmGetter = CreateDynamicMethodInternal(methodName, returnType, argumentTypes, MethodBase.GetCurrentMethod(), false);
+ }
+ return dmGetter;
+ }
+
+ private static NetDynamicMethod CreateDynamicMethodInternal(string methodName, Type returnType, Type[] argumentTypes, MemberInfo member, bool skipVisibility)
+ {
+ NetDynamicMethod dm;
+ dm = new NetDynamicMethod(methodName, returnType, argumentTypes, member.Module, skipVisibility);
+// if (member is FieldInfo)
+// {
+// // workaround for DynamicMethod bug not invoking type initializer before accessing static field
+// // it seems all works correct if the DM is created with limited accessibility
+// bool isStatic = (((FieldInfo) member).IsStatic);
+// if (isStatic)
+// {
+// new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).PermitOnly();
+// }
+// dm = new NetDynamicMethod(methodName, returnType, argumentTypes, member.DeclaringType, true);
+// if (isStatic)
+// {
+// CodeAccessPermission.RevertPermitOnly();
+// }
+// }
+// else
+// {
+// dm = new NetDynamicMethod(methodName, returnType, argumentTypes, member.DeclaringType, true);
+// }
+ return dm;
+ }
+
+ private static bool IsPublic(MemberInfo member)
+ {
+ if (member == null) return true;
+
+ switch(member.MemberType)
+ {
+ case MemberTypes.Event:
+ {
+ bool isPublic = ((EventInfo) member).GetAddMethod() != null;
+ return isPublic && IsPublic(member.DeclaringType);
+ }
+ case MemberTypes.Field:
+ {
+ bool isPublic = ((FieldInfo)member).IsPublic;
+ return isPublic && IsPublic(member.DeclaringType);
+ }
+ case MemberTypes.Property:
+ {
+ throw new NotSupportedException();
+ }
+ case MemberTypes.Constructor:
+ case MemberTypes.Method:
+ {
+ bool isPublic = ((MethodBase)member).IsPublic;
+ return isPublic && IsPublic(member.DeclaringType);
+ }
+ case MemberTypes.NestedType:
+ {
+ bool isPublic = ((Type)member).IsPublic;
+ return isPublic && IsPublic(member.DeclaringType);
+ }
+ case MemberTypes.TypeInfo:
+ {
+ bool isPublic = ((Type)member).IsPublic;
+ return isPublic;
+ }
+ default:
+ throw new NotSupportedException();
+ }
+ }
#endif
#region Shared Code Generation
- private static void EmitFieldGetter( ILGenerator il, FieldInfo fieldInfo, bool isInstanceMethod )
+ private static void EmitFieldGetter(ILGenerator il, FieldInfo fieldInfo, bool isInstanceMethod)
{
if (fieldInfo.IsLiteral)
{
- object value = fieldInfo.GetValue( null );
- EmitConstant( il, value );
+ object value = fieldInfo.GetValue(null);
+ EmitConstant(il, value);
}
else if (fieldInfo.IsStatic)
{
- il.Emit( OpCodes.Ldsfld, fieldInfo );
+// object v = fieldInfo.GetValue(null); // ensure type is initialized...
+ il.Emit(OpCodes.Ldsfld, fieldInfo);
}
else
{
- EmitTarget( il, fieldInfo.DeclaringType, isInstanceMethod );
- il.Emit( OpCodes.Ldfld, fieldInfo );
+ EmitTarget(il, fieldInfo.DeclaringType, isInstanceMethod);
+ il.Emit(OpCodes.Ldfld, fieldInfo);
}
if (fieldInfo.FieldType.IsValueType)
{
- il.Emit( OpCodes.Box, fieldInfo.FieldType );
+ il.Emit(OpCodes.Box, fieldInfo.FieldType);
}
- il.Emit( OpCodes.Ret );
+ il.Emit(OpCodes.Ret);
}
- internal static void EmitFieldSetter( ILGenerator il, FieldInfo fieldInfo, bool isInstanceMethod )
+ internal static void EmitFieldSetter(ILGenerator il, FieldInfo fieldInfo, bool isInstanceMethod)
{
if (!fieldInfo.IsLiteral
&& !fieldInfo.IsInitOnly
@@ -417,51 +524,51 @@ namespace Spring.Reflection.Dynamic
{
if (!fieldInfo.IsStatic)
{
- EmitTarget( il, fieldInfo.DeclaringType, isInstanceMethod );
+ EmitTarget(il, fieldInfo.DeclaringType, isInstanceMethod);
}
- il.Emit( OpCodes.Ldarg_1 );
+ il.Emit(OpCodes.Ldarg_1);
if (fieldInfo.FieldType.IsValueType)
{
- EmitUnbox( il, fieldInfo.FieldType );
+ EmitUnbox(il, fieldInfo.FieldType);
}
else
{
- il.Emit( OpCodes.Castclass, fieldInfo.FieldType );
+ il.Emit(OpCodes.Castclass, fieldInfo.FieldType);
}
if (fieldInfo.IsStatic)
{
- il.Emit( OpCodes.Stsfld, fieldInfo );
+ il.Emit(OpCodes.Stsfld, fieldInfo);
}
else
{
- il.Emit( OpCodes.Stfld, fieldInfo );
+ il.Emit(OpCodes.Stfld, fieldInfo);
}
- il.Emit( OpCodes.Ret );
+ il.Emit(OpCodes.Ret);
}
else
{
- EmitThrowInvalidOperationException( il, string.Format( "Cannot write to read-only field '{0}.{1}'", fieldInfo.DeclaringType.FullName, fieldInfo.Name ) );
+ EmitThrowInvalidOperationException(il, string.Format("Cannot write to read-only field '{0}.{1}'", fieldInfo.DeclaringType.FullName, fieldInfo.Name));
}
}
- internal static void EmitPropertyGetter( ILGenerator il, PropertyInfo propertyInfo, bool isInstanceMethod )
+ internal static void EmitPropertyGetter(ILGenerator il, PropertyInfo propertyInfo, bool isInstanceMethod)
{
if (propertyInfo.CanRead)
{
- MethodInfo getMethod = propertyInfo.GetGetMethod( true );
- EmitInvokeMethod( il, getMethod, isInstanceMethod );
+ MethodInfo getMethod = propertyInfo.GetGetMethod(true);
+ EmitInvokeMethod(il, getMethod, isInstanceMethod);
}
else
{
- EmitThrowInvalidOperationException( il, string.Format( "Cannot read from write-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name ) );
+ EmitThrowInvalidOperationException(il, string.Format("Cannot read from write-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name));
}
}
- internal static void EmitPropertySetter( ILGenerator il, PropertyInfo propertyInfo, bool isInstanceMethod )
+ internal static void EmitPropertySetter(ILGenerator il, PropertyInfo propertyInfo, bool isInstanceMethod)
{
- MethodInfo method = propertyInfo.GetSetMethod( true );
+ MethodInfo method = propertyInfo.GetSetMethod(true);
if (propertyInfo.CanWrite
&& !(propertyInfo.DeclaringType.IsValueType && !method.IsStatic))
@@ -475,184 +582,184 @@ namespace Spring.Reflection.Dynamic
ParameterInfo[] args = propertyInfo.GetIndexParameters(); // get indexParameters here!
for (int i = 0; i < args.Length; i++)
{
- SetupOutputArgument( il, paramsArrayPosition, args[i], outArgs );
+ SetupOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
// load target
if (!method.IsStatic)
{
- EmitTarget( il, method.DeclaringType, isInstanceMethod );
+ EmitTarget(il, method.DeclaringType, isInstanceMethod);
}
// load indexer arguments
for (int i = 0; i < args.Length; i++)
{
- SetupMethodArgument( il, paramsArrayPosition, args[i], outArgs );
+ SetupMethodArgument(il, paramsArrayPosition, args[i], outArgs);
}
// load value
- il.Emit( OpCodes.Ldarg_1 );
+ il.Emit(OpCodes.Ldarg_1);
if (propertyInfo.PropertyType.IsValueType)
{
- EmitUnbox( il, propertyInfo.PropertyType );
+ EmitUnbox(il, propertyInfo.PropertyType);
}
else
{
- il.Emit( OpCodes.Castclass, propertyInfo.PropertyType );
+ il.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
}
// call setter
- EmitCall( il, method );
+ EmitCall(il, method);
for (int i = 0; i < args.Length; i++)
{
- ProcessOutputArgument( il, paramsArrayPosition, args[i], outArgs );
+ ProcessOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
- il.Emit( OpCodes.Ret );
+ il.Emit(OpCodes.Ret);
}
else
{
- EmitThrowInvalidOperationException( il, string.Format( "Cannot write to read-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name ) );
+ EmitThrowInvalidOperationException(il, string.Format("Cannot write to read-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name));
}
}
///
/// Delegates a Method(object target, params object[] args) call to the actual underlying method.
///
- internal static void EmitInvokeMethod( ILGenerator il, MethodInfo method, bool isInstanceMethod )
+ internal static void EmitInvokeMethod(ILGenerator il, MethodInfo method, bool isInstanceMethod)
{
int paramsArrayPosition = (isInstanceMethod) ? 2 : 1;
ParameterInfo[] args = method.GetParameters();
IDictionary outArgs = new Hashtable();
for (int i = 0; i < args.Length; i++)
{
- SetupOutputArgument( il, paramsArrayPosition, args[i], outArgs );
+ SetupOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
if (!method.IsStatic)
{
- EmitTarget( il, method.DeclaringType, isInstanceMethod );
+ EmitTarget(il, method.DeclaringType, isInstanceMethod);
}
for (int i = 0; i < args.Length; i++)
{
- SetupMethodArgument( il, paramsArrayPosition, args[i], outArgs );
+ SetupMethodArgument(il, paramsArrayPosition, args[i], outArgs);
}
- EmitCall( il, method );
+ EmitCall(il, method);
for (int i = 0; i < args.Length; i++)
{
- ProcessOutputArgument( il, paramsArrayPosition, args[i], outArgs );
+ ProcessOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
- EmitMethodReturn( il, method.ReturnType );
+ EmitMethodReturn(il, method.ReturnType);
}
internal static void EmitInvokeConstructor(ILGenerator il, ConstructorInfo constructor, bool isInstanceMethod)
{
int paramsArrayPosition = (isInstanceMethod) ? 1 : 0;
- ParameterInfo[] args = constructor.GetParameters();
-
+ ParameterInfo[] args = constructor.GetParameters();
+
IDictionary outArgs = new Hashtable();
for (int i = 0; i < args.Length; i++)
{
- SetupOutputArgument( il, paramsArrayPosition, args[i], outArgs );
+ SetupOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
-
- for (int i = 0; i < args.Length; i++)
- {
- SetupMethodArgument(il, paramsArrayPosition, args[i], null);
- }
-
- il.Emit(OpCodes.Newobj, constructor);
-
+
for (int i = 0; i < args.Length; i++)
{
- ProcessOutputArgument( il, paramsArrayPosition, args[i], outArgs );
+ SetupMethodArgument(il, paramsArrayPosition, args[i], null);
}
-
- EmitMethodReturn(il, constructor.DeclaringType);
- }
-
+
+ il.Emit(OpCodes.Newobj, constructor);
+
+ for (int i = 0; i < args.Length; i++)
+ {
+ ProcessOutputArgument(il, paramsArrayPosition, args[i], outArgs);
+ }
+
+ EmitMethodReturn(il, constructor.DeclaringType);
+ }
+
#endregion
private static OpCode[] LdArgOpCodes = { OpCodes.Ldarg_0, OpCodes.Ldarg_1, OpCodes.Ldarg_2 };
- private static void SetupOutputArgument( ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs )
+ private static void SetupOutputArgument(ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs)
{
- if (!IsOutputOrRefArgument( argInfo ))
+ if (!IsOutputOrRefArgument(argInfo))
return;
Type argType = argInfo.ParameterType.GetElementType();
- LocalBuilder lb = il.DeclareLocal( argType );
+ LocalBuilder lb = il.DeclareLocal(argType);
if (!argInfo.IsOut)
{
- PushParamsArgumentValue( il, paramsArrayPosition, argType, argInfo.Position );
- il.Emit( OpCodes.Stloc, lb );
+ PushParamsArgumentValue(il, paramsArrayPosition, argType, argInfo.Position);
+ il.Emit(OpCodes.Stloc, lb);
}
outArgs[argInfo.Position] = lb;
}
- private static bool IsOutputOrRefArgument( ParameterInfo argInfo )
+ private static bool IsOutputOrRefArgument(ParameterInfo argInfo)
{
- return argInfo.IsOut || argInfo.ParameterType.Name.EndsWith( "&" );
+ return argInfo.IsOut || argInfo.ParameterType.Name.EndsWith("&");
}
- private static void ProcessOutputArgument( ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs )
+ private static void ProcessOutputArgument(ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs)
{
- if (!IsOutputOrRefArgument( argInfo ))
+ if (!IsOutputOrRefArgument(argInfo))
return;
Type argType = argInfo.ParameterType.GetElementType();
- il.Emit( LdArgOpCodes[paramsArrayPosition] );
- il.Emit( OpCodes.Ldc_I4, argInfo.Position );
- il.Emit( OpCodes.Ldloc, (LocalBuilder)outArgs[argInfo.Position] );
+ il.Emit(LdArgOpCodes[paramsArrayPosition]);
+ il.Emit(OpCodes.Ldc_I4, argInfo.Position);
+ il.Emit(OpCodes.Ldloc, (LocalBuilder)outArgs[argInfo.Position]);
if (argType.IsValueType)
{
- il.Emit( OpCodes.Box, argType );
+ il.Emit(OpCodes.Box, argType);
}
- il.Emit( OpCodes.Stelem_Ref );
+ il.Emit(OpCodes.Stelem_Ref);
}
- private static void SetupMethodArgument( ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs )
+ private static void SetupMethodArgument(ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs)
{
- if ( IsOutputOrRefArgument( argInfo ))
+ if (IsOutputOrRefArgument(argInfo))
{
- il.Emit( OpCodes.Ldloca_S, (LocalBuilder)outArgs[argInfo.Position] );
+ il.Emit(OpCodes.Ldloca_S, (LocalBuilder)outArgs[argInfo.Position]);
}
else
{
- PushParamsArgumentValue( il, paramsArrayPosition, argInfo.ParameterType, argInfo.Position );
+ PushParamsArgumentValue(il, paramsArrayPosition, argInfo.ParameterType, argInfo.Position);
}
}
- private static void PushParamsArgumentValue( ILGenerator il, int paramsArrayPosition, Type argumentType, int argumentPosition )
+ private static void PushParamsArgumentValue(ILGenerator il, int paramsArrayPosition, Type argumentType, int argumentPosition)
{
- il.Emit( LdArgOpCodes[paramsArrayPosition] );
- il.Emit( OpCodes.Ldc_I4, argumentPosition );
- il.Emit( OpCodes.Ldelem_Ref );
+ il.Emit(LdArgOpCodes[paramsArrayPosition]);
+ il.Emit(OpCodes.Ldc_I4, argumentPosition);
+ il.Emit(OpCodes.Ldelem_Ref);
if (argumentType.IsValueType)
{
// call ConvertArgumentIfNecessary() to convert e.g. int32 to double if necessary
- il.Emit( OpCodes.Ldtoken, argumentType );
- EmitCall( il, FnGetTypeFromHandle );
- il.Emit( OpCodes.Ldc_I4, argumentPosition );
- EmitCall( il, FnConvertArgumentIfNecessary );
- EmitUnbox( il, argumentType );
+ il.Emit(OpCodes.Ldtoken, argumentType);
+ EmitCall(il, FnGetTypeFromHandle);
+ il.Emit(OpCodes.Ldc_I4, argumentPosition);
+ EmitCall(il, FnConvertArgumentIfNecessary);
+ EmitUnbox(il, argumentType);
}
else
{
- il.Emit( OpCodes.Castclass, argumentType );
+ il.Emit(OpCodes.Castclass, argumentType);
}
}
- private static void EmitUnbox( ILGenerator il, Type argumentType )
+ private static void EmitUnbox(ILGenerator il, Type argumentType)
{
#if NET_2_0
- il.Emit( OpCodes.Unbox_Any, argumentType );
+ il.Emit(OpCodes.Unbox_Any, argumentType);
#else
il.Emit(OpCodes.Unbox, argumentType);
il.Emit(OpCodes.Ldobj, argumentType);
@@ -664,23 +771,23 @@ namespace Spring.Reflection.Dynamic
///
/// IL generator to use.
/// Type of the return value.
- private static void EmitMethodReturn( ILGenerator il, Type returnValueType )
+ private static void EmitMethodReturn(ILGenerator il, Type returnValueType)
{
- if (returnValueType == typeof( void ))
+ if (returnValueType == typeof(void))
{
- il.Emit( OpCodes.Ldnull );
+ il.Emit(OpCodes.Ldnull);
}
else if (returnValueType.IsValueType)
{
- il.Emit( OpCodes.Box, returnValueType );
+ il.Emit(OpCodes.Box, returnValueType);
}
- il.Emit( OpCodes.Ret );
+ il.Emit(OpCodes.Ret);
}
- private delegate Type GetTypeFromHandleDelegate( RuntimeTypeHandle handle );
- private static readonly MethodInfo FnGetTypeFromHandle = new GetTypeFromHandleDelegate( Type.GetTypeFromHandle ).Method;
- private delegate object ChangeTypeDelegate( object value, Type targetType, int argIndex );
- private static readonly MethodInfo FnConvertArgumentIfNecessary = new ChangeTypeDelegate( ConvertValueTypeArgumentIfNecessary ).Method;
+ private delegate Type GetTypeFromHandleDelegate(RuntimeTypeHandle handle);
+ private static readonly MethodInfo FnGetTypeFromHandle = new GetTypeFromHandleDelegate(Type.GetTypeFromHandle).Method;
+ private delegate object ChangeTypeDelegate(object value, Type targetType, int argIndex);
+ private static readonly MethodInfo FnConvertArgumentIfNecessary = new ChangeTypeDelegate(ConvertValueTypeArgumentIfNecessary).Method;
///
/// Converts to an instance of if necessary to
@@ -696,7 +803,7 @@ namespace Spring.Reflection.Dynamic
/// Note: is expected to be a value type!
///
///
- public static object ConvertValueTypeArgumentIfNecessary( object value, Type targetType, int argIndex )
+ public static object ConvertValueTypeArgumentIfNecessary(object value, Type targetType, int argIndex)
{
if (value == null)
{
@@ -704,12 +811,12 @@ namespace Spring.Reflection.Dynamic
{
return null;
}
- throw new InvalidCastException( string.Format( "Cannot convert NULL at position {0} to argument type {1}", argIndex, targetType.FullName ) );
+ throw new InvalidCastException(string.Format("Cannot convert NULL at position {0} to argument type {1}", argIndex, targetType.FullName));
}
Type valueType = value.GetType();
#if NET_2_0
- if (ReflectionUtils.IsNullableType( targetType ))
+ if (ReflectionUtils.IsNullableType(targetType))
{
targetType = Nullable.GetUnderlyingType(targetType);
}
@@ -723,47 +830,47 @@ namespace Spring.Reflection.Dynamic
if (!valueType.IsValueType)
{
// we're facing a reftype/valuetype mix that never can convert
- throw new InvalidCastException( string.Format( "Cannot convert value '{0}' of type {1} at position {2} to argument type {3}", value, valueType.FullName, argIndex, targetType.FullName ) );
+ throw new InvalidCastException(string.Format("Cannot convert value '{0}' of type {1} at position {2} to argument type {3}", value, valueType.FullName, argIndex, targetType.FullName));
}
// we're dealing only with ValueType's now - try to convert them
try
{
// TODO: allow widening conversions only
- return Convert.ChangeType( value, targetType );
+ return Convert.ChangeType(value, targetType);
}
catch (Exception ex)
{
- throw new InvalidCastException( string.Format( "Cannot convert value '{0}' of type {1} at position {2} to argument type {3}", value, valueType.FullName, argIndex, targetType.FullName ), ex );
+ throw new InvalidCastException(string.Format("Cannot convert value '{0}' of type {1} at position {2} to argument type {3}", value, valueType.FullName, argIndex, targetType.FullName), ex);
}
}
- private static void EmitTarget( ILGenerator il, Type targetType, bool isInstanceMethod )
+ private static void EmitTarget(ILGenerator il, Type targetType, bool isInstanceMethod)
{
- il.Emit( (isInstanceMethod) ? OpCodes.Ldarg_1 : OpCodes.Ldarg_0 );
+ il.Emit((isInstanceMethod) ? OpCodes.Ldarg_1 : OpCodes.Ldarg_0);
if (targetType.IsValueType)
{
- LocalBuilder local = il.DeclareLocal( targetType );
- EmitUnbox( il, targetType );
- il.Emit( OpCodes.Stloc_0 );
- il.Emit( OpCodes.Ldloca_S, 0 );
+ LocalBuilder local = il.DeclareLocal(targetType);
+ EmitUnbox(il, targetType);
+ il.Emit(OpCodes.Stloc_0);
+ il.Emit(OpCodes.Ldloca_S, 0);
}
else
{
- il.Emit( OpCodes.Castclass, targetType );
+ il.Emit(OpCodes.Castclass, targetType);
}
}
- private static void EmitCall( ILGenerator il, MethodInfo method )
+ private static void EmitCall(ILGenerator il, MethodInfo method)
{
- il.EmitCall( (method.IsVirtual) ? OpCodes.Callvirt : OpCodes.Call, method, null );
+ il.EmitCall((method.IsVirtual) ? OpCodes.Callvirt : OpCodes.Call, method, null);
}
- private static void EmitConstant( ILGenerator il, object value )
+ private static void EmitConstant(ILGenerator il, object value)
{
if (value is String)
{
- il.Emit( OpCodes.Ldstr, (string)value );
+ il.Emit(OpCodes.Ldstr, (string)value);
return;
}
@@ -771,78 +878,78 @@ namespace Spring.Reflection.Dynamic
{
if ((bool)value)
{
- il.Emit( OpCodes.Ldc_I4_1 );
+ il.Emit(OpCodes.Ldc_I4_1);
}
else
{
- il.Emit( OpCodes.Ldc_I4_0 );
+ il.Emit(OpCodes.Ldc_I4_0);
}
return;
}
if (value is Char)
{
- il.Emit( OpCodes.Ldc_I4, (Char)value );
- il.Emit( OpCodes.Conv_I2 );
+ il.Emit(OpCodes.Ldc_I4, (Char)value);
+ il.Emit(OpCodes.Conv_I2);
return;
}
if (value is byte)
{
- il.Emit( OpCodes.Ldc_I4, (byte)value );
- il.Emit( OpCodes.Conv_I1 );
+ il.Emit(OpCodes.Ldc_I4, (byte)value);
+ il.Emit(OpCodes.Conv_I1);
}
else if (value is Int16)
{
- il.Emit( OpCodes.Ldc_I4, (Int16)value );
- il.Emit( OpCodes.Conv_I2 );
+ il.Emit(OpCodes.Ldc_I4, (Int16)value);
+ il.Emit(OpCodes.Conv_I2);
}
else if (value is Int32)
{
- il.Emit( OpCodes.Ldc_I4, (Int32)value );
+ il.Emit(OpCodes.Ldc_I4, (Int32)value);
}
else if (value is Int64)
{
- il.Emit( OpCodes.Ldc_I8, (Int64)value );
+ il.Emit(OpCodes.Ldc_I8, (Int64)value);
}
else if (value is UInt16)
{
- il.Emit( OpCodes.Ldc_I4, (UInt16)value );
- il.Emit( OpCodes.Conv_U2 );
+ il.Emit(OpCodes.Ldc_I4, (UInt16)value);
+ il.Emit(OpCodes.Conv_U2);
}
else if (value is UInt32)
{
- il.Emit( OpCodes.Ldc_I4, (UInt32)value );
- il.Emit( OpCodes.Conv_U4 );
+ il.Emit(OpCodes.Ldc_I4, (UInt32)value);
+ il.Emit(OpCodes.Conv_U4);
}
else if (value is UInt64)
{
- il.Emit( OpCodes.Ldc_I8, (UInt64)value );
- il.Emit( OpCodes.Conv_U8 );
+ il.Emit(OpCodes.Ldc_I8, (UInt64)value);
+ il.Emit(OpCodes.Conv_U8);
}
else if (value is Single)
{
- il.Emit( OpCodes.Ldc_R4, (Single)value );
+ il.Emit(OpCodes.Ldc_R4, (Single)value);
}
else if (value is Double)
{
- il.Emit( OpCodes.Ldc_R8, (Double)value );
+ il.Emit(OpCodes.Ldc_R8, (Double)value);
}
}
private static readonly ConstructorInfo NewInvalidOperationException =
- typeof( InvalidOperationException ).GetConstructor( new Type[] { typeof( string ) } );
+ typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) });
///
/// Generates code that throws .
///
/// IL generator to use.
/// Error message to use.
- private static void EmitThrowInvalidOperationException( ILGenerator il, string message )
+ private static void EmitThrowInvalidOperationException(ILGenerator il, string message)
{
- il.Emit( OpCodes.Ldstr, message );
- il.Emit( OpCodes.Newobj, NewInvalidOperationException );
- il.Emit( OpCodes.Throw );
+ il.Emit(OpCodes.Ldstr, message);
+ il.Emit(OpCodes.Newobj, NewInvalidOperationException);
+ il.Emit(OpCodes.Throw);
}
}
}
\ No newline at end of file
diff --git a/src/Spring/Spring.Core/Spring.Core.2008.csproj b/src/Spring/Spring.Core/Spring.Core.2008.csproj
index 97de62a9..9bd72de8 100644
--- a/src/Spring/Spring.Core/Spring.Core.2008.csproj
+++ b/src/Spring/Spring.Core/Spring.Core.2008.csproj
@@ -11,8 +11,6 @@
Spring.Core
-
-
JScript
Grid
IE50
@@ -38,6 +36,8 @@
true
false
true
+ true
+ ..\..\..\Spring.Net.snk
..\..\..\build\VS.Net.2008\Spring.Core\Debug\
@@ -1013,6 +1013,7 @@
+
diff --git a/src/Spring/Spring.Core/Util/ObjectUtils.cs b/src/Spring/Spring.Core/Util/ObjectUtils.cs
index ea048574..57168af7 100644
--- a/src/Spring/Spring.Core/Util/ObjectUtils.cs
+++ b/src/Spring/Spring.Core/Util/ObjectUtils.cs
@@ -247,8 +247,7 @@ namespace Spring.Util
#endif
try
{
- // replaced with SafeConstructor() to avoid nasty "TargetInvocationException"s
- //return constructor.Invoke(arguments);
+ // replaced with SafeConstructor() to avoid nasty "TargetInvocationException"s in NET >= 2.0
return (new SafeConstructor(constructor)).Invoke(arguments);
}
catch (Exception ex)
diff --git a/src/Spring/Spring.Core/Util/ReflectionUtils.cs b/src/Spring/Spring.Core/Util/ReflectionUtils.cs
index b1c97647..46c791ca 100644
--- a/src/Spring/Spring.Core/Util/ReflectionUtils.cs
+++ b/src/Spring/Spring.Core/Util/ReflectionUtils.cs
@@ -1,5 +1,5 @@
-#region License
-
+#region License
+
/*
* Copyright © 2002-2005 the original author or authors.
*
@@ -14,132 +14,139 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-
-#endregion
-
-#region Imports
-
-using System;
-using System.Collections;
-#if NET_2_0
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-#endif
-using System.Globalization;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Text;
-using System.Runtime.CompilerServices;
-
-#endregion
-
-namespace Spring.Util
-{
- ///
- /// Various reflection related methods that are missing from the standard library.
- ///
- /// Rod Johnson
- /// Juergen Hoeller
- /// Aleksandar Seovic (.NET)
- /// Stan Dvoychenko (.NET)
- /// Bruno Baia (.NET)
- public sealed class ReflectionUtils
- {
- ///
- /// Convenience value that will
- /// match all private and public, static and instance members on a class
- /// in a case inSenSItivE fashion.
- ///
- public const BindingFlags AllMembersCaseInsensitiveFlags = BindingFlags.Public |
- BindingFlags.NonPublic | BindingFlags.Instance
- | BindingFlags.Static
+ */
+
+#endregion
+
+#region Imports
+
+using System;
+using System.Collections;
+#if NET_2_0
+using System.Collections.ObjectModel;
+#endif
+using System.Globalization;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Security;
+using System.Security.Permissions;
+using System.Text;
+using System.Runtime.CompilerServices;
+
+#endregion
+
+namespace Spring.Util
+{
+ ///
+ /// Various reflection related methods that are missing from the standard library.
+ ///
+ /// Rod Johnson
+ /// Juergen Hoeller
+ /// Aleksandar Seovic (.NET)
+ /// Stan Dvoychenko (.NET)
+ /// Bruno Baia (.NET)
+ public sealed class ReflectionUtils
+ {
+ ///
+ /// Convenience value that will
+ /// match all private and public, static and instance members on a class
+ /// in a case inSenSItivE fashion.
+ ///
+ public const BindingFlags AllMembersCaseInsensitiveFlags = BindingFlags.Public |
+ BindingFlags.NonPublic | BindingFlags.Instance
+ | BindingFlags.Static
| BindingFlags.IgnoreCase;
+ ///
+ /// Avoid BeforeFieldInit problem
+ ///
+ static ReflectionUtils()
+ {}
+
///
/// Checks, if the specified type is a nullable
///
- public static bool IsNullableType( Type type )
+ public static bool IsNullableType(Type type)
{
#if NET_2_0
- return (type.IsGenericType && type.GetGenericTypeDefinition()==typeof(Nullable<>));
+ return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>));
#else
return false;
#endif
- }
-
- ///
- /// Returns signature for the specified , method name and argument
- /// s.
- ///
- /// The the method is in.
- /// The method name.
- ///
- /// The argument s.
- ///
- /// The method signature.
- public static string GetSignature(
- Type type, string method, Type[] argumentTypes)
- {
- StringBuilder sb = new StringBuilder();
- sb.Append(type.FullName).Append("::").Append(method).Append("(");
- string separator = "";
- for (int i = 0; i < argumentTypes.Length; i++)
- {
- sb.Append(separator).Append(argumentTypes[i].FullName);
- separator = ",";
- }
- sb.Append(")");
- return sb.ToString();
- }
-
-
- ///
- /// Returns method for the specified , method
- /// name and argument
- /// s.
- ///
+ }
+
+ ///
+ /// Returns signature for the specified , method name and argument
+ /// s.
+ ///
+ /// The the method is in.
+ /// The method name.
+ ///
+ /// The argument s.
+ ///
+ /// The method signature.
+ public static string GetSignature(
+ Type type, string method, Type[] argumentTypes)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(type.FullName).Append("::").Append(method).Append("(");
+ string separator = "";
+ for (int i = 0; i < argumentTypes.Length; i++)
+ {
+ sb.Append(separator).Append(argumentTypes[i].FullName);
+ separator = ",";
+ }
+ sb.Append(")");
+ return sb.ToString();
+ }
+
+
+ ///
+ /// Returns method for the specified , method
+ /// name and argument
+ /// s.
+ ///
///
/// Searches with BindingFlags
/// When dealing with interface methods, you probable want to 'normalize' method references by calling
/// .
///
- ///
- ///
- /// The target to find the method on.
- ///
- /// The method to find.
- ///
- /// The argument s. May be
- /// if the method has no arguments.
- ///
+ ///
+ ///
+ /// The target to find the method on.
+ ///
+ /// The method to find.
+ ///
+ /// The argument s. May be
+ /// if the method has no arguments.
+ ///
/// The target method.
- ///
- public static MethodInfo GetMethod(
- Type targetType, string method, Type[] argumentTypes)
- {
- AssertUtils.ArgumentNotNull(targetType, "Type must not be null");
- // try method exactly as specified first...
- MethodInfo retMethod = targetType.GetMethod(
- method,
- ReflectionUtils.AllMembersCaseInsensitiveFlags,
- null,
- argumentTypes == null ? Type.EmptyTypes : argumentTypes,
- null);
-
- if (retMethod == null)
- {
- // try explicit interface implementation...
- int idx = method.LastIndexOf('.');
- if (idx > -1)
- {
- method = method.Substring(idx + 1);
- retMethod = ReflectionUtils.GetMethod(targetType, method, argumentTypes);
- }
- }
- return retMethod;
- }
-
+ ///
+ public static MethodInfo GetMethod(
+ Type targetType, string method, Type[] argumentTypes)
+ {
+ AssertUtils.ArgumentNotNull(targetType, "Type must not be null");
+ // try method exactly as specified first...
+ MethodInfo retMethod = targetType.GetMethod(
+ method,
+ ReflectionUtils.AllMembersCaseInsensitiveFlags,
+ null,
+ argumentTypes == null ? Type.EmptyTypes : argumentTypes,
+ null);
+
+ if (retMethod == null)
+ {
+ // try explicit interface implementation...
+ int idx = method.LastIndexOf('.');
+ if (idx > -1)
+ {
+ method = method.Substring(idx + 1);
+ retMethod = ReflectionUtils.GetMethod(targetType, method, argumentTypes);
+ }
+ }
+ return retMethod;
+ }
+
///
/// Resolves a given to the representing the actual implementation.
///
@@ -148,8 +155,8 @@ namespace Spring.Util
///
/// a
/// the type to lookup
- /// the representing the actual implementation method of the specified
- public static MethodInfo MapInterfaceMethodToImplementationIfNecessary( MethodInfo methodInfo, System.Type implementingType )
+ /// the representing the actual implementation method of the specified
+ public static MethodInfo MapInterfaceMethodToImplementationIfNecessary(MethodInfo methodInfo, System.Type implementingType)
{
AssertUtils.ArgumentNotNull(methodInfo, "methodInfo");
AssertUtils.ArgumentNotNull(implementingType, "implementingType");
@@ -159,817 +166,817 @@ namespace Spring.Util
if (methodInfo.DeclaringType.IsInterface)
{
- InterfaceMapping interfaceMapping = implementingType.GetInterfaceMap( methodInfo.DeclaringType );
- int methodIndex = Array.IndexOf( interfaceMapping.InterfaceMethods, methodInfo );
+ InterfaceMapping interfaceMapping = implementingType.GetInterfaceMap(methodInfo.DeclaringType);
+ int methodIndex = Array.IndexOf(interfaceMapping.InterfaceMethods, methodInfo);
concreteMethodInfo = interfaceMapping.TargetMethods[methodIndex];
}
return concreteMethodInfo;
}
-
- ///
- /// Returns an array of parameter s for the specified method
- /// or constructor.
- ///
- /// The method (or constructor).
- /// An array containing the parameter s.
- ///
- /// If is .
- ///
- public static Type[] GetParameterTypes(MethodBase method)
- {
- AssertUtils.ArgumentNotNull(method, "method");
- return GetParameterTypes(method.GetParameters());
- }
-
- ///
- /// Returns an array of parameter s for the
- /// specified parameter info array.
- ///
- /// The parameter info array.
- /// An array containing parameter s.
- ///
- /// If is or any of the
- /// elements is .
- ///
- public static Type[] GetParameterTypes(ParameterInfo[] args)
- {
- AssertUtils.ArgumentNotNull(args, "args");
- Type[] types = new Type[args.Length];
- for (int i = 0; i < args.Length; i++)
- {
- types[i] = args[i].ParameterType;
- }
- return types;
- }
-
-#if NET_2_0
- ///
- /// Returns an array of s that represent
- /// the names of the generic type parameter.
- ///
- /// The method.
- /// An array containing the parameter names.
- ///
- /// If is .
- ///
- public static string[] GetGenericParameterNames(MethodInfo method)
- {
- AssertUtils.ArgumentNotNull(method, "method");
- return GetGenericParameterNames(method.GetGenericArguments());
- }
-
- ///
- /// Returns an array of s that represent
- /// the names of the generic type parameter.
- ///
- /// The parameter info array.
- /// An array containing parameter names.
- ///
- /// If is or any of the
- /// elements is .
- ///
- public static string[] GetGenericParameterNames(Type[] args)
- {
- AssertUtils.ArgumentNotNull(args, "args");
- string[] names = new string[args.Length];
- for (int i = 0; i < args.Length; i++)
- {
- names[i] = args[i].Name;
- }
- return names;
- }
-#endif
-
- ///
- /// From a given list of methods, selects the method having an exact match on the given ' types.
- ///
- /// the list of methods to choose from
- /// the arguments to the method
- /// the method matching exactly the passed ' types
- ///
- /// If more than 1 matching methods are found in the list.
- ///
- public static MethodInfo GetMethodByArgumentValues(MethodInfo[] methods, object[] argValues)
- {
- return (MethodInfo)GetMethodBaseByArgumentValues("method", methods, argValues);
- }
-
- ///
- /// From a given list of methods, selects the method having an exact match on the given ' types.
- ///
- /// the type of method (used for exception reporting only)
- /// the list of methods to choose from
- /// the arguments to the method
- /// the method matching exactly the passed ' types
- ///
- /// If more than 1 matching methods are found in the list.
- ///
- private static MethodBase GetMethodBaseByArgumentValues(string methodTypeName, MethodBase[] methods,
- object[] argValues)
- {
- MethodBase match = null;
- int matchCount = 0;
-
- foreach (MethodBase m in methods)
- {
- ParameterInfo[] parameters = m.GetParameters();
- bool isMatch = true;
- bool isExactMatch = true;
- object[] paramValues = (argValues==null)?new object[0] : argValues;
-
- try
- {
- if (parameters.Length > 0)
- {
- ParameterInfo lastParameter = parameters[parameters.Length - 1];
- if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0)
- {
- paramValues =
- PackageParamArray(argValues, parameters.Length,
- lastParameter.ParameterType.GetElementType());
- }
- }
-
- if (parameters.Length != paramValues.Length)
+
+ ///
+ /// Returns an array of parameter s for the specified method
+ /// or constructor.
+ ///
+ /// The method (or constructor).
+ /// An array containing the parameter s.
+ ///
+ /// If is .
+ ///
+ public static Type[] GetParameterTypes(MethodBase method)
+ {
+ AssertUtils.ArgumentNotNull(method, "method");
+ return GetParameterTypes(method.GetParameters());
+ }
+
+ ///
+ /// Returns an array of parameter s for the
+ /// specified parameter info array.
+ ///
+ /// The parameter info array.
+ /// An array containing parameter s.
+ ///
+ /// If is or any of the
+ /// elements is .
+ ///
+ public static Type[] GetParameterTypes(ParameterInfo[] args)
+ {
+ AssertUtils.ArgumentNotNull(args, "args");
+ Type[] types = new Type[args.Length];
+ for (int i = 0; i < args.Length; i++)
+ {
+ types[i] = args[i].ParameterType;
+ }
+ return types;
+ }
+
+#if NET_2_0
+ ///
+ /// Returns an array of s that represent
+ /// the names of the generic type parameter.
+ ///
+ /// The method.
+ /// An array containing the parameter names.
+ ///
+ /// If is .
+ ///
+ public static string[] GetGenericParameterNames(MethodInfo method)
+ {
+ AssertUtils.ArgumentNotNull(method, "method");
+ return GetGenericParameterNames(method.GetGenericArguments());
+ }
+
+ ///
+ /// Returns an array of s that represent
+ /// the names of the generic type parameter.
+ ///
+ /// The parameter info array.
+ /// An array containing parameter names.
+ ///
+ /// If is or any of the
+ /// elements is .
+ ///
+ public static string[] GetGenericParameterNames(Type[] args)
+ {
+ AssertUtils.ArgumentNotNull(args, "args");
+ string[] names = new string[args.Length];
+ for (int i = 0; i < args.Length; i++)
+ {
+ names[i] = args[i].Name;
+ }
+ return names;
+ }
+#endif
+
+ ///
+ /// From a given list of methods, selects the method having an exact match on the given ' types.
+ ///
+ /// the list of methods to choose from
+ /// the arguments to the method
+ /// the method matching exactly the passed ' types
+ ///
+ /// If more than 1 matching methods are found in the list.
+ ///
+ public static MethodInfo GetMethodByArgumentValues(MethodInfo[] methods, object[] argValues)
+ {
+ return (MethodInfo)GetMethodBaseByArgumentValues("method", methods, argValues);
+ }
+
+ ///
+ /// From a given list of methods, selects the method having an exact match on the given ' types.
+ ///
+ /// the type of method (used for exception reporting only)
+ /// the list of methods to choose from
+ /// the arguments to the method
+ /// the method matching exactly the passed ' types
+ ///
+ /// If more than 1 matching methods are found in the list.
+ ///
+ private static MethodBase GetMethodBaseByArgumentValues(string methodTypeName, MethodBase[] methods,
+ object[] argValues)
+ {
+ MethodBase match = null;
+ int matchCount = 0;
+
+ foreach (MethodBase m in methods)
+ {
+ ParameterInfo[] parameters = m.GetParameters();
+ bool isMatch = true;
+ bool isExactMatch = true;
+ object[] paramValues = (argValues == null) ? new object[0] : argValues;
+
+ try
+ {
+ if (parameters.Length > 0)
+ {
+ ParameterInfo lastParameter = parameters[parameters.Length - 1];
+ if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0)
+ {
+ paramValues =
+ PackageParamArray(argValues, parameters.Length,
+ lastParameter.ParameterType.GetElementType());
+ }
+ }
+
+ if (parameters.Length != paramValues.Length)
{
isMatch = false;
- }
- else
- {
- for (int i = 0; i < parameters.Length; i++)
- {
- Type paramType = parameters[i].ParameterType;
- object paramValue = paramValues[i];
- if ((paramValue == null && paramType.IsValueType)
- || (paramValue != null && !paramType.IsAssignableFrom(paramValue.GetType())))
- {
- isMatch = false;
- break;
- }
- if (paramValue == null || paramType != paramValue.GetType())
- {
- isExactMatch = false;
- }
- }
- }
- }
- catch (InvalidCastException)
- {
- isMatch = false;
- }
-
- if (isMatch)
- {
- if (isExactMatch)
- {
- return m;
- }
-
- matchCount++;
- if (matchCount == 1)
- {
- match = m;
- }
- else
- {
- throw new AmbiguousMatchException(
- string.Format("Ambiguous match for {0} '{1}' for the specified number and types of arguments.", methodTypeName,
- m.Name));
- }
- }
- }
-
- return match;
- }
-
- ///
- /// From a given list of constructors, selects the constructor having an exact match on the given ' types.
- ///
- /// the list of constructors to choose from
- /// the arguments to the method
- /// the constructor matching exactly the passed ' types
- ///
- /// If more than 1 matching methods are found in the list.
- ///
- public static ConstructorInfo GetConstructorByArgumentValues(ConstructorInfo[] methods, object[] argValues)
- {
- return (ConstructorInfo)GetMethodBaseByArgumentValues("constructor", methods, argValues);
- }
-
-
- ///
- /// Packages arguments into argument list containing parameter array as a last argument.
- ///
- /// Argument vaklues to package.
- /// Total number of oarameters.
- /// Type of the param array element.
- /// Packaged arguments.
- public static object[] PackageParamArray(object[] argValues, int argCount, Type elementType)
- {
- object[] values = new object[argCount];
- int i = 0;
-
- // copy regular arguments
- while (i < argCount - 1)
- {
- values[i] = argValues[i];
- i++;
- }
-
- // package param array into last argument
- Array paramArray = Array.CreateInstance(elementType, argValues.Length - i);
- int j = 0;
- while (i < argValues.Length)
- {
- paramArray.SetValue(argValues[i++], j++);
- }
- values[values.Length - 1] = paramArray;
-
- return values;
- }
-
- ///
- /// Convenience method to convert an interface
- /// to a array that contains
- /// all the interfaces inherited and the specified interface.
- ///
- /// The interface to convert.
- /// An array of interface s.
- ///
- /// If the specified is not an interface.
- ///
- ///
- /// If is .
- ///
- public static Type[] ToInterfaceArray(Type intf)
- {
- AssertUtils.ArgumentNotNull(intf, "intf");
-
- if (!intf.IsInterface)
- {
- throw new ArgumentException(
- string.Format(CultureInfo.InvariantCulture,
- "[{0}] is a class.",
- intf.FullName));
- }
-
- ArrayList interfaces = new ArrayList(intf.GetInterfaces());
- interfaces.Add(intf);
-
- return (Type[])interfaces.ToArray(typeof(Type));
- }
-
- ///
- /// Is the supplied the default indexer for the
- /// supplied ?
- ///
- ///
- /// The name of the property on the supplied to be checked.
- ///
- ///
- /// The to be checked.
- ///
- ///
- /// if the supplied is the
- /// default indexer for the supplied .
- ///
- ///
- /// If the supplied is .
- ///
- public static bool PropertyIsIndexer(string propertyName, Type type)
- {
- DefaultMemberAttribute[] attribs =
- (DefaultMemberAttribute[])type.GetCustomAttributes(typeof(DefaultMemberAttribute), true);
- if (attribs.Length != 0)
- {
- foreach (DefaultMemberAttribute attrib in attribs)
- {
- if (attrib.MemberName.Equals(propertyName))
- {
- return true;
- }
- }
- }
- return false;
- }
-
- ///
- /// Is the supplied declared on one of these interfaces?
- ///
- /// The method to check.
- /// The array of interfaces we want to check.
- ///
- /// if the method is declared on one of these interfaces.
- ///
- ///
- /// If any of the s specified is not an interface.
- ///
- ///
- /// If or any of the specified interfaces is
- /// .
- ///
- public static bool MethodIsOnOneOfTheseInterfaces(MethodBase method, Type[] interfaces)
- {
- AssertUtils.ArgumentNotNull(method, "method");
- if (interfaces == null)
- {
- return false;
- }
- Type[] paramTypes = GetParameterTypes(method.GetParameters());
- for (int i = 0; i < interfaces.Length; i++)
- {
- Type interfaceType = interfaces[i];
- AssertUtils.ArgumentNotNull(interfaceType, StringUtils.Surround("interfaces[", i, "]"));
- if (!interfaceType.IsInterface)
- {
- throw new ArgumentException(interfaces[i].FullName + " is not an interface");
- }
- try
- {
- MethodInfo mi = interfaceType.GetMethod(
- method.Name,
- BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly,
- null, paramTypes, null);
- if (mi != null)
- {
- // found it...
- return true;
- }
- }
- catch
- {
- // didn't find it, so keep going...
- }
- }
- return false;
- }
-
- ///
- /// Returns the default value for the specified
- ///
- ///
- ///
- /// Follows the standard .NET conventions for default values where
- /// relevant; for example, all numeric types default to the value
- /// 0.
- ///
- ///
- ///
- /// The to return default value for.
- ///
- ///
- /// The default value for the specified .
- ///
- ///
- /// If the supplied is an enumerated type that
- /// has no values.
- ///
- public static object GetDefaultValue(Type type)
- {
- if (!type.IsValueType)
- {
- return null;
- }
- if (type == typeof(Boolean))
- {
- return false;
- }
- if (type == typeof(DateTime))
- {
- return DateTime.MinValue;
- }
- if (type == typeof(Char))
- {
- return Char.MinValue;
- }
- if (type.IsEnum)
- {
- Array values = Enum.GetValues(type);
- if (values == null || values.Length == 0)
- {
- throw new ArgumentException("Bad 'enum' Type : cannot get default value because 'enum' has no values.");
- }
- return values.GetValue(0);
- }
- return 0;
- }
-
- ///
- /// Returns an array consisting of the default values for the supplied
- /// .
- ///
- ///
- /// The array of s to return default values for.
- ///
- ///
- /// An array consisting of the default values for the supplied
- /// .
- ///
- ///
- /// If any of the elements in the supplied
- /// array is an enumerated type that has no values.
- ///
- ///
- public static object[] GetDefaultValues(Type[] types)
- {
- object[] defaults = new object[types.Length];
- for (int i = 0; i < types.Length; ++i)
- {
- defaults[i] = GetDefaultValue(types[i]);
- }
- return defaults;
- }
-
- ///
- /// Checks that the parameter s of the
- /// supplied match the parameter
- /// s of the supplied
- /// .
- ///
- /// The method to be checked.
- ///
- /// The array of parameter s to check against.
- ///
- ///
- /// if the parameter s
- /// match.
- ///
- public static bool ParameterTypesMatch(
- MethodInfo candidate, Type[] parameterTypes)
- {
- #region Sanity Checks
-
- AssertUtils.ArgumentNotNull(candidate, "candidate");
- AssertUtils.ArgumentNotNull(parameterTypes, "parameterTypes");
-
- #endregion
-
- Type[] candidatesParameterTypes
- = ReflectionUtils.GetParameterTypes(candidate);
- if (candidatesParameterTypes.Length != parameterTypes.Length)
- {
- return false;
- }
- for (int i = 0; i < candidatesParameterTypes.Length; ++i)
- {
- if (!candidatesParameterTypes[i].Equals(parameterTypes[i]))
- {
- return false;
- }
- }
- return true;
- }
-
- ///
- /// Returns an array containing the s of the
- /// objects in the supplied array.
- ///
- ///
- /// The objects array for which the corresponding s
- /// are needed.
- ///
- ///
- /// An array containing the s of the objects
- /// in the supplied array; this array will be empty (but not
- /// if the supplied
- /// is null or has no elements.
- ///
- ///
- ///
- /// [C#]
- /// Given an array containing the following objects,
- /// [83, "Foo", new object ()], the
- /// array returned from this method call would consist of the following
- /// elements...
- /// [Int32, String, Object].
- ///
- ///
- public static Type[] GetTypes(object[] args)
- {
- if (args == null || args.Length == 0)
- {
- return Type.EmptyTypes;
- }
- Type[] paramsType = new Type[args.Length];
- for (int i = 0; i < args.Length; ++i)
- {
- object arg = args[i];
- paramsType[i] = (arg != null) ? args[i].GetType() : typeof(object);
- }
- return paramsType;
- }
-
- ///
- /// Does the given and/or it's superclasses
- /// have at least one or more methods with the given name (with any
- /// argument types)?
- ///
- ///
- ///
- /// Includes non-public methods in the methods searched.
- ///
- ///
- ///
- /// The to be checked.
- ///
- ///
- /// The name of the method to be searched for. Case inSenSItivE.
- ///
- ///
- /// if the given or / and it's
- /// superclasses have at least one or more methods (with any argument types);
- /// if not, or either of the parameters is .
- ///
- public static bool HasAtLeastOneMethodWithName(Type type, string name)
- {
- if (type == null || StringUtils.IsNullOrEmpty(name))
- {
- return false;
- }
- return MethodCountForName(type, name) > 0;
- }
-
- ///
- /// Within , counts the number of overloads for the method with the given (case-insensitive!)
- ///
- /// The type to be searched
- /// the name of the method for which overloads shall be counted
- /// The number of overloads for method within type
- public static int MethodCountForName(Type type, string name)
- {
- AssertUtils.ArgumentNotNull(type, "type", "Type must not be null");
- AssertUtils.ArgumentNotNull(name, "name", "Method name must not be null");
- MemberInfo[] methods = type.FindMembers(
- MemberTypes.Method,
- ReflectionUtils.AllMembersCaseInsensitiveFlags,
- new MemberFilter(ReflectionUtils.MethodNameFilter),
- name);
- return methods.Length;
- }
-
- private static bool MethodNameFilter(MemberInfo member, object criteria)
- {
- MethodInfo method = member as MethodInfo;
- string name = criteria as string;
- return String.Compare(method.Name, name, true, CultureInfo.InvariantCulture) == 0;
- }
-
- ///
- /// Creates a .
- ///
- ///
- ///
- /// Note that if a non-
- /// is supplied, any read write properties exposed by the
- /// will be used to overwrite values that may have been passed in via the
- /// . That is, the will be used
- /// to initialize the custom attribute, and then any read-write properties on the
- /// will be plugged in.
- ///
- ///
- ///
- /// The desired .
- ///
- ///
- /// Any constructor arguments for the attribute (may be
- /// in the case of no arguments).
- ///
- ///
- /// Source attribute to copy properties from (may be ).
- ///
- /// A custom attribute builder.
- ///
- /// If the parameter is .
- ///
- ///
- /// If the parameter is not a
- /// that derives from the class.
- ///
- ///
- public static CustomAttributeBuilder CreateCustomAttribute(
- Type type, object[] ctorArgs, Attribute sourceAttribute)
- {
- #region Sanity Checks
-
- AssertUtils.ArgumentNotNull(type, "type");
- if (!typeof(Attribute).IsAssignableFrom(type))
- {
- throw new ArgumentException(
- string.Format("[{0}] does not derive from the [System.Attribute] class.",
- type.FullName));
- }
-
- #endregion
-
- ConstructorInfo ci = type.GetConstructor(ReflectionUtils.GetTypes(ctorArgs));
- if (ci == null && ctorArgs.Length == 0)
- {
- ci = type.GetConstructors()[0];
- ctorArgs = GetDefaultValues(GetParameterTypes(ci.GetParameters()));
- }
-
- if (sourceAttribute != null)
- {
- object defaultAttribute = null;
- try
- {
- defaultAttribute = ci.Invoke(ctorArgs);
- }
- catch
- {
- }
-
- IList getSetProps = new ArrayList();
- IList getSetValues = new ArrayList();
- IList readOnlyProps = new ArrayList();
- IList readOnlyValues = new ArrayList();
- foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
- {
- if (pi.DeclaringType == typeof(Attribute))
- continue;
-
- if (pi.CanRead)
- {
- if (pi.CanWrite)
- {
- object propValue = pi.GetValue(sourceAttribute, null);
- if (defaultAttribute != null)
- {
- object defaultValue = pi.GetValue(defaultAttribute, null);
- if ((propValue == null && defaultValue == null) ||
- (propValue != null && propValue.Equals(defaultValue)))
- continue;
- }
- getSetProps.Add(pi);
- getSetValues.Add(propValue);
- }
- else
- {
- readOnlyProps.Add(pi);
- readOnlyValues.Add(pi.GetValue(sourceAttribute, null));
- }
- }
- }
-
- if (readOnlyProps.Count == 1)
- {
- PropertyInfo pi = readOnlyProps[0] as PropertyInfo;
- ConstructorInfo ciTemp = type.GetConstructor(new Type[1] { pi.PropertyType });
- if (ciTemp != null)
- {
- ci = ciTemp;
- ctorArgs = new object[1] { readOnlyValues[0] };
- }
- else
- {
- ciTemp = type.GetConstructor(new Type[1] { readOnlyValues[0].GetType() });
- if (ciTemp != null)
- {
- ci = ciTemp;
- ctorArgs = new object[1] { readOnlyValues[0] };
- }
- }
- }
-
- PropertyInfo[] propertyInfos = new PropertyInfo[getSetProps.Count];
- getSetProps.CopyTo(propertyInfos, 0);
-
- object[] propertyValues = new object[getSetValues.Count];
- getSetValues.CopyTo(propertyValues, 0);
-
- return new CustomAttributeBuilder(ci, ctorArgs, propertyInfos, propertyValues);
- }
- else
- {
- return new CustomAttributeBuilder(ci, ctorArgs);
- }
- }
-
- ///
- /// Creates a .
- ///
- ///
- /// The desired .
- ///
- ///
- /// Source attribute to copy properties from (may be ).
- ///
- /// A custom attribute builder.
- public static CustomAttributeBuilder CreateCustomAttribute(
- Type type, Attribute sourceAttribute)
- {
- return CreateCustomAttribute(type, new object[] { }, sourceAttribute);
- }
-
- ///
- /// Creates a .
- ///
- ///
- /// The source attribute to copy properties from.
- ///
- /// A custom attribute builder.
- ///
- /// If the supplied is
- /// .
- ///
- public static CustomAttributeBuilder CreateCustomAttribute(Attribute sourceAttribute)
- {
- return CreateCustomAttribute(sourceAttribute.GetType(), sourceAttribute);
- }
-
- ///
- /// Creates a .
- ///
- ///
- /// The desired .
- ///
- /// A custom attribute builder.
- public static CustomAttributeBuilder CreateCustomAttribute(Type type)
- {
- return CreateCustomAttribute(type, new object[] { }, null);
- }
-
- ///
- /// Creates a .
- ///
- ///
- /// The desired .
- ///
- ///
- /// Any constructor arguments for the attribute (may be
- /// in the case of no arguments).
- ///
- /// A custom attribute builder.
- public static CustomAttributeBuilder CreateCustomAttribute(
- Type type, params object[] ctorArgs)
- {
- return CreateCustomAttribute(type, ctorArgs, null);
- }
-
-#if NET_2_0
- ///
- /// Creates a .
- ///
- ///
- /// The to create
- /// the custom attribute builder from.
- ///
- /// A custom attribute builder.
- public static CustomAttributeBuilder CreateCustomAttribute(CustomAttributeData attributeData)
- {
- object[] parameterValues = new object[attributeData.ConstructorArguments.Count];
- Type[] parameterTypes = new Type[attributeData.ConstructorArguments.Count];
-
- IList namedParameterValues = new ArrayList();
- IList namedFieldValues = new ArrayList();
-
- // Fill arrays of the constructor parameters
- for (int i = 0; i < attributeData.ConstructorArguments.Count; i++)
- {
- parameterTypes[i] = attributeData.ConstructorArguments[i].ArgumentType;
- parameterValues[i] = ConvertValueIfNecessary(attributeData.ConstructorArguments[i].Value);
- }
-
- Type attributeType = attributeData.Constructor.DeclaringType;
- PropertyInfo[] attributeProperties = attributeType.GetProperties(
- BindingFlags.Instance | BindingFlags.Public);
- FieldInfo[] attributeFields = attributeType.GetFields(
- BindingFlags.Instance | BindingFlags.Public);
-
- // Not using generics bellow as probably Spring.NET tries to keep
- // it on .NET1 compatibility level right now I believe (SD)
- // In case of using List the above note makes
- // no sense (SD:)
- IList propertiesToSet = new ArrayList();
- int k = 0;
-
- IList fieldsToSet = new ArrayList();
- int n = 0;
-
-
- // Fills arrays of the constructor named parameters
- foreach (CustomAttributeNamedArgument namedArgument in attributeData.NamedArguments)
- {
- bool noMatchingProperty = false;
-
- // Now iterate through all of the PropertyInfo, find the
- // one with the corresponding to the NamedProperty name
- // and add it to the array of properties to set.
- for (int j = 0; j < attributeProperties.Length; j++)
- {
- if (attributeProperties[j].Name == namedArgument.MemberInfo.Name)
- {
- propertiesToSet.Add(attributeProperties[j]);
- namedParameterValues.Add(ConvertValueIfNecessary(namedArgument.TypedValue.Value));
- break;
- }
- else
- {
- if (j == attributeProperties.Length - 1)
- {
- // In case of no match, throw
- noMatchingProperty = true;
+ }
+ else
+ {
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ Type paramType = parameters[i].ParameterType;
+ object paramValue = paramValues[i];
+ if ((paramValue == null && paramType.IsValueType)
+ || (paramValue != null && !paramType.IsAssignableFrom(paramValue.GetType())))
+ {
+ isMatch = false;
+ break;
+ }
+ if (paramValue == null || paramType != paramValue.GetType())
+ {
+ isExactMatch = false;
+ }
+ }
+ }
+ }
+ catch (InvalidCastException)
+ {
+ isMatch = false;
+ }
+
+ if (isMatch)
+ {
+ if (isExactMatch)
+ {
+ return m;
+ }
+
+ matchCount++;
+ if (matchCount == 1)
+ {
+ match = m;
+ }
+ else
+ {
+ throw new AmbiguousMatchException(
+ string.Format("Ambiguous match for {0} '{1}' for the specified number and types of arguments.", methodTypeName,
+ m.Name));
+ }
+ }
+ }
+
+ return match;
+ }
+
+ ///
+ /// From a given list of constructors, selects the constructor having an exact match on the given ' types.
+ ///
+ /// the list of constructors to choose from
+ /// the arguments to the method
+ /// the constructor matching exactly the passed ' types
+ ///
+ /// If more than 1 matching methods are found in the list.
+ ///
+ public static ConstructorInfo GetConstructorByArgumentValues(ConstructorInfo[] methods, object[] argValues)
+ {
+ return (ConstructorInfo)GetMethodBaseByArgumentValues("constructor", methods, argValues);
+ }
+
+
+ ///
+ /// Packages arguments into argument list containing parameter array as a last argument.
+ ///
+ /// Argument vaklues to package.
+ /// Total number of oarameters.
+ /// Type of the param array element.
+ /// Packaged arguments.
+ public static object[] PackageParamArray(object[] argValues, int argCount, Type elementType)
+ {
+ object[] values = new object[argCount];
+ int i = 0;
+
+ // copy regular arguments
+ while (i < argCount - 1)
+ {
+ values[i] = argValues[i];
+ i++;
+ }
+
+ // package param array into last argument
+ Array paramArray = Array.CreateInstance(elementType, argValues.Length - i);
+ int j = 0;
+ while (i < argValues.Length)
+ {
+ paramArray.SetValue(argValues[i++], j++);
+ }
+ values[values.Length - 1] = paramArray;
+
+ return values;
+ }
+
+ ///
+ /// Convenience method to convert an interface
+ /// to a array that contains
+ /// all the interfaces inherited and the specified interface.
+ ///
+ /// The interface to convert.
+ /// An array of interface s.
+ ///
+ /// If the specified is not an interface.
+ ///
+ ///
+ /// If is .
+ ///
+ public static Type[] ToInterfaceArray(Type intf)
+ {
+ AssertUtils.ArgumentNotNull(intf, "intf");
+
+ if (!intf.IsInterface)
+ {
+ throw new ArgumentException(
+ string.Format(CultureInfo.InvariantCulture,
+ "[{0}] is a class.",
+ intf.FullName));
+ }
+
+ ArrayList interfaces = new ArrayList(intf.GetInterfaces());
+ interfaces.Add(intf);
+
+ return (Type[])interfaces.ToArray(typeof(Type));
+ }
+
+ ///
+ /// Is the supplied the default indexer for the
+ /// supplied ?
+ ///
+ ///
+ /// The name of the property on the supplied to be checked.
+ ///
+ ///
+ /// The to be checked.
+ ///
+ ///
+ /// if the supplied is the
+ /// default indexer for the supplied .
+ ///
+ ///
+ /// If the supplied is .
+ ///
+ public static bool PropertyIsIndexer(string propertyName, Type type)
+ {
+ DefaultMemberAttribute[] attribs =
+ (DefaultMemberAttribute[])type.GetCustomAttributes(typeof(DefaultMemberAttribute), true);
+ if (attribs.Length != 0)
+ {
+ foreach (DefaultMemberAttribute attrib in attribs)
+ {
+ if (attrib.MemberName.Equals(propertyName))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Is the supplied declared on one of these interfaces?
+ ///
+ /// The method to check.
+ /// The array of interfaces we want to check.
+ ///
+ /// if the method is declared on one of these interfaces.
+ ///
+ ///
+ /// If any of the s specified is not an interface.
+ ///
+ ///
+ /// If or any of the specified interfaces is
+ /// .
+ ///
+ public static bool MethodIsOnOneOfTheseInterfaces(MethodBase method, Type[] interfaces)
+ {
+ AssertUtils.ArgumentNotNull(method, "method");
+ if (interfaces == null)
+ {
+ return false;
+ }
+ Type[] paramTypes = GetParameterTypes(method.GetParameters());
+ for (int i = 0; i < interfaces.Length; i++)
+ {
+ Type interfaceType = interfaces[i];
+ AssertUtils.ArgumentNotNull(interfaceType, StringUtils.Surround("interfaces[", i, "]"));
+ if (!interfaceType.IsInterface)
+ {
+ throw new ArgumentException(interfaces[i].FullName + " is not an interface");
+ }
+ try
+ {
+ MethodInfo mi = interfaceType.GetMethod(
+ method.Name,
+ BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly,
+ null, paramTypes, null);
+ if (mi != null)
+ {
+ // found it...
+ return true;
+ }
+ }
+ catch
+ {
+ // didn't find it, so keep going...
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Returns the default value for the specified
+ ///
+ ///
+ ///
+ /// Follows the standard .NET conventions for default values where
+ /// relevant; for example, all numeric types default to the value
+ /// 0.
+ ///
+ ///
+ ///
+ /// The to return default value for.
+ ///
+ ///
+ /// The default value for the specified .
+ ///
+ ///
+ /// If the supplied is an enumerated type that
+ /// has no values.
+ ///
+ public static object GetDefaultValue(Type type)
+ {
+ if (!type.IsValueType)
+ {
+ return null;
+ }
+ if (type == typeof(Boolean))
+ {
+ return false;
+ }
+ if (type == typeof(DateTime))
+ {
+ return DateTime.MinValue;
+ }
+ if (type == typeof(Char))
+ {
+ return Char.MinValue;
+ }
+ if (type.IsEnum)
+ {
+ Array values = Enum.GetValues(type);
+ if (values == null || values.Length == 0)
+ {
+ throw new ArgumentException("Bad 'enum' Type : cannot get default value because 'enum' has no values.");
+ }
+ return values.GetValue(0);
+ }
+ return 0;
+ }
+
+ ///
+ /// Returns an array consisting of the default values for the supplied
+ /// .
+ ///
+ ///
+ /// The array of s to return default values for.
+ ///
+ ///
+ /// An array consisting of the default values for the supplied
+ /// .
+ ///
+ ///
+ /// If any of the elements in the supplied
+ /// array is an enumerated type that has no values.
+ ///
+ ///
+ public static object[] GetDefaultValues(Type[] types)
+ {
+ object[] defaults = new object[types.Length];
+ for (int i = 0; i < types.Length; ++i)
+ {
+ defaults[i] = GetDefaultValue(types[i]);
+ }
+ return defaults;
+ }
+
+ ///
+ /// Checks that the parameter s of the
+ /// supplied match the parameter
+ /// s of the supplied
+ /// .
+ ///
+ /// The method to be checked.
+ ///
+ /// The array of parameter s to check against.
+ ///
+ ///
+ /// if the parameter s
+ /// match.
+ ///
+ public static bool ParameterTypesMatch(
+ MethodInfo candidate, Type[] parameterTypes)
+ {
+ #region Sanity Checks
+
+ AssertUtils.ArgumentNotNull(candidate, "candidate");
+ AssertUtils.ArgumentNotNull(parameterTypes, "parameterTypes");
+
+ #endregion
+
+ Type[] candidatesParameterTypes
+ = ReflectionUtils.GetParameterTypes(candidate);
+ if (candidatesParameterTypes.Length != parameterTypes.Length)
+ {
+ return false;
+ }
+ for (int i = 0; i < candidatesParameterTypes.Length; ++i)
+ {
+ if (!candidatesParameterTypes[i].Equals(parameterTypes[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ ///
+ /// Returns an array containing the s of the
+ /// objects in the supplied array.
+ ///
+ ///
+ /// The objects array for which the corresponding s
+ /// are needed.
+ ///
+ ///
+ /// An array containing the s of the objects
+ /// in the supplied array; this array will be empty (but not
+ /// if the supplied
+ /// is null or has no elements.
+ ///
+ ///
+ ///
+ /// [C#]
+ /// Given an array containing the following objects,
+ /// [83, "Foo", new object ()], the
+ /// array returned from this method call would consist of the following
+ /// elements...
+ /// [Int32, String, Object].
+ ///
+ ///
+ public static Type[] GetTypes(object[] args)
+ {
+ if (args == null || args.Length == 0)
+ {
+ return Type.EmptyTypes;
+ }
+ Type[] paramsType = new Type[args.Length];
+ for (int i = 0; i < args.Length; ++i)
+ {
+ object arg = args[i];
+ paramsType[i] = (arg != null) ? args[i].GetType() : typeof(object);
+ }
+ return paramsType;
+ }
+
+ ///
+ /// Does the given and/or it's superclasses
+ /// have at least one or more methods with the given name (with any
+ /// argument types)?
+ ///
+ ///
+ ///
+ /// Includes non-public methods in the methods searched.
+ ///
+ ///
+ ///
+ /// The to be checked.
+ ///
+ ///
+ /// The name of the method to be searched for. Case inSenSItivE.
+ ///
+ ///
+ /// if the given or / and it's
+ /// superclasses have at least one or more methods (with any argument types);
+ /// if not, or either of the parameters is .
+ ///
+ public static bool HasAtLeastOneMethodWithName(Type type, string name)
+ {
+ if (type == null || StringUtils.IsNullOrEmpty(name))
+ {
+ return false;
+ }
+ return MethodCountForName(type, name) > 0;
+ }
+
+ ///
+ /// Within , counts the number of overloads for the method with the given (case-insensitive!)
+ ///
+ /// The type to be searched
+ /// the name of the method for which overloads shall be counted
+ /// The number of overloads for method within type
+ public static int MethodCountForName(Type type, string name)
+ {
+ AssertUtils.ArgumentNotNull(type, "type", "Type must not be null");
+ AssertUtils.ArgumentNotNull(name, "name", "Method name must not be null");
+ MemberInfo[] methods = type.FindMembers(
+ MemberTypes.Method,
+ ReflectionUtils.AllMembersCaseInsensitiveFlags,
+ new MemberFilter(ReflectionUtils.MethodNameFilter),
+ name);
+ return methods.Length;
+ }
+
+ private static bool MethodNameFilter(MemberInfo member, object criteria)
+ {
+ MethodInfo method = member as MethodInfo;
+ string name = criteria as string;
+ return String.Compare(method.Name, name, true, CultureInfo.InvariantCulture) == 0;
+ }
+
+ ///
+ /// Creates a .
+ ///
+ ///
+ ///
+ /// Note that if a non-
+ /// is supplied, any read write properties exposed by the
+ /// will be used to overwrite values that may have been passed in via the
+ /// . That is, the will be used
+ /// to initialize the custom attribute, and then any read-write properties on the
+ /// will be plugged in.
+ ///
+ ///
+ ///
+ /// The desired .
+ ///
+ ///
+ /// Any constructor arguments for the attribute (may be
+ /// in the case of no arguments).
+ ///
+ ///
+ /// Source attribute to copy properties from (may be ).
+ ///
+ /// A custom attribute builder.
+ ///
+ /// If the parameter is .
+ ///
+ ///
+ /// If the parameter is not a
+ /// that derives from the class.
+ ///
+ ///
+ public static CustomAttributeBuilder CreateCustomAttribute(
+ Type type, object[] ctorArgs, Attribute sourceAttribute)
+ {
+ #region Sanity Checks
+
+ AssertUtils.ArgumentNotNull(type, "type");
+ if (!typeof(Attribute).IsAssignableFrom(type))
+ {
+ throw new ArgumentException(
+ string.Format("[{0}] does not derive from the [System.Attribute] class.",
+ type.FullName));
+ }
+
+ #endregion
+
+ ConstructorInfo ci = type.GetConstructor(ReflectionUtils.GetTypes(ctorArgs));
+ if (ci == null && ctorArgs.Length == 0)
+ {
+ ci = type.GetConstructors()[0];
+ ctorArgs = GetDefaultValues(GetParameterTypes(ci.GetParameters()));
+ }
+
+ if (sourceAttribute != null)
+ {
+ object defaultAttribute = null;
+ try
+ {
+ defaultAttribute = ci.Invoke(ctorArgs);
+ }
+ catch
+ {
+ }
+
+ IList getSetProps = new ArrayList();
+ IList getSetValues = new ArrayList();
+ IList readOnlyProps = new ArrayList();
+ IList readOnlyValues = new ArrayList();
+ foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
+ {
+ if (pi.DeclaringType == typeof(Attribute))
+ continue;
+
+ if (pi.CanRead)
+ {
+ if (pi.CanWrite)
+ {
+ object propValue = pi.GetValue(sourceAttribute, null);
+ if (defaultAttribute != null)
+ {
+ object defaultValue = pi.GetValue(defaultAttribute, null);
+ if ((propValue == null && defaultValue == null) ||
+ (propValue != null && propValue.Equals(defaultValue)))
+ continue;
+ }
+ getSetProps.Add(pi);
+ getSetValues.Add(propValue);
+ }
+ else
+ {
+ readOnlyProps.Add(pi);
+ readOnlyValues.Add(pi.GetValue(sourceAttribute, null));
+ }
+ }
+ }
+
+ if (readOnlyProps.Count == 1)
+ {
+ PropertyInfo pi = readOnlyProps[0] as PropertyInfo;
+ ConstructorInfo ciTemp = type.GetConstructor(new Type[1] { pi.PropertyType });
+ if (ciTemp != null)
+ {
+ ci = ciTemp;
+ ctorArgs = new object[1] { readOnlyValues[0] };
+ }
+ else
+ {
+ ciTemp = type.GetConstructor(new Type[1] { readOnlyValues[0].GetType() });
+ if (ciTemp != null)
+ {
+ ci = ciTemp;
+ ctorArgs = new object[1] { readOnlyValues[0] };
+ }
+ }
+ }
+
+ PropertyInfo[] propertyInfos = new PropertyInfo[getSetProps.Count];
+ getSetProps.CopyTo(propertyInfos, 0);
+
+ object[] propertyValues = new object[getSetValues.Count];
+ getSetValues.CopyTo(propertyValues, 0);
+
+ return new CustomAttributeBuilder(ci, ctorArgs, propertyInfos, propertyValues);
+ }
+ else
+ {
+ return new CustomAttributeBuilder(ci, ctorArgs);
+ }
+ }
+
+ ///
+ /// Creates a .
+ ///
+ ///
+ /// The desired .
+ ///
+ ///
+ /// Source attribute to copy properties from (may be ).
+ ///
+ /// A custom attribute builder.
+ public static CustomAttributeBuilder CreateCustomAttribute(
+ Type type, Attribute sourceAttribute)
+ {
+ return CreateCustomAttribute(type, new object[] { }, sourceAttribute);
+ }
+
+ ///
+ /// Creates a .
+ ///
+ ///
+ /// The source attribute to copy properties from.
+ ///
+ /// A custom attribute builder.
+ ///
+ /// If the supplied is
+ /// .
+ ///
+ public static CustomAttributeBuilder CreateCustomAttribute(Attribute sourceAttribute)
+ {
+ return CreateCustomAttribute(sourceAttribute.GetType(), sourceAttribute);
+ }
+
+ ///
+ /// Creates a .
+ ///
+ ///
+ /// The desired .
+ ///
+ /// A custom attribute builder.
+ public static CustomAttributeBuilder CreateCustomAttribute(Type type)
+ {
+ return CreateCustomAttribute(type, new object[] { }, null);
+ }
+
+ ///
+ /// Creates a .
+ ///
+ ///
+ /// The desired .
+ ///
+ ///
+ /// Any constructor arguments for the attribute (may be
+ /// in the case of no arguments).
+ ///
+ /// A custom attribute builder.
+ public static CustomAttributeBuilder CreateCustomAttribute(
+ Type type, params object[] ctorArgs)
+ {
+ return CreateCustomAttribute(type, ctorArgs, null);
+ }
+
+#if NET_2_0
+ ///
+ /// Creates a .
+ ///
+ ///
+ /// The to create
+ /// the custom attribute builder from.
+ ///
+ /// A custom attribute builder.
+ public static CustomAttributeBuilder CreateCustomAttribute(CustomAttributeData attributeData)
+ {
+ object[] parameterValues = new object[attributeData.ConstructorArguments.Count];
+ Type[] parameterTypes = new Type[attributeData.ConstructorArguments.Count];
+
+ IList namedParameterValues = new ArrayList();
+ IList namedFieldValues = new ArrayList();
+
+ // Fill arrays of the constructor parameters
+ for (int i = 0; i < attributeData.ConstructorArguments.Count; i++)
+ {
+ parameterTypes[i] = attributeData.ConstructorArguments[i].ArgumentType;
+ parameterValues[i] = ConvertValueIfNecessary(attributeData.ConstructorArguments[i].Value);
+ }
+
+ Type attributeType = attributeData.Constructor.DeclaringType;
+ PropertyInfo[] attributeProperties = attributeType.GetProperties(
+ BindingFlags.Instance | BindingFlags.Public);
+ FieldInfo[] attributeFields = attributeType.GetFields(
+ BindingFlags.Instance | BindingFlags.Public);
+
+ // Not using generics bellow as probably Spring.NET tries to keep
+ // it on .NET1 compatibility level right now I believe (SD)
+ // In case of using List the above note makes
+ // no sense (SD:)
+ IList propertiesToSet = new ArrayList();
+ int k = 0;
+
+ IList fieldsToSet = new ArrayList();
+ int n = 0;
+
+
+ // Fills arrays of the constructor named parameters
+ foreach (CustomAttributeNamedArgument namedArgument in attributeData.NamedArguments)
+ {
+ bool noMatchingProperty = false;
+
+ // Now iterate through all of the PropertyInfo, find the
+ // one with the corresponding to the NamedProperty name
+ // and add it to the array of properties to set.
+ for (int j = 0; j < attributeProperties.Length; j++)
+ {
+ if (attributeProperties[j].Name == namedArgument.MemberInfo.Name)
+ {
+ propertiesToSet.Add(attributeProperties[j]);
+ namedParameterValues.Add(ConvertValueIfNecessary(namedArgument.TypedValue.Value));
+ break;
+ }
+ else
+ {
+ if (j == attributeProperties.Length - 1)
+ {
+ // In case of no match, throw
+ noMatchingProperty = true;
/*
throw new InvalidOperationException(
String.Format(CultureInfo.InvariantCulture,
@@ -977,388 +984,396 @@ namespace Spring.Util
"type {1}, but is present as a named property " +
"on the attributeData {2}", namedArgument.MemberInfo.Name,
attributeType.FullName, attributeData));
- */
- }
- }
- }
- if (noMatchingProperty)
- {
- for (int j = 0; j < attributeFields.Length; j++)
- {
- if (attributeFields[j].Name == namedArgument.MemberInfo.Name)
- {
- fieldsToSet.Add(attributeFields[j]);
- namedFieldValues.Add(ConvertValueIfNecessary(namedArgument.TypedValue.Value));
- break;
- }
- else
- {
- if (j == attributeFields.Length - 1)
- {
- throw new InvalidOperationException(
- String.Format(CultureInfo.InvariantCulture,
- "A property or public field with name {0} can't be found in the " +
- "type {1}, but is present as a named property " +
- "on the attributeData {2}", namedArgument.MemberInfo.Name,
- attributeType.FullName, attributeData));
- }
- }
- }
- }
- }
- // Get constructor corresponding to the parameters and their types
- ConstructorInfo constructor = attributeType.GetConstructor(parameterTypes);
-
- PropertyInfo[] namedProperties = new PropertyInfo[propertiesToSet.Count];
- propertiesToSet.CopyTo(namedProperties, 0);
-
- object[] propertyValues = new object[namedParameterValues.Count];
- namedParameterValues.CopyTo(propertyValues, 0);
-
- if (fieldsToSet.Count == 0)
- {
- return new CustomAttributeBuilder(
- constructor, parameterValues, namedProperties, propertyValues);
- }
- else
- {
- FieldInfo[] namedFields = new FieldInfo[fieldsToSet.Count];
- fieldsToSet.CopyTo(namedFields, 0);
-
- object[] fieldValues = new object[namedFieldValues.Count];
- namedFieldValues.CopyTo(fieldValues, 0);
-
- return new CustomAttributeBuilder(
- constructor, parameterValues, namedProperties, propertyValues, namedFields, fieldValues);
- }
-
-
-
- }
-
- private static object ConvertValueIfNecessary(object value)
- {
- if (value == null) return value;
-
- // We are only hunting for the case of the ReadOnlyCollection here.
- ReadOnlyCollection sourceArray =
- value as ReadOnlyCollection;
-
- if (sourceArray == null) return value;
-
- Type underlyingType = null; // type to be used for arguments
- Array returnArray = null;
- for (int i = 0; i < sourceArray.Count; i++)
- {
- if (underlyingType == null)
- {
- underlyingType = sourceArray[i].ArgumentType;
- returnArray = Array.CreateInstance(underlyingType, sourceArray.Count);
- }
- if (!underlyingType.Equals(sourceArray[i].ArgumentType))
- {
- throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
- "Types for the same named parameter of array type are expected to be same"));
- }
-
- returnArray.SetValue(sourceArray[i].Value, i);
- }
-
- return returnArray;
-
- }
-#endif
-
- ///
- /// Tries to find matching methods in the specified
- /// for each method in the supplied list.
- ///
- ///
- /// The to look for matching methods in.
- ///
- /// The methods to match.
- ///
- /// A flag that specifies whether to throw an exception if a matching
- /// method is not found.
- ///
- /// A list of the matched methods.
- ///
- /// If either of the or
- /// parameters are .
- ///
- public static MethodInfo[] GetMatchingMethods(Type type, MethodInfo[] methods, bool strict)
- {
- AssertUtils.ArgumentNotNull(type, "type");
- AssertUtils.ArgumentNotNull(methods, "methods");
-
- BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase;
-
- MethodInfo[] matched = new MethodInfo[methods.Length];
- for (int i = 0; i < methods.Length; i++)
- {
- MethodInfo method = methods[i];
- MethodInfo match = type.GetMethod(method.Name, flags, null, ReflectionUtils.GetParameterTypes(method), null);
- if ((match == null || match.ReturnType != method.ReturnType) && strict)
- {
- throw new Exception(
- string.Format("Method '{0}' could not be matched in the target class [{1}].",
- method.Name, type.FullName));
- }
- matched[i] = match;
- }
- return matched;
- }
-
- ///
- /// Returns the of the supplied
- /// .
- ///
- ///
- ///
- /// If the is a
- /// instance, the return value of this method call with be the
- /// parameter cast to a
- /// . If the is
- /// anything other than a , the return value
- /// will be the result of invoking the 's
- /// method.
- ///
- ///
- ///
- /// A or instance.
- ///
- ///
- /// The argument if it is a
- /// or the result of invoking
- /// on the argument if it
- /// is an .
- ///
- ///
- /// If the is .
- ///
- public static Type TypeOfOrType(object source)
- {
- return source is Type ? source as Type : source.GetType();
- }
-
-
-#if NET_2_0
- private static readonly MethodInfo Exception_InternalPreserveStackTrace =
- typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic);
+ */
+ }
+ }
+ }
+ if (noMatchingProperty)
+ {
+ for (int j = 0; j < attributeFields.Length; j++)
+ {
+ if (attributeFields[j].Name == namedArgument.MemberInfo.Name)
+ {
+ fieldsToSet.Add(attributeFields[j]);
+ namedFieldValues.Add(ConvertValueIfNecessary(namedArgument.TypedValue.Value));
+ break;
+ }
+ else
+ {
+ if (j == attributeFields.Length - 1)
+ {
+ throw new InvalidOperationException(
+ String.Format(CultureInfo.InvariantCulture,
+ "A property or public field with name {0} can't be found in the " +
+ "type {1}, but is present as a named property " +
+ "on the attributeData {2}", namedArgument.MemberInfo.Name,
+ attributeType.FullName, attributeData));
+ }
+ }
+ }
+ }
+ }
+ // Get constructor corresponding to the parameters and their types
+ ConstructorInfo constructor = attributeType.GetConstructor(parameterTypes);
+
+ PropertyInfo[] namedProperties = new PropertyInfo[propertiesToSet.Count];
+ propertiesToSet.CopyTo(namedProperties, 0);
+
+ object[] propertyValues = new object[namedParameterValues.Count];
+ namedParameterValues.CopyTo(propertyValues, 0);
+
+ if (fieldsToSet.Count == 0)
+ {
+ return new CustomAttributeBuilder(
+ constructor, parameterValues, namedProperties, propertyValues);
+ }
+ else
+ {
+ FieldInfo[] namedFields = new FieldInfo[fieldsToSet.Count];
+ fieldsToSet.CopyTo(namedFields, 0);
+
+ object[] fieldValues = new object[namedFieldValues.Count];
+ namedFieldValues.CopyTo(fieldValues, 0);
+
+ return new CustomAttributeBuilder(
+ constructor, parameterValues, namedProperties, propertyValues, namedFields, fieldValues);
+ }
+
+
+
+ }
+
+ private static object ConvertValueIfNecessary(object value)
+ {
+ if (value == null)
+ return value;
+
+ // We are only hunting for the case of the ReadOnlyCollection here.
+ ReadOnlyCollection sourceArray =
+ value as ReadOnlyCollection;
+
+ if (sourceArray == null)
+ return value;
+
+ Type underlyingType = null; // type to be used for arguments
+ Array returnArray = null;
+ for (int i = 0; i < sourceArray.Count; i++)
+ {
+ if (underlyingType == null)
+ {
+ underlyingType = sourceArray[i].ArgumentType;
+ returnArray = Array.CreateInstance(underlyingType, sourceArray.Count);
+ }
+ if (!underlyingType.Equals(sourceArray[i].ArgumentType))
+ {
+ throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
+ "Types for the same named parameter of array type are expected to be same"));
+ }
+
+ returnArray.SetValue(sourceArray[i].Value, i);
+ }
+
+ return returnArray;
+
+ }
+#endif
+
+ ///
+ /// Tries to find matching methods in the specified
+ /// for each method in the supplied list.
+ ///
+ ///
+ /// The to look for matching methods in.
+ ///
+ /// The methods to match.
+ ///
+ /// A flag that specifies whether to throw an exception if a matching
+ /// method is not found.
+ ///
+ /// A list of the matched methods.
+ ///
+ /// If either of the or
+ /// parameters are .
+ ///
+ public static MethodInfo[] GetMatchingMethods(Type type, MethodInfo[] methods, bool strict)
+ {
+ AssertUtils.ArgumentNotNull(type, "type");
+ AssertUtils.ArgumentNotNull(methods, "methods");
+
+ BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase;
+
+ MethodInfo[] matched = new MethodInfo[methods.Length];
+ for (int i = 0; i < methods.Length; i++)
+ {
+ MethodInfo method = methods[i];
+ MethodInfo match = type.GetMethod(method.Name, flags, null, ReflectionUtils.GetParameterTypes(method), null);
+ if ((match == null || match.ReturnType != method.ReturnType) && strict)
+ {
+ throw new Exception(
+ string.Format("Method '{0}' could not be matched in the target class [{1}].",
+ method.Name, type.FullName));
+ }
+ matched[i] = match;
+ }
+ return matched;
+ }
+
+ ///
+ /// Returns the of the supplied
+ /// .
+ ///
+ ///
+ ///
+ /// If the is a
+ /// instance, the return value of this method call with be the
+ /// parameter cast to a
+ /// . If the is
+ /// anything other than a , the return value
+ /// will be the result of invoking the 's
+ /// method.
+ ///
+ ///
+ ///
+ /// A or instance.
+ ///
+ ///
+ /// The argument if it is a
+ /// or the result of invoking
+ /// on the argument if it
+ /// is an .
+ ///
+ ///
+ /// If the is .
+ ///
+ public static Type TypeOfOrType(object source)
+ {
+ return source is Type ? source as Type : source.GetType();
+ }
+
+
+#if NET_2_0
+ private static readonly MethodInfo Exception_InternalPreserveStackTrace =
+ typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic);
#else
private static readonly FieldInfo Exception_RemoteStackTraceString =
typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic);
-#endif
-
- ///
- /// Unwraps the supplied
- /// and returns the inner exception preserving the stack trace.
- ///
- ///
- /// The to unwrap.
- ///
- /// The unwrapped exception.
- public static Exception UnwrapTargetInvocationException(TargetInvocationException ex)
- {
-#if NET_2_0
- Exception_InternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] { });
+#endif
+
+ ///
+ /// Unwraps the supplied
+ /// and returns the inner exception preserving the stack trace.
+ ///
+ ///
+ /// The to unwrap.
+ ///
+ /// The unwrapped exception.
+ public static Exception UnwrapTargetInvocationException(TargetInvocationException ex)
+ {
+#if NET_2_0
+ Exception_InternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] { });
#else
Exception_RemoteStackTraceString.SetValue(ex.InnerException, ex.InnerException.StackTrace + Environment.NewLine);
-#endif
- return ex.InnerException;
- }
-
- ///
- /// Is the supplied can be accessed outside the assembly ?
- ///
- /// The type to check.
- ///
- /// if the type can be accessed outside the assembly;
- /// Otherwise .
- ///
- public static bool IsTypeVisible(Type type)
- {
- return IsTypeVisible(type, null);
- }
-
- ///
- /// Is the supplied can be accessed
- /// from the supplied friendly assembly ?
- ///
- /// The type to check.
- /// The friendly assembly name.
- ///
- /// if the type can be accessed
- /// from the supplied friendly assembly; Otherwise .
- ///
- public static bool IsTypeVisible(Type type, string friendlyAssemblyName)
- {
-#if NET_2_0
- if (type.IsVisible)
- {
- return true;
- }
- else
- {
- if (friendlyAssemblyName != null
- && friendlyAssemblyName.Length > 0
- && (!type.IsNested || type.IsNestedPublic ||
- (!type.IsNestedPrivate && (type.IsNestedAssembly || type.IsNestedFamORAssem))))
- {
- object[] attrs = type.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), false);
- foreach (InternalsVisibleToAttribute ivta in attrs)
- {
- if (ivta.AssemblyName == friendlyAssemblyName)
- {
- return true;
- }
- }
- }
- }
+#endif
+ return ex.InnerException;
+ }
+
+ ///
+ /// Is the supplied can be accessed outside the assembly ?
+ ///
+ /// The type to check.
+ ///
+ /// if the type can be accessed outside the assembly;
+ /// Otherwise .
+ ///
+ public static bool IsTypeVisible(Type type)
+ {
+ return IsTypeVisible(type, null);
+ }
+
+ ///
+ /// Is the supplied can be accessed
+ /// from the supplied friendly assembly ?
+ ///
+ /// The type to check.
+ /// The friendly assembly name.
+ ///
+ /// if the type can be accessed
+ /// from the supplied friendly assembly; Otherwise .
+ ///
+ public static bool IsTypeVisible(Type type, string friendlyAssemblyName)
+ {
+#if NET_2_0
+ if (type.IsVisible)
+ {
+ return true;
+ }
+ else
+ {
+ if (friendlyAssemblyName != null
+ && friendlyAssemblyName.Length > 0
+ && (!type.IsNested || type.IsNestedPublic ||
+ (!type.IsNestedPrivate && (type.IsNestedAssembly || type.IsNestedFamORAssem))))
+ {
+ object[] attrs = type.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), false);
+ foreach (InternalsVisibleToAttribute ivta in attrs)
+ {
+ if (ivta.AssemblyName == friendlyAssemblyName)
+ {
+ return true;
+ }
+ }
+ }
+ }
#else
if (type.IsPublic || (type.IsNestedPublic && type.DeclaringType.IsPublic))
{
return true;
}
-#endif
- return false;
+#endif
+ return false;
}
- ///
- /// Gets all of the interfaces implemented by
- /// the specified .
- ///
- ///
- /// The object to get the interfaces of.
- ///
- ///
- /// All of the interfaces implemented by the
- /// .
- ///
- public static Type[] GetInterfaces(Type type)
- {
- AssertUtils.ArgumentNotNull(type, "type");
-
- if (type.IsInterface)
- {
- ArrayList interfaces = new ArrayList();
- interfaces.Add(type);
- interfaces.AddRange(type.GetInterfaces());
- return (Type[])interfaces.ToArray(typeof(Type));
- }
- else
- {
- return type.GetInterfaces();
- }
- }
-
- ///
- /// Returns the explicit that is the root cause of an exception.
- ///
- ///
- /// If the InnerException property of the current exception is a null reference
- /// or a , returns the current exception.
- ///
- /// The last exception thrown.
- ///
- /// The first explicit exception thrown in a chain of exceptions.
- ///
- public static Exception GetExplicitBaseException(Exception ex)
- {
- Exception innerEx = ex.InnerException;
- while (innerEx != null &&
- !(innerEx is NullReferenceException))
- {
- ex = innerEx;
- innerEx = innerEx.InnerException;
- }
- return ex;
- }
-
- ///
- /// Copies all fields from one object to another.
- ///
- ///
- /// The types of both objects must be related. This means, that either of the following is true:
- ///
- /// - fromObject.GetType() == toObject.GetType()
- /// - fromObject.GetType() is derived from toObject.GetType()
- /// - toObject.GetType() is derived from fromObject.GetType()
- ///
- ///
- /// The source object
- /// The object, who's fields will be populated with values from the source object
- /// If the object's types are not related
- public static void MemberwiseCopy(object fromObject, object toObject)
- {
- Type fromType = fromObject.GetType();
- Type toType = toObject.GetType();
-
- Type smallerType;
-
- if (fromType.IsAssignableFrom(toType))
- {
- smallerType = fromType;
- }
- else if (toType.IsAssignableFrom(fromType))
- {
- smallerType = toType;
- }
- else
- {
- throw new ArgumentException("object types are not related");
- }
-
- MemberwiseCopyInternal(fromObject, toObject, smallerType);
- }
-
-#if NET_2_0
- private static void MemberwiseCopyInternal(object fromObject, object toObject, Type smallerType)
- {
- MemberwiseCopyHandler impl = GetImpl(smallerType);
- impl(fromObject, toObject);
- }
-
- private delegate void MemberwiseCopyHandler(object a, object b);
-
- private static readonly Hashtable s_handlerCache = new Hashtable();
-
- private static MemberwiseCopyHandler GetImpl(Type type)
- {
- MemberwiseCopyHandler handler = s_handlerCache[type] as MemberwiseCopyHandler;
- if (handler != null) return handler;
-
- lock (s_handlerCache)
- {
- handler = s_handlerCache[type] as MemberwiseCopyHandler;
- if (handler != null) return handler;
-
- FieldInfo[] fields = GetFields(type);
- DynamicMethod dm = new DynamicMethod(type.FullName + ".ShallowCopy", null, new Type[] { typeof(object), typeof(object) }, type.Module, true);
- ILGenerator ilGen = dm.GetILGenerator();
- ilGen.DeclareLocal(type);
- ilGen.DeclareLocal(type);
- ilGen.Emit(OpCodes.Ldarg_0);
- ilGen.Emit(OpCodes.Castclass, type);
- ilGen.Emit(OpCodes.Stloc_0);
- ilGen.Emit(OpCodes.Ldarg_1);
- ilGen.Emit(OpCodes.Castclass, type);
- ilGen.Emit(OpCodes.Stloc_1);
-
- foreach (FieldInfo field in fields)
- {
- ilGen.Emit(OpCodes.Ldloc_1);
- ilGen.Emit(OpCodes.Ldloc_0);
- ilGen.Emit(OpCodes.Ldfld, field);
- ilGen.Emit(OpCodes.Stfld, field);
- }
- ilGen.Emit(OpCodes.Ret);
-
- handler = (MemberwiseCopyHandler)dm.CreateDelegate(typeof(MemberwiseCopyHandler));
- s_handlerCache[type] = handler;
- }
- return handler;
- }
+ ///
+ /// Gets all of the interfaces implemented by
+ /// the specified .
+ ///
+ ///
+ /// The object to get the interfaces of.
+ ///
+ ///
+ /// All of the interfaces implemented by the
+ /// .
+ ///
+ public static Type[] GetInterfaces(Type type)
+ {
+ AssertUtils.ArgumentNotNull(type, "type");
+
+ if (type.IsInterface)
+ {
+ ArrayList interfaces = new ArrayList();
+ interfaces.Add(type);
+ interfaces.AddRange(type.GetInterfaces());
+ return (Type[])interfaces.ToArray(typeof(Type));
+ }
+ else
+ {
+ return type.GetInterfaces();
+ }
+ }
+
+ ///
+ /// Returns the explicit that is the root cause of an exception.
+ ///
+ ///
+ /// If the InnerException property of the current exception is a null reference
+ /// or a , returns the current exception.
+ ///
+ /// The last exception thrown.
+ ///
+ /// The first explicit exception thrown in a chain of exceptions.
+ ///
+ public static Exception GetExplicitBaseException(Exception ex)
+ {
+ Exception innerEx = ex.InnerException;
+ while (innerEx != null &&
+ !(innerEx is NullReferenceException))
+ {
+ ex = innerEx;
+ innerEx = innerEx.InnerException;
+ }
+ return ex;
+ }
+
+ ///
+ /// Copies all fields from one object to another.
+ ///
+ ///
+ /// The types of both objects must be related. This means, that either of the following is true:
+ ///
+ /// - fromObject.GetType() == toObject.GetType()
+ /// - fromObject.GetType() is derived from toObject.GetType()
+ /// - toObject.GetType() is derived from fromObject.GetType()
+ ///
+ ///
+ /// The source object
+ /// The object, who's fields will be populated with values from the source object
+ /// If the object's types are not related
+ public static void MemberwiseCopy(object fromObject, object toObject)
+ {
+ Type fromType = fromObject.GetType();
+ Type toType = toObject.GetType();
+
+ Type smallerType;
+
+ if (fromType.IsAssignableFrom(toType))
+ {
+ smallerType = fromType;
+ }
+ else if (toType.IsAssignableFrom(fromType))
+ {
+ smallerType = toType;
+ }
+ else
+ {
+ throw new ArgumentException("object types are not related");
+ }
+
+ MemberwiseCopyInternal(fromObject, toObject, smallerType);
+ }
+
+#if NET_2_0
+ private static void MemberwiseCopyInternal(object fromObject, object toObject, Type smallerType)
+ {
+ MemberwiseCopyHandler impl = GetImpl(smallerType);
+ impl(fromObject, toObject);
+ }
+
+ private delegate void MemberwiseCopyHandler(object a, object b);
+
+ private static readonly Hashtable s_handlerCache = new Hashtable();
+
+ private static MemberwiseCopyHandler GetImpl(Type type)
+ {
+ MemberwiseCopyHandler handler = s_handlerCache[type] as MemberwiseCopyHandler;
+ if (handler != null)
+ return handler;
+
+ lock (s_handlerCache)
+ {
+ handler = s_handlerCache[type] as MemberwiseCopyHandler;
+ if (handler != null)
+ return handler;
+
+ FieldInfo[] fields = GetFields(type);
+ SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
+ {
+ DynamicMethod dm = new DynamicMethod(type.FullName + ".ShallowCopy", null, new Type[] { typeof(object), typeof(object) }, type.Module, true);
+ ILGenerator ilGen = dm.GetILGenerator();
+ ilGen.DeclareLocal(type);
+ ilGen.DeclareLocal(type);
+ ilGen.Emit(OpCodes.Ldarg_0);
+ ilGen.Emit(OpCodes.Castclass, type);
+ ilGen.Emit(OpCodes.Stloc_0);
+ ilGen.Emit(OpCodes.Ldarg_1);
+ ilGen.Emit(OpCodes.Castclass, type);
+ ilGen.Emit(OpCodes.Stloc_1);
+
+ foreach (FieldInfo field in fields)
+ {
+ ilGen.Emit(OpCodes.Ldloc_1);
+ ilGen.Emit(OpCodes.Ldloc_0);
+ ilGen.Emit(OpCodes.Ldfld, field);
+ ilGen.Emit(OpCodes.Stfld, field);
+ }
+ ilGen.Emit(OpCodes.Ret);
+
+ handler = (MemberwiseCopyHandler)dm.CreateDelegate(typeof(MemberwiseCopyHandler));
+ });
+
+ s_handlerCache[type] = handler;
+ }
+ return handler;
+ }
#else
private static void MemberwiseCopyInternal(object fromObject, object toObject, Type smallerType)
{
@@ -1369,156 +1384,157 @@ namespace Spring.Util
field.SetValue(toObject, field.GetValue(fromObject));
}
}
-#endif
-
- #region Field Cache Management for "MemberwiseCopy"
-
- private const BindingFlags FIELDBINDINGS =
- BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic;
-
- private static readonly Hashtable s_fieldCache = new Hashtable();
-
- private static FieldInfo[] GetFields(Type type)
- {
- lock (s_fieldCache)
- {
- FieldInfo[] fields = (FieldInfo[])s_fieldCache[type];
- if (fields == null)
- {
- ArrayList fieldList = new ArrayList();
- CollectFieldsRecursive(type, fieldList);
- fields = (FieldInfo[])fieldList.ToArray(typeof(FieldInfo));
- s_fieldCache[type] = fields;
- }
- return fields;
- }
- }
-
- private static void CollectFieldsRecursive(Type type, ArrayList fieldList)
- {
- if (type == typeof(object)) return;
-
- FieldInfo[] fields = type.GetFields(FIELDBINDINGS);
- fieldList.AddRange(fields);
- CollectFieldsRecursive(type.BaseType, fieldList);
- }
-
- #endregion Field Cache Management for "MemberwiseCopy"
-
-
- #region CustomAttributeBuilderBuilder inner class definition
-
- ///
- /// Creates a .
- ///
- /// Bruno Baia
- public class CustomAttributeBuilderBuilder
- {
- #region Fields
-
- private Type type;
- private ArrayList constructorArgs;
- private ArrayList namedProperties;
- private ArrayList propertyValues;
-
- #endregion
-
- #region Constructor(s) / Destructor
-
- ///
- /// Creates a new instance of the
- /// class.
- ///
- /// The custom attribute type.
- public CustomAttributeBuilderBuilder(Type attributeType)
- :
- this(attributeType, ObjectUtils.EmptyObjects)
- {
- }
-
- ///
- /// Creates a new instance of the
- /// class.
- ///
- /// The custom attribute type.
- /// The custom attribute constructor arguments.
- public CustomAttributeBuilderBuilder(Type attributeType, params object[] constructorArgs)
- {
- AssertUtils.ArgumentNotNull(attributeType, "attributeType");
- if (!typeof(Attribute).IsAssignableFrom(attributeType))
- {
- throw new ArgumentException(
- string.Format("[{0}] does not derive from the [System.Attribute] class.",
- attributeType.FullName));
- }
- this.type = attributeType;
- this.constructorArgs = new ArrayList(constructorArgs);
- this.namedProperties = new ArrayList();
- this.propertyValues = new ArrayList();
- }
-
- #endregion
-
- #region Public Methods
-
- ///
- /// Adds the specified values to the constructor argument list
- /// used to create the custom attribute.
- ///
- /// An array of argument values.
- public void AddContructorArgument(params object[] values)
- {
- this.constructorArgs.AddRange(values);
- }
-
- ///
- /// Adds a property value to the custom attribute.
- ///
- /// The property name.
- /// The property value.
- public void AddPropertyValue(string name, object value)
- {
- PropertyInfo propertyInfo = this.type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
- if (propertyInfo == null)
- {
- throw new ArgumentException(
- String.Format("The property '{0}' does no exist in the attribute '{1}'.", name, this.type));
- }
-
- this.namedProperties.Add(propertyInfo);
- this.propertyValues.Add(value);
- }
-
- ///
- /// Creates the .
- ///
- /// The created .
- public CustomAttributeBuilder Build()
- {
- object[] caArray = (object[])this.constructorArgs.ToArray(typeof(object));
- ConstructorInfo ci = this.type.GetConstructor(ReflectionUtils.GetTypes(caArray));
- if (ci == null && caArray.Length == 0)
- {
- ci = this.type.GetConstructors()[0];
- caArray = ReflectionUtils.GetDefaultValues(ReflectionUtils.GetParameterTypes(ci.GetParameters()));
- }
-
- if (namedProperties.Count > 0)
- {
- PropertyInfo[] npArray = (PropertyInfo[])this.namedProperties.ToArray(typeof(PropertyInfo));
- object[] pvArray = (object[])this.propertyValues.ToArray(typeof(object));
- return new CustomAttributeBuilder(ci, caArray, npArray, pvArray);
- }
- else
- {
- return new CustomAttributeBuilder(ci, caArray);
- }
-
- }
-
- #endregion
- }
-
- #endregion
- }
+#endif
+
+ #region Field Cache Management for "MemberwiseCopy"
+
+ private const BindingFlags FIELDBINDINGS =
+ BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic;
+
+ private static readonly Hashtable s_fieldCache = new Hashtable();
+
+ private static FieldInfo[] GetFields(Type type)
+ {
+ lock (s_fieldCache)
+ {
+ FieldInfo[] fields = (FieldInfo[])s_fieldCache[type];
+ if (fields == null)
+ {
+ ArrayList fieldList = new ArrayList();
+ CollectFieldsRecursive(type, fieldList);
+ fields = (FieldInfo[])fieldList.ToArray(typeof(FieldInfo));
+ s_fieldCache[type] = fields;
+ }
+ return fields;
+ }
+ }
+
+ private static void CollectFieldsRecursive(Type type, ArrayList fieldList)
+ {
+ if (type == typeof(object))
+ return;
+
+ FieldInfo[] fields = type.GetFields(FIELDBINDINGS);
+ fieldList.AddRange(fields);
+ CollectFieldsRecursive(type.BaseType, fieldList);
+ }
+
+ #endregion Field Cache Management for "MemberwiseCopy"
+
+
+ #region CustomAttributeBuilderBuilder inner class definition
+
+ ///
+ /// Creates a .
+ ///
+ /// Bruno Baia
+ public class CustomAttributeBuilderBuilder
+ {
+ #region Fields
+
+ private Type type;
+ private ArrayList constructorArgs;
+ private ArrayList namedProperties;
+ private ArrayList propertyValues;
+
+ #endregion
+
+ #region Constructor(s) / Destructor
+
+ ///
+ /// Creates a new instance of the
+ /// class.
+ ///
+ /// The custom attribute type.
+ public CustomAttributeBuilderBuilder(Type attributeType)
+ :
+ this(attributeType, ObjectUtils.EmptyObjects)
+ {
+ }
+
+ ///
+ /// Creates a new instance of the
+ /// class.
+ ///
+ /// The custom attribute type.
+ /// The custom attribute constructor arguments.
+ public CustomAttributeBuilderBuilder(Type attributeType, params object[] constructorArgs)
+ {
+ AssertUtils.ArgumentNotNull(attributeType, "attributeType");
+ if (!typeof(Attribute).IsAssignableFrom(attributeType))
+ {
+ throw new ArgumentException(
+ string.Format("[{0}] does not derive from the [System.Attribute] class.",
+ attributeType.FullName));
+ }
+ this.type = attributeType;
+ this.constructorArgs = new ArrayList(constructorArgs);
+ this.namedProperties = new ArrayList();
+ this.propertyValues = new ArrayList();
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Adds the specified values to the constructor argument list
+ /// used to create the custom attribute.
+ ///
+ /// An array of argument values.
+ public void AddContructorArgument(params object[] values)
+ {
+ this.constructorArgs.AddRange(values);
+ }
+
+ ///
+ /// Adds a property value to the custom attribute.
+ ///
+ /// The property name.
+ /// The property value.
+ public void AddPropertyValue(string name, object value)
+ {
+ PropertyInfo propertyInfo = this.type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
+ if (propertyInfo == null)
+ {
+ throw new ArgumentException(
+ String.Format("The property '{0}' does no exist in the attribute '{1}'.", name, this.type));
+ }
+
+ this.namedProperties.Add(propertyInfo);
+ this.propertyValues.Add(value);
+ }
+
+ ///
+ /// Creates the .
+ ///
+ /// The created .
+ public CustomAttributeBuilder Build()
+ {
+ object[] caArray = (object[])this.constructorArgs.ToArray(typeof(object));
+ ConstructorInfo ci = this.type.GetConstructor(ReflectionUtils.GetTypes(caArray));
+ if (ci == null && caArray.Length == 0)
+ {
+ ci = this.type.GetConstructors()[0];
+ caArray = ReflectionUtils.GetDefaultValues(ReflectionUtils.GetParameterTypes(ci.GetParameters()));
+ }
+
+ if (namedProperties.Count > 0)
+ {
+ PropertyInfo[] npArray = (PropertyInfo[])this.namedProperties.ToArray(typeof(PropertyInfo));
+ object[] pvArray = (object[])this.propertyValues.ToArray(typeof(object));
+ return new CustomAttributeBuilder(ci, caArray, npArray, pvArray);
+ }
+ else
+ {
+ return new CustomAttributeBuilder(ci, caArray);
+ }
+
+ }
+
+ #endregion
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/src/Spring/Spring.Core/Util/SecurityCritical.cs b/src/Spring/Spring.Core/Util/SecurityCritical.cs
new file mode 100644
index 00000000..152cad98
--- /dev/null
+++ b/src/Spring/Spring.Core/Util/SecurityCritical.cs
@@ -0,0 +1,50 @@
+#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
+
+using System.Runtime.CompilerServices;
+using System.Security;
+
+namespace Spring.Util
+{
+ ///
+ /// Utility class to be used from within this assembly for executing security critical code
+ /// NEVER EVER MAKE THIS PUBLIC!
+ ///
+ /// Erich Eichinger
+ internal class SecurityCritical
+ {
+ internal delegate void PrivilegedCallback();
+
+ [SecurityCritical, SecurityTreatAsSafe]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ internal static void ExecutePrivileged(IStackWalk permission, PrivilegedCallback callback)
+ {
+ permission.Assert();
+ try
+ {
+ callback();
+ }
+ finally
+ {
+ CodeAccessPermission.RevertAssert();
+ }
+ }
+ }
+}
diff --git a/src/Spring/Spring.Core/Util/SystemUtils.cs b/src/Spring/Spring.Core/Util/SystemUtils.cs
index ddba4339..7546f0f8 100644
--- a/src/Spring/Spring.Core/Util/SystemUtils.cs
+++ b/src/Spring/Spring.Core/Util/SystemUtils.cs
@@ -21,10 +21,8 @@
#region Imports
using System;
-using System.Configuration;
-using System.Reflection;
+using System.Reflection;
using System.Threading;
-using System.Xml;
#endregion
diff --git a/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs b/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs
index 82c39c37..6098e08e 100644
--- a/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs
+++ b/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs
@@ -233,7 +233,7 @@ namespace Spring.EnterpriseServices
}
///
- /// Use Spring context to configure the serviced components.
+ /// Use Spring context to configure the serviced components within COM.
///
public bool UseSpring
{
diff --git a/src/Spring/Spring.Web/AssemblyInfo.cs b/src/Spring/Spring.Web/AssemblyInfo.cs
index bf214506..b9a53b12 100644
--- a/src/Spring/Spring.Web/AssemblyInfo.cs
+++ b/src/Spring/Spring.Web/AssemblyInfo.cs
@@ -1,7 +1,24 @@
using System.Reflection;
+using System.Security;
using System.Web.UI;
[assembly: AssemblyTitle("Spring.Web")]
[assembly: AssemblyDescription("Interfaces and classes that provide web application support in Spring.Net")]
[assembly: TagPrefix("Spring.Web.UI.Controls", "spring")]
-//[assembly: AssemblyKeyFile(@"C:\users\aseovic\projects\OpenSource\Spring.Net\Spring.Net.PrivateKey.keys")]
\ No newline at end of file
+//[assembly: AssemblyKeyFile(@"C:\users\aseovic\projects\OpenSource\Spring.Net\Spring.Net.PrivateKey.keys")]
+[assembly: AllowPartiallyTrustedCallers]
+[assembly: SecurityCritical]
+
+#if NET_1_0 || NET_1_1
+namespace System.Security
+{
+ ///
+ ///
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method)]
+ internal class SecurityCriticalAttribute : Attribute
+ { }
+ [AttributeUsage(AttributeTargets.Method)]
+ internal class SecurityTreatAsSafeAttribute : Attribute
+ { }
+}
+#endif
diff --git a/src/Spring/Spring.Web/Context/Support/WebSupportModule.cs b/src/Spring/Spring.Web/Context/Support/WebSupportModule.cs
index 11ebe2ea..c2667c2b 100644
--- a/src/Spring/Spring.Web/Context/Support/WebSupportModule.cs
+++ b/src/Spring/Spring.Web/Context/Support/WebSupportModule.cs
@@ -23,6 +23,8 @@
using System;
using System.Globalization;
using System.Reflection;
+using System.Security;
+using System.Security.Permissions;
using System.Web;
using System.Web.Caching;
using System.Web.SessionState;
@@ -80,8 +82,8 @@ namespace Spring.Context.Support
private static CacheItemRemovedCallback s_originalCallback;
#if NET_2_0
// required to enable accessing HttpContext.Request during IHttpModule.Init() in integrated mode
- private static readonly FieldInfo fiHideRequestResponse = typeof(HttpContext).GetField("HideRequestResponse", BindingFlags.Instance|BindingFlags.NonPublic);
- private static readonly SafeField ContextHideRequestResponse = (fiHideRequestResponse!=null)?new SafeField(fiHideRequestResponse):null;
+ private static readonly FieldInfo fiHideRequestResponse;
+ private static readonly SafeField ContextHideRequestResponse;
#endif
///
@@ -95,6 +97,20 @@ namespace Spring.Context.Support
static WebSupportModule()
{
s_log = LogManager.GetLogger(typeof(WebSupportModule));
+#if NET_2_0
+ // required to enable accessing HttpContext.Request during IHttpModule.Init() in integrated mode
+ ContextHideRequestResponse = null;
+ try
+ {
+ fiHideRequestResponse = typeof(HttpContext).GetField("HideRequestResponse", BindingFlags.Instance|BindingFlags.NonPublic);
+// fiHideRequestResponse.SetValue(HttpContext.Current, false);
+ ContextHideRequestResponse = (fiHideRequestResponse!=null)?new SafeField(fiHideRequestResponse):null;
+ }
+ catch(SecurityException sec)
+ {
+ s_log.Warn(string.Format("failed reflecting field HttpContext.HideRequestResponse due to security restrictions {0}", sec));
+ }
+#endif
// register additional resource handler
ResourceHandlerRegistry.RegisterResourceHandler(WebUtils.DEFAULT_RESOURCE_PROTOCOL, typeof(WebResource));
diff --git a/src/Spring/Spring.Web/Spring.Web.2008.csproj b/src/Spring/Spring.Web/Spring.Web.2008.csproj
index 8897b40b..4b0b17b7 100644
--- a/src/Spring/Spring.Web/Spring.Web.2008.csproj
+++ b/src/Spring/Spring.Web/Spring.Web.2008.csproj
@@ -23,6 +23,8 @@
v2.0
+ true
+ ..\..\..\Spring.Net.snk
..\..\..\build\VS.Net.2008\Spring.Web\Debug\
@@ -124,6 +126,7 @@
Code
+
diff --git a/src/Spring/Spring.Web/Util/SecurityCritical.cs b/src/Spring/Spring.Web/Util/SecurityCritical.cs
new file mode 100644
index 00000000..3248b7b0
--- /dev/null
+++ b/src/Spring/Spring.Web/Util/SecurityCritical.cs
@@ -0,0 +1,66 @@
+#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
+
+using System.Runtime.CompilerServices;
+using System.Security;
+
+namespace Spring.Util
+{
+ ///
+ /// Utility class to be used from within this assembly for executing security critical code
+ /// NEVER EVER MAKE THIS PUBLIC!
+ ///
+ /// Erich Eichinger
+ internal class SecurityCritical
+ {
+ internal delegate void PrivilegedCallback();
+
+ [SecurityCritical, SecurityTreatAsSafe]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ internal static void ExecutePrivileged(IStackWalk permission, PrivilegedCallback callback)
+ {
+ permission.Assert();
+ try
+ {
+ callback();
+ }
+ finally
+ {
+ CodeAccessPermission.RevertAssert();
+ }
+ }
+
+ // internal delegate TResult PrivilegedCallback();
+ //
+ // [SecurityCritical, SecurityTreatAsSafe]
+ // internal static TResult ExecutePrivileged(IStackWalk permission, PrivilegedCallback callback)
+ // {
+ // permission.Assert();
+ // try
+ // {
+ // return callback();
+ // }
+ // finally
+ // {
+ // CodeAccessPermission.RevertAssert();
+ // }
+ // }
+ }
+}
diff --git a/src/Spring/Spring.Web/Web/Support/AbstractHandlerFactory.cs b/src/Spring/Spring.Web/Web/Support/AbstractHandlerFactory.cs
index 9457e207..ed2c9eb8 100644
--- a/src/Spring/Spring.Web/Web/Support/AbstractHandlerFactory.cs
+++ b/src/Spring/Spring.Web/Web/Support/AbstractHandlerFactory.cs
@@ -23,6 +23,8 @@
using System;
using System.Collections;
using System.IO;
+using System.Security;
+using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using Common.Logging;
@@ -94,7 +96,25 @@ namespace Spring.Web.Support
///
/// Holds an instance of the instrinsic System.Web.UI.SimpleHandlerFactory
///
- private static IHttpHandlerFactory s_simpleHandlerFactory;
+ private static readonly IHttpHandlerFactory s_simpleHandlerFactory;
+
+ static AbstractHandlerFactory()
+ {
+ PrivilegedCommand cmd = new PrivilegedCommand();
+ SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), new SecurityCritical.PrivilegedCallback(cmd.Execute));
+ s_simpleHandlerFactory = cmd.Result;
+ }
+
+ private class PrivilegedCommand
+ {
+ public IHttpHandlerFactory Result = null;
+
+ public void Execute()
+ {
+ Type simpleHandlerFactoryType = typeof(IHttpHandler).Assembly.GetType("System.Web.UI.SimpleHandlerFactory");
+ Result = (IHttpHandlerFactory)Activator.CreateInstance(simpleHandlerFactoryType, true);
+ }
+ }
///
/// Get the global instance of System.Web.UI.SimpleHandlerFactory
@@ -110,8 +130,6 @@ namespace Spring.Web.Support
// instantiate lazy to avoid security exceptions in restricted reflection environments
if (s_simpleHandlerFactory == null)
{
- Type simpleHandlerFactoryType = typeof(IHttpHandler).Assembly.GetType("System.Web.UI.SimpleHandlerFactory");
- s_simpleHandlerFactory = (IHttpHandlerFactory)Activator.CreateInstance(simpleHandlerFactoryType, true);
}
return s_simpleHandlerFactory;
}
@@ -128,7 +146,7 @@ namespace Spring.Web.Support
///
protected AbstractHandlerFactory()
{
- this.Log = LogManager.GetLogger( this.GetType() );
+ this.Log = LogManager.GetLogger(this.GetType());
}
///
@@ -149,14 +167,14 @@ namespace Spring.Web.Support
/// A new object that processes
/// the request.
///
- public virtual IHttpHandler GetHandler( HttpContext context, string requestType, string url, string physicalPath )
+ public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string url, string physicalPath)
{
bool isDebug = Log.IsDebugEnabled;
#region Instrumentation
if (isDebug)
- Log.Debug( string.Format( "GetHandler():resolving url '{0}'", url ) );
+ Log.Debug(string.Format("GetHandler():resolving url '{0}'", url));
#endregion
@@ -172,7 +190,7 @@ namespace Spring.Web.Support
if (isDebug)
{
- Log.Debug( string.Format( "GetHandler():resolved url '{0}' from reusable handler cache", url ) );
+ Log.Debug(string.Format("GetHandler():resolved url '{0}' from reusable handler cache", url));
}
#endregion
@@ -187,7 +205,7 @@ namespace Spring.Web.Support
{
IConfigurableApplicationContext appContext = GetCheckedApplicationContext(url);
- handler = CreateHandlerInstance( appContext, context, requestType, url, physicalPath );
+ handler = CreateHandlerInstance(appContext, context, requestType, url, physicalPath);
ApplyDependencyInjectionInfrastructure(handler, appContext);
@@ -207,7 +225,7 @@ namespace Spring.Web.Support
///
/// The object to release.
///
- public virtual void ReleaseHandler( IHttpHandler handler )
+ public virtual void ReleaseHandler(IHttpHandler handler)
{ }
///
@@ -219,7 +237,7 @@ namespace Spring.Web.Support
/// The requested .
/// The physical path of the requested resource.
/// A handler instance for processing the current request.
- protected abstract IHttpHandler CreateHandlerInstance( IConfigurableApplicationContext appContext, HttpContext context, string requestType, string rawUrl, string physicalPath );
+ protected abstract IHttpHandler CreateHandlerInstance(IConfigurableApplicationContext appContext, HttpContext context, string requestType, string rawUrl, string physicalPath);
///
/// Get the application context instance corresponding to the given absolute url and checks
@@ -236,16 +254,16 @@ namespace Spring.Web.Support
///
/// Calls to obtain a context instance.
///
- protected IConfigurableApplicationContext GetCheckedApplicationContext( string url )
+ protected IConfigurableApplicationContext GetCheckedApplicationContext(string url)
{
- IApplicationContext appContext = GetContext( url );
+ IApplicationContext appContext = GetContext(url);
if (appContext == null)
{
- throw new ArgumentException( string.Format( "no application context for virtual path '{0}'", url ) );
+ throw new ArgumentException(string.Format("no application context for virtual path '{0}'", url));
}
if (!(appContext is IConfigurableApplicationContext))
{
- throw new InvalidOperationException( string.Format( "application context '{0}' for virtual path '{1}' must implement IConfigurableApplicationContext", appContext.ToString(), url ) );
+ throw new InvalidOperationException(string.Format("application context '{0}' for virtual path '{1}' must implement IConfigurableApplicationContext", appContext.ToString(), url));
}
return (IConfigurableApplicationContext)appContext;
}
@@ -259,9 +277,9 @@ namespace Spring.Web.Support
/// Subclasses may override this method to change the context source.
/// By default, is used for obtaining context instances.
///
- protected virtual IApplicationContext GetContext( string virtualPath )
+ protected virtual IApplicationContext GetContext(string virtualPath)
{
- return WebApplicationContext.GetContext( virtualPath );
+ return WebApplicationContext.GetContext(virtualPath);
}
///
@@ -276,27 +294,27 @@ namespace Spring.Web.Support
///
/// Resolve an object definition by url.
///
- protected internal static NamedObjectDefinition FindWebObjectDefinition( string appRelativeVirtualPath, IConfigurableListableObjectFactory objectFactory )
+ protected internal static NamedObjectDefinition FindWebObjectDefinition(string appRelativeVirtualPath, IConfigurableListableObjectFactory objectFactory)
{
- ILog Log = LogManager.GetLogger( typeof( AbstractHandlerFactory ) );
+ ILog Log = LogManager.GetLogger(typeof(AbstractHandlerFactory));
bool isDebug = Log.IsDebugEnabled;
// lookup definition using app-relative url
if (isDebug)
- Log.Debug( string.Format( "GetHandler():looking up definition for app-relative url '{0}'", appRelativeVirtualPath ) );
+ Log.Debug(string.Format("GetHandler():looking up definition for app-relative url '{0}'", appRelativeVirtualPath));
string objectDefinitionName = appRelativeVirtualPath;
- IObjectDefinition pageDefinition = objectFactory.GetObjectDefinition( appRelativeVirtualPath, true );
+ IObjectDefinition pageDefinition = objectFactory.GetObjectDefinition(appRelativeVirtualPath, true);
if (pageDefinition == null)
{
// try using pagename+extension and pagename only
- string pageExtension = Path.GetExtension( appRelativeVirtualPath );
- string pageName = WebUtils.GetPageName( appRelativeVirtualPath );
+ string pageExtension = Path.GetExtension(appRelativeVirtualPath);
+ string pageName = WebUtils.GetPageName(appRelativeVirtualPath);
// only looks in the specified object factory -- it will *not* search parent contexts
- pageDefinition = objectFactory.GetObjectDefinition( pageName + pageExtension, false );
+ pageDefinition = objectFactory.GetObjectDefinition(pageName + pageExtension, false);
if (pageDefinition == null)
{
- pageDefinition = objectFactory.GetObjectDefinition( pageName, false );
+ pageDefinition = objectFactory.GetObjectDefinition(pageName, false);
if (pageDefinition != null)
objectDefinitionName = pageName;
}
@@ -308,21 +326,21 @@ namespace Spring.Web.Support
if (pageDefinition != null)
{
if (isDebug)
- Log.Debug( string.Format( "GetHandler():found definition for page-name '{0}'", objectDefinitionName ) );
+ Log.Debug(string.Format("GetHandler():found definition for page-name '{0}'", objectDefinitionName));
}
else
{
if (isDebug)
- Log.Debug( string.Format( "GetHandler():no definition found for page-name '{0}'", pageName ) );
+ Log.Debug(string.Format("GetHandler():no definition found for page-name '{0}'", pageName));
}
}
else
{
if (isDebug)
- Log.Debug( string.Format( "GetHandler():found definition for page-url '{0}'", appRelativeVirtualPath ) );
+ Log.Debug(string.Format("GetHandler():found definition for page-url '{0}'", appRelativeVirtualPath));
}
- return (pageDefinition == null) ? (NamedObjectDefinition)null : new NamedObjectDefinition( objectDefinitionName, pageDefinition );
+ return (pageDefinition == null) ? (NamedObjectDefinition)null : new NamedObjectDefinition(objectDefinitionName, pageDefinition);
}
///
@@ -338,8 +356,8 @@ namespace Spring.Web.Support
}
else
{
- if ( (handler is ISupportsWebDependencyInjection)
- && (((ISupportsWebDependencyInjection)handler).DefaultApplicationContext == null) )
+ if ((handler is ISupportsWebDependencyInjection)
+ && (((ISupportsWebDependencyInjection)handler).DefaultApplicationContext == null))
{
((ISupportsWebDependencyInjection)handler).DefaultApplicationContext = applicationContext;
}
diff --git a/src/Spring/Spring.Web/Web/Support/ControlAccessor.cs b/src/Spring/Spring.Web/Web/Support/ControlAccessor.cs
index 3635cd91..8a8e0f78 100644
--- a/src/Spring/Spring.Web/Web/Support/ControlAccessor.cs
+++ b/src/Spring/Spring.Web/Web/Support/ControlAccessor.cs
@@ -22,9 +22,11 @@ using System;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
+using System.Security;
+using System.Security.Permissions;
using System.Web.UI;
using Spring.Reflection.Dynamic;
-using Spring.Web.Support;
+using Spring.Util;
#endregion
@@ -36,26 +38,20 @@ namespace Spring.Web.Support
/// Erich Eichinger
internal class ControlAccessor
{
- private static readonly MethodInfo s_miClear = GetMethod("Clear");
- private static MethodInfo GetMethod(string name)
- {
- return typeof(Control).GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
- }
- private static FieldInfo GetField(string name)
- {
- return typeof(Control).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
- }
-
private delegate ControlCollection CreateControlCollectionDelegate(Control target);
private delegate void AddedControlDelegate(Control target, Control control, int index);
private delegate void RemovedControlDelegate(Control target, Control control);
private delegate void VoidMethodDelegate(Control target);
+ private static readonly MethodInfo s_miClear;
+ private static readonly SafeField ControlsArrayField;
+
#if NET_2_0
- private static readonly CreateControlCollectionDelegate BaseCreateControlCollection = (CreateControlCollectionDelegate) Delegate.CreateDelegate(typeof(CreateControlCollectionDelegate), GetMethod("CreateControlCollection"));
- private static readonly AddedControlDelegate BaseAddedControl = (AddedControlDelegate) Delegate.CreateDelegate(typeof (AddedControlDelegate), GetMethod("AddedControl"));
- private static readonly RemovedControlDelegate BaseRemovedControl = (RemovedControlDelegate) Delegate.CreateDelegate(typeof (RemovedControlDelegate), GetMethod("RemovedControl"));
- private static readonly VoidMethodDelegate BaseClearNamingContainer = (VoidMethodDelegate) Delegate.CreateDelegate(typeof (VoidMethodDelegate), GetMethod("ClearNamingContainer"));
+ private static readonly CreateControlCollectionDelegate BaseCreateControlCollection;
+ private static readonly AddedControlDelegate BaseAddedControl;
+ private static readonly RemovedControlDelegate BaseRemovedControl;
+ private static readonly VoidMethodDelegate BaseClearNamingContainer;
+
#else
private class DynamicMethodWrapper
{
@@ -117,6 +113,56 @@ namespace Spring.Web.Support
private static readonly VoidMethodDelegate BaseClearNamingContainer = DynamicMethodWrapper.ClearNamingContainer(GetMethod("ClearNamingContainer"));
#endif
+ static ControlAccessor()
+ {
+ SafeField fldControls = null;
+ MethodInfo fnClear = null;
+#if NET_2_0
+ SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
+ {
+#endif
+ fnClear = GetMethod("Clear");
+ fldControls = new SafeField(typeof(ControlCollection).GetField("_controls", BindingFlags.Instance | BindingFlags.NonPublic));
+#if NET_2_0
+ });
+#endif
+ s_miClear = fnClear;
+ ControlsArrayField = fldControls;
+
+#if NET_2_0
+ CreateControlCollectionDelegate fnBaseCreateControlCollection = null;
+ AddedControlDelegate fnBaseAddedControl = null;
+ RemovedControlDelegate fnBaseRemovedControl = null;
+ VoidMethodDelegate fnBaseClearNamingContainer = null;
+#if NET_2_0
+ SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
+ {
+#endif
+ fnBaseCreateControlCollection = (CreateControlCollectionDelegate)Delegate.CreateDelegate(typeof(CreateControlCollectionDelegate), GetMethod("CreateControlCollection"));
+ fnBaseAddedControl = (AddedControlDelegate)Delegate.CreateDelegate(typeof(AddedControlDelegate), GetMethod("AddedControl"));
+ fnBaseRemovedControl = (RemovedControlDelegate)Delegate.CreateDelegate(typeof(RemovedControlDelegate), GetMethod("RemovedControl"));
+ fnBaseClearNamingContainer = (VoidMethodDelegate)Delegate.CreateDelegate(typeof(VoidMethodDelegate), GetMethod("ClearNamingContainer"));
+#if NET_2_0
+ });
+#endif
+ BaseCreateControlCollection = fnBaseCreateControlCollection;
+ BaseAddedControl = fnBaseAddedControl;
+ BaseRemovedControl = fnBaseRemovedControl;
+ BaseClearNamingContainer = fnBaseClearNamingContainer;
+#endif
+
+ }
+
+ private static MethodInfo GetMethod(string name)
+ {
+ return typeof(Control).GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+ }
+ private static FieldInfo GetField(string name)
+ {
+ return typeof(Control).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+ }
+
+
private readonly Control _targetControl;
///
@@ -187,7 +233,6 @@ namespace Spring.Web.Support
}
}
- private static readonly SafeField ControlsArrayField = new SafeField(typeof(ControlCollection).GetField("_controls", BindingFlags.Instance|BindingFlags.NonPublic));
public void SetControlAt(Control control, int index)
{
Control[] controls = (Control[]) ControlsArrayField.GetValue(this.Controls);
@@ -217,24 +262,29 @@ namespace Spring.Web.Support
MethodInfo ensureOccasionalFields = GetMethod("EnsureOccasionalFields");
FieldInfo controls = occasionalFields.FieldType.GetField("Controls");
- System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("get_Controls", typeof(ControlCollection), new Type[] { typeof(Control) }, typeof(Control).Module, true);
- ILGenerator il = dm.GetILGenerator();
- Label occFieldsNull = il.DefineLabel();
- Label retControls = il.DefineLabel();
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, occasionalFields);
- il.Emit(OpCodes.Brfalse_S, occFieldsNull);
- il.MarkLabel(retControls);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, occasionalFields);
- il.Emit(OpCodes.Ldfld, controls);
- il.Emit(OpCodes.Ret);
- il.MarkLabel(occFieldsNull);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Call, ensureOccasionalFields);
- il.Emit(OpCodes.Br, retControls);
+ GetControlsDelegate handler = null;
- return (GetControlsDelegate) dm.CreateDelegate(typeof(GetControlsDelegate));
+ SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
+ {
+ System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("get_Controls", typeof(ControlCollection), new Type[] { typeof(Control) }, typeof(Control).Module, true);
+ ILGenerator il = dm.GetILGenerator();
+ Label occFieldsNull = il.DefineLabel();
+ Label retControls = il.DefineLabel();
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldfld, occasionalFields);
+ il.Emit(OpCodes.Brfalse_S, occFieldsNull);
+ il.MarkLabel(retControls);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldfld, occasionalFields);
+ il.Emit(OpCodes.Ldfld, controls);
+ il.Emit(OpCodes.Ret);
+ il.MarkLabel(occFieldsNull);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Call, ensureOccasionalFields);
+ il.Emit(OpCodes.Br, retControls);
+ handler = (GetControlsDelegate) dm.CreateDelegate(typeof(GetControlsDelegate));
+ });
+ return handler;
}
private static SetControlsDelegate GetSetControlsDelegate()
@@ -243,53 +293,30 @@ namespace Spring.Web.Support
MethodInfo ensureOccasionalFields = GetMethod("EnsureOccasionalFields");
FieldInfo controls = occasionalFields.FieldType.GetField("Controls");
- System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("set_Controls", null, new Type[] { typeof(Control), typeof(ControlCollection) }, typeof(Control).Module, true);
- ILGenerator il = dm.GetILGenerator();
- Label occFieldsNull = il.DefineLabel();
- Label setControls = il.DefineLabel();
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, occasionalFields);
- il.Emit(OpCodes.Brfalse_S, occFieldsNull);
- il.MarkLabel(setControls);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, occasionalFields);
- il.Emit(OpCodes.Ldarg_1);
- il.Emit(OpCodes.Stfld, controls);
- il.Emit(OpCodes.Ret);
- il.MarkLabel(occFieldsNull);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Call, ensureOccasionalFields);
- il.Emit(OpCodes.Br, setControls);
-
- return (SetControlsDelegate) dm.CreateDelegate(typeof(SetControlsDelegate));
+ SetControlsDelegate handler = null;
+ SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
+ {
+ System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("set_Controls", null, new Type[] { typeof(Control), typeof(ControlCollection) }, typeof(Control).Module, true);
+ ILGenerator il = dm.GetILGenerator();
+ Label occFieldsNull = il.DefineLabel();
+ Label setControls = il.DefineLabel();
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldfld, occasionalFields);
+ il.Emit(OpCodes.Brfalse_S, occFieldsNull);
+ il.MarkLabel(setControls);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldfld, occasionalFields);
+ il.Emit(OpCodes.Ldarg_1);
+ il.Emit(OpCodes.Stfld, controls);
+ il.Emit(OpCodes.Ret);
+ il.MarkLabel(occFieldsNull);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Call, ensureOccasionalFields);
+ il.Emit(OpCodes.Br, setControls);
+ handler = (SetControlsDelegate) dm.CreateDelegate(typeof(SetControlsDelegate));
+ });
+ return handler;
}
-
-// private static readonly Type s_tOccasionalFields = typeof(Control).GetNestedType("OccasionalFields", BindingFlags.NonPublic);
-//
-// private static readonly VoidMethodDelegate EnsureOccasionalFields = (VoidMethodDelegate) Delegate.CreateDelegate(typeof (VoidMethodDelegate), GetMethod("EnsureOccasionalFields"));
-// private static readonly IDynamicField _occasionalFields = SafeField.CreateFrom(GetField("_occasionalFields"));
-// private static readonly IDynamicField _controls = SafeField.CreateFrom(s_tOccasionalFields.GetField("Controls"));
-//
-// private ControlCollection GetChildControlCollection()
-// {
-// // we *must not* simply call control.Controls here!
-// // Some controls (e.g. Repeater overload this property and call Control.EnsureChildControls()
-// // which causes Control.ChildControlsCreated flag to be set and prevents children from being created after loading viewstate!
-//
-// EnsureOccasionalFields(_targetControl);
-//
-// object occasionalFields = _occasionalFields.GetValue(_targetControl);
-// object childControls = _controls.GetValue(occasionalFields);
-// return (ControlCollection) childControls;
-// }
-//
-// private void SetChildControlCollection( ControlCollection controls )
-// {
-// EnsureOccasionalFields(_targetControl);
-//
-// object occasionalFields = _occasionalFields.GetValue(_targetControl);
-// _controls.SetValue(occasionalFields, controls);
-// }
#else
private static readonly IDynamicField fControls = SafeField.CreateFrom(GetField("_controls"));
diff --git a/src/Spring/Spring.Web/Web/Support/ControlCollectionAccessor.cs b/src/Spring/Spring.Web/Web/Support/ControlCollectionAccessor.cs
index ab64582a..6ce037c1 100644
--- a/src/Spring/Spring.Web/Web/Support/ControlCollectionAccessor.cs
+++ b/src/Spring/Spring.Web/Web/Support/ControlCollectionAccessor.cs
@@ -20,8 +20,11 @@
using System;
using System.Reflection;
+using System.Security;
+using System.Security.Permissions;
using System.Web.UI;
using Spring.Reflection.Dynamic;
+using Spring.Util;
#endregion
@@ -33,12 +36,25 @@ namespace Spring.Web.Support
/// Erich Eichinger
internal class ControlCollectionAccessor
{
-#if MONO_2_0
- private static readonly IDynamicField _owner = new SafeField(typeof (ControlCollection).GetField("owner", BindingFlags.Instance | BindingFlags.NonPublic));
-#else
- private static readonly IDynamicField _owner = new SafeField(typeof (ControlCollection).GetField("_owner", BindingFlags.Instance | BindingFlags.NonPublic));
+ private static readonly IDynamicField _owner;
+ static ControlCollectionAccessor()
+ {
+ IDynamicField owner = null;
+#if NET_2_0
+ SecurityCritical.ExecutePrivileged( new PermissionSet(PermissionState.Unrestricted), delegate
+ {
#endif
-
+#if MONO_2_0
+ owner = new SafeField(typeof (ControlCollection).GetField("owner", BindingFlags.Instance | BindingFlags.NonPublic));
+#else
+ owner = new SafeField(typeof (ControlCollection).GetField("_owner", BindingFlags.Instance | BindingFlags.NonPublic));
+#endif
+#if NET_2_0
+ });
+#endif
+ _owner = owner;
+ }
+
private readonly ControlCollection _controls;
private readonly Type _controlsType;
diff --git a/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionStrategy.cs b/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionStrategy.cs
index e285800b..326d3f9e 100644
--- a/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionStrategy.cs
+++ b/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionStrategy.cs
@@ -133,14 +133,13 @@ namespace Spring.Web.Support
factoryMethod = (CreateControlCollectionDelegate)s_collectionFactoryCache[ownerType];
if (factoryMethod == null)
{
- Type interceptedCollectionType =
- GetInterceptedCollectionType(collectionType, WebDependencyInjectionUtils.InjectDependenciesRecursive);
+ Type interceptedCollectionType = GetInterceptedCollectionType(
+ collectionType
+ , WebDependencyInjectionUtils.InjectDependenciesRecursive
+ );
- ConstructorInfo ctor =
- interceptedCollectionType.GetConstructor(new Type[] { typeof(Control) });
- DynamicMethod dm =
- new System.Reflection.Emit.DynamicMethod(string.Empty, typeof(ControlCollection),
- new Type[] { typeof(Control) });
+ ConstructorInfo ctor = interceptedCollectionType.GetConstructor(new Type[] { typeof(Control) });
+ DynamicMethod dm = new DynamicMethod(string.Empty, typeof(ControlCollection), new Type[] { typeof(Control) });
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, ctor);
diff --git a/src/Spring/Spring.Web/Web/Support/LocalResourceManager.cs b/src/Spring/Spring.Web/Web/Support/LocalResourceManager.cs
index fb74d81f..07f51361 100644
--- a/src/Spring/Spring.Web/Web/Support/LocalResourceManager.cs
+++ b/src/Spring/Spring.Web/Web/Support/LocalResourceManager.cs
@@ -24,6 +24,8 @@ using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
+using System.Security;
+using System.Security.Permissions;
using System.Web;
using System.Web.Compilation;
using System.Web.UI;
@@ -46,17 +48,33 @@ namespace Spring.Web.Support
internal abstract class LocalResourceManager : ResourceManager
{
private delegate IResourceProvider GetResourceProviderDelegate( TemplateControl control );
- private static readonly GetResourceProviderDelegate getLocalResourceProvider = (GetResourceProviderDelegate)Delegate.CreateDelegate( typeof( GetResourceProviderDelegate ), typeof( ResourceExpressionBuilder ).GetMethod( "GetLocalResourceProvider", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof( TemplateControl ) }, null ) );
- private static readonly Type LocalResXResourceProviderFactoryType = typeof( IResourceProvider ).Assembly.GetType( "System.Web.Compilation.ResXResourceProviderFactory", true );
- private static readonly Type LocalResXResourceProviderType = typeof( IResourceProvider ).Assembly.GetType( "System.Web.Compilation.LocalResXResourceProvider", true );
- private static readonly ResourceProviderFactory LocalResXResourceProviderFactory = (ResourceProviderFactory)Activator.CreateInstance( LocalResXResourceProviderFactoryType, true );
- private static readonly SafeMethod fnGetLocalResourceAssembly = new SafeMethod( LocalResXResourceProviderType.GetMethod( "GetLocalResourceAssembly", BindingFlags.Instance | BindingFlags.NonPublic ) );
+ private static readonly GetResourceProviderDelegate getLocalResourceProvider;
+ private static readonly Type LocalResXResourceProviderFactoryType;
+ private static readonly Type LocalResXResourceProviderType;
+ private static readonly ResourceProviderFactory LocalResXResourceProviderFactory;
+ private static readonly SafeMethod fnGetLocalResourceAssembly;
///
/// Avoid beforeFieldInit
///
static LocalResourceManager()
- { }
+ {
+ LocalResXResourceProviderFactoryType = typeof(IResourceProvider).Assembly.GetType("System.Web.Compilation.ResXResourceProviderFactory", true);
+ LocalResXResourceProviderType = typeof(IResourceProvider).Assembly.GetType("System.Web.Compilation.LocalResXResourceProvider", true);
+
+ GetResourceProviderDelegate fnGetResourceProvider = null;
+ ResourceProviderFactory rpf = null;
+ SafeMethod glra = null;
+ SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
+ {
+ fnGetResourceProvider = (GetResourceProviderDelegate)Delegate.CreateDelegate(typeof(GetResourceProviderDelegate), typeof(ResourceExpressionBuilder).GetMethod("GetLocalResourceProvider", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(TemplateControl) }, null));
+ rpf = (ResourceProviderFactory)Activator.CreateInstance( LocalResXResourceProviderFactoryType, true );
+ glra = new SafeMethod(LocalResXResourceProviderType.GetMethod("GetLocalResourceAssembly", BindingFlags.Instance | BindingFlags.NonPublic));
+ });
+ getLocalResourceProvider = fnGetResourceProvider;
+ LocalResXResourceProviderFactory = rpf;
+ fnGetLocalResourceAssembly = glra;
+ }
internal static ResourceManager GetLocalResourceManager( TemplateControl control )
{
diff --git a/src/Spring/Spring.Web/Web/Support/PageHandlerFactory.cs b/src/Spring/Spring.Web/Web/Support/PageHandlerFactory.cs
index 25ae6176..58146626 100644
--- a/src/Spring/Spring.Web/Web/Support/PageHandlerFactory.cs
+++ b/src/Spring/Spring.Web/Web/Support/PageHandlerFactory.cs
@@ -74,8 +74,6 @@ namespace Spring.Web.Support
/// Instance of the IHttpHandler object that should be used to process request.
public override IHttpHandler GetHandler(HttpContext context, string requestType, string url, string physicalPath)
{
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
-
return base.GetHandler(context, requestType, url, physicalPath);
}
diff --git a/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionOwnerProxy.cs b/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionOwnerProxy.cs
index 937215d1..083b436a 100644
--- a/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionOwnerProxy.cs
+++ b/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionOwnerProxy.cs
@@ -19,10 +19,13 @@
#region Imports
using System.Reflection;
+using System.Security;
+using System.Security.Permissions;
using System.Web.UI;
using Spring.Context;
using Spring.Context.Support;
using Spring.Reflection.Dynamic;
+using Spring.Util;
using Spring.Web.Support;
#endregion
@@ -90,7 +93,17 @@ namespace Spring.Web.Support
, INamingContainer
{
#if NET_2_0
- private static readonly SafeField refOccasionalFields = new SafeField(typeof(Control).GetField("_occasionalFields", BindingFlags.Instance|BindingFlags.NonPublic));
+ private static readonly SafeField refOccasionalFields;
+
+ static NamingContainerSupportsWebDependencyInjectionOwnerProxy()
+ {
+ SafeField fld = null;
+ SecurityCritical.ExecutePrivileged( new PermissionSet(PermissionState.Unrestricted), delegate
+ {
+ fld = new SafeField(typeof(Control).GetField("_occasionalFields", BindingFlags.Instance | BindingFlags.NonPublic));
+ });
+ refOccasionalFields = fld;
+ }
#endif
public NamingContainerSupportsWebDependencyInjectionOwnerProxy(IApplicationContext defaultApplicationContext, Control targetControl) : base(defaultApplicationContext, targetControl)
diff --git a/src/Spring/Spring.Web/Web/UI/Controls/Panel.cs b/src/Spring/Spring.Web/Web/UI/Controls/Panel.cs
index 0a52c5d9..fb037db5 100644
--- a/src/Spring/Spring.Web/Web/UI/Controls/Panel.cs
+++ b/src/Spring/Spring.Web/Web/UI/Controls/Panel.cs
@@ -174,6 +174,13 @@ namespace Spring.Web.UI.Controls
}
}
+ ///
+ /// Expose the context of this panel for medium trust safe access in e.g. .
+ ///
+ public new virtual HttpContext Context
+ {
+ get { return base.Context; }
+ }
#region Dependency Injection Support
private IApplicationContext _defaultApplicationContext;
diff --git a/src/Spring/Spring.Web/Web/UI/Page.cs b/src/Spring/Spring.Web/Web/UI/Page.cs
index a8fba0f6..8fcb7302 100644
--- a/src/Spring/Spring.Web/Web/UI/Page.cs
+++ b/src/Spring/Spring.Web/Web/UI/Page.cs
@@ -740,6 +740,8 @@ namespace Spring.Web.UI
set { this.sharedState = value; }
}
+ #endregion
+
#if NET_2_0
///
/// Overrides the default PreviousPage property to return an instance of ,
@@ -750,8 +752,16 @@ namespace Spring.Web.UI
get { return this.Context.PreviousHandler as Page; }
}
#endif
-
- #endregion
+ ///
+ /// Publish associated with this page for convenient usage in Binding Expressions
+ ///
+ [Browsable(false)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public new virtual HttpContext Context
+ {
+ get {
+ return base.Context; }
+ }
#region Master Page support
diff --git a/src/Spring/Spring.Web/Web/UI/UserControl.cs b/src/Spring/Spring.Web/Web/UI/UserControl.cs
index 8108fc94..18823693 100644
--- a/src/Spring/Spring.Web/Web/UI/UserControl.cs
+++ b/src/Spring/Spring.Web/Web/UI/UserControl.cs
@@ -1110,6 +1110,19 @@ namespace Spring.Web.UI
get { return (Page)base.Page; }
}
+ ///
+ /// Publish associated with this page for convenient usage in Binding Expressions
+ ///
+ [Browsable(false)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public new virtual HttpContext Context
+ {
+ get
+ {
+ return base.Context;
+ }
+ }
+
#endregion
#region Helper Methods
diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/BasePropertyTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/BasePropertyTests.cs
index 31238a25..a937c371 100644
--- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/BasePropertyTests.cs
+++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/BasePropertyTests.cs
@@ -3,6 +3,7 @@ using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Text;
using NUnit.Framework;
using Spring.Context.Support;
@@ -264,14 +265,26 @@ namespace Spring.Reflection.Dynamic
public class MyStaticClass
{
public const Int64 MyConst = 3456;
- public static readonly string myReadonlyField = "hohoho";
+ public static readonly string myReadonlyField;
+ private static readonly string myPrivateReadonlyField;
public static string myField;
+ static MyStaticClass()
+ {
+ myReadonlyField = "hohoho";
+ myPrivateReadonlyField = "hahaha";
+ }
+
public static string MyProperty
{
get { return myField; }
set { myField = value; }
}
+
+ public static string MyPrivateReadOnylFieldAccessor
+ {
+ get { return myPrivateReadonlyField; }
+ }
}
public struct MyStaticStruct
diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicFieldTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicFieldTests.cs
index 9c0ebce3..503feb1e 100644
--- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicFieldTests.cs
+++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicFieldTests.cs
@@ -23,6 +23,8 @@
using System;
using System.Diagnostics;
using System.Reflection;
+using System.Security;
+using System.Security.Permissions;
using NUnit.Framework;
using Spring.Context.Support;
@@ -125,10 +127,54 @@ namespace Spring.Reflection.Dynamic
catch (InvalidOperationException) { }
IDynamicField myReadonlyField = Create( typeof( MyStaticClass ).GetField( "myReadonlyField" ) );
- Assert.AreEqual( "hohoho", myReadonlyField.GetValue( null ) );
+ string s2 = (string) myReadonlyField.GetValue(null);
+ string s1 = MyStaticClass.myReadonlyField;
+ Assert.AreEqual(s1, s2);
+ }
+
+
+#if NET_2_0
+
+ [Test]
+ public void CanReadPrivateReadOnlyField()
+ {
+ IDynamicField myPrivateReadonlyField2 = null;
+ FieldInfo fieldInfo = typeof(MyStaticClass).GetField("myPrivateReadonlyField", BindingFlags.Static | BindingFlags.NonPublic);
+
+ myPrivateReadonlyField2 = Create(fieldInfo);
+
+ string u2 = (string)myPrivateReadonlyField2.GetValue(null);
+ string u1 = "hahaha";
+ Assert.AreEqual(u1, u2);
+ }
+
+ [Test, Ignore("TODO: this works as expected when run using TD.NET & R# (in VS2k8), but fails with nant/NET 2.0 ?!?")]
+ public void CannotReadPrivateReadOnlyFieldIfNoReflectionPermission()
+ {
+ FieldInfo fieldInfo = typeof(MyStaticClass).GetField("myPrivateReadonlyField", BindingFlags.Static | BindingFlags.NonPublic);
try
{
- myReadonlyField.SetValue( null, "some other string" );
+ SecurityTemplate.MediumTrustInvoke( delegate
+ {
+ IDynamicField myPrivateReadonlyField2 = Create(fieldInfo);
+ });
+ Assert.Fail("private field must not be accessible in medium trust: " + fieldInfo);
+ }
+ catch (SecurityException sex)
+ {
+ Assert.IsTrue( sex.Message.IndexOf("ReflectionPermission") > -1 );
+ }
+ }
+#endif
+
+ [Test]
+ public void CannotSetStaticReadOnlyField()
+ {
+ IDynamicField myReadonlyField = Create(typeof(MyStaticClass).GetField("myReadonlyField"));
+ try
+ {
+ myReadonlyField.SetValue(null, "some other string");
+ Assert.Fail();
}
catch (InvalidOperationException) { }
}
diff --git a/test/Spring/Spring.Core.Tests/SecurityTemplate.cs b/test/Spring/Spring.Core.Tests/SecurityTemplate.cs
new file mode 100644
index 00000000..2c170eb8
--- /dev/null
+++ b/test/Spring/Spring.Core.Tests/SecurityTemplate.cs
@@ -0,0 +1,526 @@
+#region License
+
+/*
+ * Copyright 2002-2009 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#endregion
+
+#if NET_2_0
+
+using System;
+using System.Configuration;
+using System.Data.SqlClient;
+using System.Drawing.Printing;
+using System.IO;
+using System.Net;
+//using System.Net.Mail;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Security.Policy;
+using System.Text;
+using System.Threading;
+using System.Web;
+using System.Web.Configuration;
+
+namespace Spring
+{
+ ///
+ /// Allows to invoke parts of your code within the context of a certain PermissionSet.
+ ///
+ ///
+ ///
+ /// You may also use the static method and
+ /// to load a instance
+ /// yourself and apply it on your application domain using . Note,
+ /// that you must set the policy *before* an assembly gets loaded to apply that policy on that assembly!
+ ///
+ ///
+ /// The policy file format is the one used by .
+ /// You get good examples from your %FrameworkDir%/CONFIG/ directory (e.g. 'web_mediumtrust.config').
+ ///
+ ///
+ /// Erich Eichinger
+ public class SecurityTemplate
+ {
+ ///
+ /// The default full trust permission set name ("FullTrust")
+ ///
+ public static readonly string PERMISSIONSET_FULLTRUST = "FullTrust";
+ ///
+ /// The default no trust permission set name ("Nothing")
+ ///
+ public static readonly string PERMISSIONSET_NOTHING = "Nothing";
+ ///
+ /// The default medium trust permission set name ("MediumTrust")
+ ///
+ public static readonly string PERMISSIONSET_MEDIUMTRUST = "MediumTrust";
+ ///
+ /// The default low trust permission set name ("LowTrust")
+ ///
+ public static readonly string PERMISSIONSET_LOWTRUST = "LowTrust";
+ ///
+ /// The default asp.net permission set name ("ASP.NET")
+ ///
+ public static readonly string PERMISSIONSET_ASPNET = "ASP.Net";
+
+ private readonly PolicyLevel _domainPolicy;
+ // private readonly Dictionary securityContextCache = new Dictionary();
+ private bool throwOnUnknownPermissionSet = true;
+
+ ///
+ /// Avoid beforeFieldInit
+ ///
+ static SecurityTemplate()
+ {}
+
+ ///
+ /// Invoke the specified callback in a medium trusted context
+ ///
+ public static void MediumTrustInvoke( ThreadStart callback )
+ {
+ SecurityTemplate template = new SecurityTemplate(false);
+ template.PartialTrustInvoke(PERMISSIONSET_MEDIUMTRUST, callback);
+ }
+
+ ///
+ /// Access the domain of this instance.
+ ///
+ public PolicyLevel DomainPolicy
+ {
+ get { return _domainPolicy; }
+ }
+
+ ///
+ /// Whether to throw an in case
+ /// the permission set name is not found when invoking .
+ /// Defaults to true.
+ ///
+ public bool ThrowOnUnknownPermissionSet
+ {
+ get { return throwOnUnknownPermissionSet; }
+ set
+ {
+ throwOnUnknownPermissionSet = value;
+ // securityContextCache.Clear(); // clear cache
+ }
+ }
+
+ ///
+ /// Creates a new instance providing default "FullTrust", "Nothing", "MediumTrust" and "LowTrust" permissionsets
+ ///
+ /// NCover requires unmangaged code permissions, set this flag true in this case.
+ private SecurityTemplate(bool allowUnmanagedCode)
+ {
+ PolicyLevel pLevel = PolicyLevel.CreateAppDomainLevel();
+
+ // NOTHING permissionset
+ if (null == pLevel.GetNamedPermissionSet(PERMISSIONSET_NOTHING))
+ {
+ NamedPermissionSet noPermissionSet = new NamedPermissionSet(PERMISSIONSET_NOTHING, PermissionState.None);
+ noPermissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.NoFlags));
+ pLevel.AddNamedPermissionSet(noPermissionSet);
+ }
+
+ // FULLTRUST permissionset
+ if (null == pLevel.GetNamedPermissionSet(PERMISSIONSET_FULLTRUST))
+ {
+ NamedPermissionSet fulltrustPermissionSet = new NamedPermissionSet(PERMISSIONSET_FULLTRUST, PermissionState.Unrestricted);
+ pLevel.AddNamedPermissionSet(fulltrustPermissionSet);
+ }
+ // MEDIUMTRUST permissionset (corresponds to ASP.Net permission set in web_mediumtrust.config)
+ NamedPermissionSet mediumTrustPermissionSet = new NamedPermissionSet(PERMISSIONSET_MEDIUMTRUST, PermissionState.None);
+ mediumTrustPermissionSet.AddPermission(new AspNetHostingPermission(AspNetHostingPermissionLevel.Medium));
+ mediumTrustPermissionSet.AddPermission(new DnsPermission(PermissionState.Unrestricted));
+ mediumTrustPermissionSet.AddPermission(new EnvironmentPermission(EnvironmentPermissionAccess.Read,
+ "TEMP;TMP;USERNAME;OS;COMPUTERNAME"));
+ mediumTrustPermissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.AllAccess,
+ AppDomain.CurrentDomain.BaseDirectory));
+ IsolatedStorageFilePermission isolatedStorageFilePermission = new IsolatedStorageFilePermission(PermissionState.None);
+ isolatedStorageFilePermission.UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByUser;
+ isolatedStorageFilePermission.UserQuota = 9223372036854775807;
+ mediumTrustPermissionSet.AddPermission(isolatedStorageFilePermission);
+ mediumTrustPermissionSet.AddPermission(new PrintingPermission(PrintingPermissionLevel.DefaultPrinting));
+ SecurityPermissionFlag securityPermissionFlag = SecurityPermissionFlag.Assertion | SecurityPermissionFlag.Execution |
+ SecurityPermissionFlag.ControlThread | SecurityPermissionFlag.ControlPrincipal |
+ SecurityPermissionFlag.RemotingConfiguration;
+ if (allowUnmanagedCode)
+ {
+ securityPermissionFlag |= SecurityPermissionFlag.UnmanagedCode;
+ }
+ mediumTrustPermissionSet.AddPermission(new SecurityPermission(securityPermissionFlag));
+#if NET_2_0
+ mediumTrustPermissionSet.AddPermission(new System.Net.Mail.SmtpPermission(System.Net.Mail.SmtpAccess.Connect));
+#endif
+ mediumTrustPermissionSet.AddPermission(new SqlClientPermission(PermissionState.Unrestricted));
+ mediumTrustPermissionSet.AddPermission(new WebPermission());
+ pLevel.AddNamedPermissionSet(mediumTrustPermissionSet);
+
+ // LOWTRUST permissionset (corresponds to ASP.Net permission set in web_mediumtrust.config)
+ NamedPermissionSet lowTrustPermissionSet = new NamedPermissionSet(PERMISSIONSET_LOWTRUST, PermissionState.None);
+ lowTrustPermissionSet.AddPermission(new AspNetHostingPermission(AspNetHostingPermissionLevel.Low));
+ lowTrustPermissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery,
+ AppDomain.CurrentDomain.BaseDirectory));
+ IsolatedStorageFilePermission isolatedStorageFilePermissionLow = new IsolatedStorageFilePermission(PermissionState.None);
+ isolatedStorageFilePermissionLow.UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByUser;
+ isolatedStorageFilePermissionLow.UserQuota = 1048576;
+ lowTrustPermissionSet.AddPermission(isolatedStorageFilePermissionLow);
+ SecurityPermissionFlag securityPermissionFlagLow = SecurityPermissionFlag.Execution;
+ if (allowUnmanagedCode)
+ {
+ securityPermissionFlagLow |= SecurityPermissionFlag.UnmanagedCode;
+ }
+ lowTrustPermissionSet.AddPermission(new SecurityPermission(securityPermissionFlagLow));
+ pLevel.AddNamedPermissionSet(lowTrustPermissionSet);
+
+ // UnionCodeGroup rootCodeGroup = new UnionCodeGroup(new AllMembershipCondition(), new PolicyStatement(noPermissionSet, PolicyStatementAttribute.Nothing));
+ // pLevel.RootCodeGroup = rootCodeGroup;
+ _domainPolicy = pLevel;
+ }
+
+ ///
+ /// Loads domain policy from specified file
+ ///
+ ///
+ public SecurityTemplate(FileInfo securityConfigurationFile)
+ {
+ string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
+ _domainPolicy = LoadDomainPolicyFromUri(new Uri(securityConfigurationFile.FullName), appDirectory, string.Empty);
+ }
+
+ ///
+ /// Create a security tool from the specified domainPolicy
+ ///
+ public SecurityTemplate(PolicyLevel domainPolicy)
+ {
+ this._domainPolicy = domainPolicy;
+ }
+
+ ///
+ /// Invokes the given callback using the policy's default
+ /// partial trust permissionset ("ASP.Net" ).
+ ///
+ public void PartialTrustInvoke(ThreadStart callback)
+ {
+ string defaultPermissionSetName = PERMISSIONSET_MEDIUMTRUST;
+ if (null != GetNamedPermissionSet(PERMISSIONSET_ASPNET))
+ {
+ defaultPermissionSetName = PERMISSIONSET_ASPNET;
+ }
+
+ PartialTrustInvoke(defaultPermissionSetName, callback);
+ }
+
+ ///
+ /// Invokes the given callback using the specified permissionset.
+ ///
+// [SecurityTreatAsSafe, SecurityCritical]
+ public void PartialTrustInvoke(string permissionSetName, ThreadStart callback)
+ {
+ PermissionSet ps = null;
+ ps = GetNamedPermissionSet(permissionSetName);
+ if (ps == null && throwOnUnknownPermissionSet)
+ {
+ throw new ArgumentOutOfRangeException("permissionSetName", permissionSetName,
+ string.Format("unknown PermissionSet name '{0}'",
+ permissionSetName));
+ }
+
+ if (!IsFullTrust(ps))
+ {
+ ps.PermitOnly();
+ callback();
+ CodeAccessPermission.RevertPermitOnly();
+ }
+ else
+ {
+ callback();
+ }
+ }
+
+ private PermissionSet GetNamedPermissionSet(string name)
+ {
+ if (_domainPolicy != null)
+ {
+ return _domainPolicy.GetNamedPermissionSet(name);
+ }
+ return null;
+ }
+
+ ///
+ /// Loads the policy configuration from app.config configuration section
+ ///
+ ///
+ /// Configuration is identical to web.config:
+ ///
+ /// <configuration>
+ /// <system.web>
+ /// <securityPolicy>
+ /// <trustLevel name="Full" policyFile="internal"/>
+ /// <trustLevel name="High" policyFile="web_hightrust.config"/>
+ /// <trustLevel name="Medium" policyFile="web_mediumtrust.config"/>
+ /// <trustLevel name="Low" policyFile="web_lowtrust.config"/>
+ /// <trustLevel name="Minimal" policyFile="web_minimaltrust.config"/>
+ /// </securityPolicy>
+ /// <trust level="Medium" originUrl=""/>
+ /// </system.web>
+ /// </configuration>
+ ///
+ ///
+ ///
+ ///
+ public static PolicyLevel LoadDomainPolicyFromAppConfig(bool throwOnError)
+ {
+ TrustSection trustSection = (TrustSection)ConfigurationManager.GetSection("system.web/trust");
+ SecurityPolicySection securityPolicySection = (SecurityPolicySection)ConfigurationManager.GetSection("system.web/securityPolicy");
+
+ if ((trustSection == null) || string.IsNullOrEmpty(trustSection.Level))
+ {
+ if (!throwOnError)
+ return null;
+ throw new ConfigurationErrorsException("Configuration section not found ");
+ }
+
+ if (trustSection.Level == "Full")
+ {
+ return null;
+ }
+
+ if ((securityPolicySection == null) || (securityPolicySection.TrustLevels[trustSection.Level] == null))
+ {
+ if (!throwOnError)
+ return null;
+ throw new ConfigurationErrorsException(string.Format("configuration not found", trustSection.Level));
+ }
+
+ string policyFileExpanded = GetPolicyFilenameExpanded(securityPolicySection.TrustLevels[trustSection.Level]);
+ string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
+ PolicyLevel domainPolicy = LoadDomainPolicyFromUri(new Uri(policyFileExpanded), appDirectory, trustSection.OriginUrl);
+ return domainPolicy;
+ }
+
+ ///
+ /// Loads a policy from a file (),
+ /// replacing placeholders
+ ///
+ /// - $AppDir$, $AppDirUrl$ =>
+ /// - $CodeGen$ => (TODO)
+ /// - $OriginHost$ =>
+ /// - $Gac$ => the current machine's GAC path
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static PolicyLevel LoadDomainPolicyFromUri(Uri policyFileLocation, string appDirectory, string originUrl)
+ {
+ bool foundGacToken = false;
+ PolicyLevel domainPolicy = CreatePolicyLevel(policyFileLocation, appDirectory, appDirectory, originUrl, out foundGacToken);
+ if (foundGacToken)
+ {
+ CodeGroup rootCodeGroup = domainPolicy.RootCodeGroup;
+ bool hasGacMembershipCondition = false;
+ foreach (CodeGroup childCodeGroup in rootCodeGroup.Children)
+ {
+ if (childCodeGroup.MembershipCondition is GacMembershipCondition)
+ {
+ hasGacMembershipCondition = true;
+ break;
+ }
+ }
+ if (!hasGacMembershipCondition && (rootCodeGroup is FirstMatchCodeGroup))
+ {
+ FirstMatchCodeGroup firstMatchCodeGroup = (FirstMatchCodeGroup)rootCodeGroup;
+ if ((firstMatchCodeGroup.MembershipCondition is AllMembershipCondition) && (firstMatchCodeGroup.PermissionSetName == PERMISSIONSET_NOTHING))
+ {
+ PermissionSet unrestrictedPermissionSet = new PermissionSet(PermissionState.Unrestricted);
+ CodeGroup gacGroup = new UnionCodeGroup(new GacMembershipCondition(), new PolicyStatement(unrestrictedPermissionSet));
+ CodeGroup rootGroup = new FirstMatchCodeGroup(rootCodeGroup.MembershipCondition, rootCodeGroup.PolicyStatement);
+ foreach (CodeGroup childGroup in rootCodeGroup.Children)
+ {
+ if (((childGroup is UnionCodeGroup) && (childGroup.MembershipCondition is UrlMembershipCondition)) && (childGroup.PolicyStatement.PermissionSet.IsUnrestricted() && (gacGroup != null)))
+ {
+ rootGroup.AddChild(gacGroup);
+ gacGroup = null;
+ }
+ rootGroup.AddChild(childGroup);
+ }
+ domainPolicy.RootCodeGroup = rootGroup;
+ }
+ }
+ }
+ return domainPolicy;
+ }
+
+ private static PolicyLevel CreatePolicyLevel(Uri configFile, string appDir, string binDir, string strOriginUrl, out bool foundGacToken)
+ {
+ WebClient webClient = new WebClient();
+ string strXmlPolicy = webClient.DownloadString(configFile);
+ appDir = FileUtil.RemoveTrailingDirectoryBackSlash(appDir);
+ binDir = FileUtil.RemoveTrailingDirectoryBackSlash(binDir);
+ strXmlPolicy = strXmlPolicy.Replace("$AppDir$", appDir).Replace("$AppDirUrl$", MakeFileUrl(appDir)).Replace("$CodeGen$", MakeFileUrl(binDir));
+ if (strOriginUrl == null)
+ {
+ strOriginUrl = string.Empty;
+ }
+ strXmlPolicy = strXmlPolicy.Replace("$OriginHost$", strOriginUrl);
+ if (strXmlPolicy.IndexOf("$Gac$", StringComparison.Ordinal) != -1)
+ {
+ string gacLocation = GetGacLocation();
+ if (gacLocation != null)
+ {
+ gacLocation = MakeFileUrl(gacLocation);
+ }
+ if (gacLocation == null)
+ {
+ gacLocation = string.Empty;
+ }
+ strXmlPolicy = strXmlPolicy.Replace("$Gac$", gacLocation);
+ foundGacToken = true;
+ }
+ else
+ {
+ foundGacToken = false;
+ }
+ return SecurityManager.LoadPolicyLevelFromString(strXmlPolicy, PolicyLevelType.AppDomain);
+ }
+
+ private static string GetPolicyFilenameExpanded(TrustLevel trustLevel)
+ {
+ bool isRelative = true;
+ if (trustLevel.PolicyFile.Length > 1)
+ {
+ char ch = trustLevel.PolicyFile[1];
+ char ch2 = trustLevel.PolicyFile[0];
+ if (ch == ':')
+ {
+ isRelative = false;
+ }
+ else if ((ch2 == '\\') && (ch == '\\'))
+ {
+ isRelative = false;
+ }
+ }
+
+ if (isRelative)
+ {
+ string configurationElementFileSource = trustLevel.ElementInformation.Properties["policyFile"].Source;
+ string path = configurationElementFileSource.Substring(0, configurationElementFileSource.LastIndexOf('\\') + 1);
+ return path + trustLevel.PolicyFile;
+ }
+ return trustLevel.PolicyFile;
+ }
+
+ [DllImport("mscorwks.dll", CharSet = CharSet.Unicode)]
+ private static extern int GetCachePath(int dwCacheFlags, StringBuilder pwzCachePath, ref int pcchPath);
+
+ private static string GetGacLocation()
+ {
+ int capacity = 0x106;
+ StringBuilder pwzCachePath = new StringBuilder(capacity);
+ int pcchPath = capacity - 2;
+ int hRes = GetCachePath(2, pwzCachePath, ref pcchPath);
+ if (hRes < 0)
+ {
+ throw new HttpException("failed obtaining GAC path", hRes);
+ }
+ return pwzCachePath.ToString();
+ }
+
+ private static string MakeFileUrl(string path)
+ {
+ Uri uri = new Uri(path);
+ return uri.ToString();
+ }
+
+ private class FileUtil
+ {
+ internal static string RemoveTrailingDirectoryBackSlash(string path)
+ {
+ if (path == null)
+ {
+ return null;
+ }
+ int length = path.Length;
+ if ((length > 3) && (path[length - 1] == '\\'))
+ {
+ path = path.Substring(0, length - 1);
+ }
+ return path;
+ }
+ }
+
+ private static bool IsFullTrust(PermissionSet perms)
+ {
+ if (perms != null)
+ {
+ return perms.IsUnrestricted();
+ }
+ return true;
+ }
+
+ // [SecurityTreatAsSafe, SecurityCritical]
+ // private bool NeedPartialTrustInvoke(string permissionSetName)
+ // {
+ // if (_domainPolicy == null) return false;
+ //
+ // SecurityContext securityContext = null;
+ // if (!securityContextCache.ContainsKey(permissionSetName))
+ // {
+ // NamedPermissionSet permissionSet = _domainPolicy.GetNamedPermissionSet(permissionSetName);
+ // if (permissionSet == null && throwOnUnknownPermissionSet)
+ // {
+ // throw new ArgumentOutOfRangeException("permissionSetName", permissionSetName, "Undefined permission set");
+ // }
+ // if (!IsFullTrust(permissionSet))
+ // {
+ // try
+ // {
+ // permissionSet.PermitOnly();
+ // securityContext = CaptureSecurityContextNoIdentityFlow();
+ // }
+ // finally
+ // {
+ // CodeAccessPermission.RevertPermitOnly();
+ // }
+ // }
+ // securityContextCache[permissionSetName] = securityContext;
+ // }
+ // else
+ // {
+ // securityContext = securityContextCache[permissionSetName];
+ // }
+ // return (securityContext != null);
+ // }
+
+
+ // [SecurityCritical]
+ // private static SecurityContext CaptureSecurityContextNoIdentityFlow()
+ // {
+ // if (SecurityContext.IsWindowsIdentityFlowSuppressed())
+ // {
+ // return SecurityContext.Capture();
+ // }
+ // using (SecurityContext.SuppressFlowWindowsIdentity())
+ // {
+ // return SecurityContext.Capture();
+ // }
+ // }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2008.csproj b/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2008.csproj
index 77754094..a0ce0057 100644
--- a/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2008.csproj
+++ b/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2008.csproj
@@ -656,6 +656,7 @@
+
Code
diff --git a/test/Spring/Spring.Core.Tests/Util/ReflectionUtilsMemberwiseCopyTests.cs b/test/Spring/Spring.Core.Tests/Util/ReflectionUtilsMemberwiseCopyTests.cs
index ca7eb606..76d9bec1 100644
--- a/test/Spring/Spring.Core.Tests/Util/ReflectionUtilsMemberwiseCopyTests.cs
+++ b/test/Spring/Spring.Core.Tests/Util/ReflectionUtilsMemberwiseCopyTests.cs
@@ -1,4 +1,8 @@
using System;
+using System.Security;
+using System.Security.Permissions;
+using System.Threading;
+using System.Web;
using NUnit.Framework;
namespace Spring.Util
@@ -46,9 +50,50 @@ namespace Spring.Util
ReflectionUtils.MemberwiseCopy(i2, i1);
- Assert.AreEqual(i2, i1);
+ Assert.AreEqual(i1, i2);
}
- }
+
+#if NET_2_0
+ [Test]
+ public void MediumTrustAllowsCopyingBetweenTypesFromSameModule()
+ {
+ SampleBaseClass i1 = new SampleDerivedClass("1st config val");
+ SampleBaseClass i2 = new SampleFurtherDerivedClass("2nd config val");
+
+ SecurityTemplate.MediumTrustInvoke(new ThreadStart(new CopyCommand(i2, i1).Execute));
+ Assert.AreEqual(i1, i2);
+ }
+
+ [Test]
+ public void MediumTrustThrowsSecurityExceptionWhenCopyingBetweenTypesFromDifferentModules()
+ {
+ Exception e1 = new Exception("my name is e1");
+ HttpException e2 = new HttpException("my name is e2");
+ // I know, I am a bit paranoid about that basic assumption
+ Assert.AreNotEqual( e1.GetType().Assembly, e2.GetType().Assembly );
+
+ SecurityTemplate.MediumTrustInvoke(new ThreadStart(new CopyCommand(e2, e1).Execute));
+ Assert.AreEqual(e1.Message, e2.Message);
+ }
+
+ class CopyCommand
+ {
+ private object a;
+ private object b;
+
+ public CopyCommand(object a, object b)
+ {
+ this.a = a;
+ this.b = b;
+ }
+
+ public void Execute()
+ {
+ ReflectionUtils.MemberwiseCopy(a, b);
+ }
+ }
+#endif
+ }
#region Test Support Classes
@@ -57,7 +102,7 @@ namespace Spring.Util
private const string MyConstant = "SampleBaseClass.MyConstant";
private readonly string _someReadOnlyVal = "SampleBaseClass.SomeReadOnlyVal";
protected readonly string _someProtectedReadOnlyVal = "SampleBaseClass.SomeProtectedReadOnlyVal";
- private string _someConfigVal = "SampleBaseClass.SomeConfigVal";
+ private string _someConfigVal;
public SampleBaseClass(string someConfigVal)
{
@@ -76,9 +121,12 @@ namespace Spring.Util
public override bool Equals(object obj)
{
- if (this == obj) return true;
- SampleBaseClass sampleBaseClass = obj as SampleBaseClass;
- if (sampleBaseClass == null) return false;
+ if (ReferenceEquals(obj, null) || (!this.GetType().IsAssignableFrom(obj.GetType())))
+ return false;
+ if (ReferenceEquals(this , obj))
+ return true;
+
+ SampleBaseClass sampleBaseClass = (SampleBaseClass) obj;
if (!Equals(_someReadOnlyVal, sampleBaseClass._someReadOnlyVal)) return false;
if (!Equals(_someProtectedReadOnlyVal, sampleBaseClass._someProtectedReadOnlyVal)) return false;
if (!Equals(_someConfigVal, sampleBaseClass._someConfigVal)) return false;
@@ -102,11 +150,12 @@ namespace Spring.Util
public override bool Equals(object obj)
{
- if (this == obj) return true;
- SampleDerivedClass sampleDerivedClass = obj as SampleDerivedClass;
- if (sampleDerivedClass == null) return false;
- if (!base.Equals(obj)) return false;
- if (!Equals(_someConfigVal, sampleDerivedClass._someConfigVal)) return false;
+ if (!base.Equals(obj))
+ return false;
+
+ SampleDerivedClass sampleDerivedClass = (SampleDerivedClass)obj;
+ if (!Equals(_someConfigVal, sampleDerivedClass._someConfigVal))
+ return false;
return true;
}
}