Global reformat for files (#272)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<clear />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
|
||||
76
README.md
76
README.md
@@ -5,7 +5,6 @@ THE SPRING.NET FRAMEWORK
|
||||
---------------------------------------------------------
|
||||
http://www.springframework.net/
|
||||
|
||||
|
||||
## INTRODUCTION
|
||||
|
||||
Spring.NET contains:
|
||||
@@ -19,23 +18,29 @@ Spring.NET contains:
|
||||
* ASP.NET MVC and ASP.NET WebAPI Framework
|
||||
* Dependency Injection for MVC (includin WebAPI).
|
||||
* Declarative transaction management abstraction
|
||||
* Declarative transaction management via use of common XML configuration and attributes across different transaction APIs
|
||||
* Declarative transaction management via use of common XML configuration and attributes across different transaction
|
||||
APIs
|
||||
* ADO.NET framework
|
||||
* Simplifies use of ADO.NET. DAO support classes and integration with Spring's declarative transaction management functionality
|
||||
* Simplifies use of ADO.NET. DAO support classes and integration with Spring's declarative transaction management
|
||||
functionality
|
||||
* Portable Service Abstractions
|
||||
* Export plain .NET objects via .NET Remoting, Web Service or .NET Serviced Component and create client side proxies based on endpoint URL and service interface.
|
||||
* Export plain .NET objects via .NET Remoting, Web Service or .NET Serviced Component and create client side proxies
|
||||
based on endpoint URL and service interface.
|
||||
* NHibernate Integation
|
||||
* NHibernate 5 integration to simplify use of NHibernate and participate in Spring's declarative transaction management functionality.
|
||||
* NHibernate 5 integration to simplify use of NHibernate and participate in Spring's declarative transaction
|
||||
management functionality.
|
||||
* ASP.NET AJAX Integration
|
||||
* Exporter to expose plain object on which Dependency Injection and AOP have been applied to JavaScript.
|
||||
* NUnit and MSTest integration
|
||||
* Provides Dependency Injection of test cases and Spring container loading and caching. . Data access and transaction management features aid with integration testing.
|
||||
* Provides Dependency Injection of test cases and Spring container loading and caching. . Data access and
|
||||
transaction management features aid with integration testing.
|
||||
* WCF integration
|
||||
* Provides Dependency Injection and applicatin of AOP advice to WCF services
|
||||
* Quartz integration
|
||||
* Configure Quartz jobs using dependency injection and Spring's transactional support to persist job details
|
||||
* MSMQ integration
|
||||
* Simplifies the use MSMQ by providing helper classes for message sending and receiving. Integrates with Spring's transaction management features.
|
||||
* Simplifies the use MSMQ by providing helper classes for message sending and receiving. Integrates with Spring's
|
||||
transaction management features.
|
||||
* NMS integration
|
||||
* Simplifies the use of NMS by providing helper classes for message sending and receiving.
|
||||
* TIBCO EMS integration
|
||||
@@ -43,7 +48,8 @@ Spring.NET contains:
|
||||
* NVelocity integration
|
||||
* Simplifies the use of configuring NVelocity
|
||||
|
||||
Spring.NET is a port of the Java based Spring Framework. In turn, the Java/J2EE Spring Framework is based on code published in "Expert One-on-One J2EE Design and Development" by Rod Johnson (Wrox, 2002).
|
||||
Spring.NET is a port of the Java based Spring Framework. In turn, the Java/J2EE Spring Framework is based on code
|
||||
published in "Expert One-on-One J2EE Design and Development" by Rod Johnson (Wrox, 2002).
|
||||
|
||||
## SUPPORTED .NET FRAMEWORK VERSIONS
|
||||
|
||||
@@ -64,7 +70,7 @@ Release contents:
|
||||
* `doc` contains reference documentation, MSDN-style API help, and the Spring.NET xsd.
|
||||
* `examples` contains sample applications.
|
||||
* `build-support` contains additonal applications need to build using NAnt as some convenience
|
||||
VS.NET solution files.
|
||||
VS.NET solution files.
|
||||
* `dev-support` contains 'developer support' tools and code, such as solution templates for VS.NET
|
||||
|
||||
debug build is done using /DEBUG:full and release build using /DEBUG:pdbonly flags.
|
||||
@@ -75,74 +81,89 @@ Latest info is available at the public website: http://www.springframework.net/
|
||||
|
||||
The Spring Framework is released under the terms of the Apache Software License (see license.txt).
|
||||
|
||||
|
||||
## DISTRIBUTION DLLs
|
||||
|
||||
The "bin" directory contains the following distinct dll files for use in applications. Dependencies are those other than on the .NET BCL.
|
||||
The "bin" directory contains the following distinct dll files for use in applications. Dependencies are those other than
|
||||
on the .NET BCL.
|
||||
|
||||
* __Spring.Core__ (~765 KB) [](https://www.nuget.org/packages/Spring.Core/) [](#)
|
||||
* __Spring.Core__ (~765
|
||||
KB) [](https://www.nuget.org/packages/Spring.Core/) [](#)
|
||||
* Contents: Inversion of control container. Collection classes.
|
||||
* Dependencies: Common.Logging
|
||||
|
||||
* __Spring.Aop__ (~150 KB) [](https://www.nuget.org/packages/Spring.Aop/) [](#)
|
||||
* __Spring.Aop__ (~150
|
||||
KB) [](https://www.nuget.org/packages/Spring.Aop/) [](#)
|
||||
* Contents: Abstract Oriented Programming Framework.
|
||||
* Dependencies: Spring.Core, Common.Logging
|
||||
|
||||
* __Spring.Data__ (~320 KB) [](https://www.nuget.org/packages/Spring.Data/) [](#)
|
||||
* __Spring.Data__ (~320
|
||||
KB) [](https://www.nuget.org/packages/Spring.Data/) [](#)
|
||||
* Contents: Transaction and ADO.NET Framework.
|
||||
* Dependencies: Spring.Core, Spring.Aop
|
||||
|
||||
* __Spring.Data.NHibernate5__ (~90 KB) [](https://www.nuget.org/packages/Spring.Data.NHibernate5/) [](#)
|
||||
* __Spring.Data.NHibernate5__ (~90
|
||||
KB) [](https://www.nuget.org/packages/Spring.Data.NHibernate5/) [](#)
|
||||
* Contents: NHibernate 5.x integration
|
||||
* Dependencies: Spring.Core, Spring.Aop, Spring.Data, NHibernate
|
||||
|
||||
* __Spring.Services__ (~70 KB) [](https://www.nuget.org/packages/Spring.Services/) [](#)
|
||||
* __Spring.Services__ (~70
|
||||
KB) [](https://www.nuget.org/packages/Spring.Services/) [](#)
|
||||
* Contents: Web Services, Remoting, and Enterprise Component based services.
|
||||
* Dependencies: Spring.Core, Spring.Aop
|
||||
|
||||
* __Spring.Web__ (~165 KB) [](https://www.nuget.org/packages/Spring.Web/) [](#)
|
||||
* __Spring.Web__ (~165
|
||||
KB) [](https://www.nuget.org/packages/Spring.Web/) [](#)
|
||||
* Contents: ASP.NET based Web Application Framework.
|
||||
* Dependencies: Spring.Core, Spring.Aop
|
||||
|
||||
* __Spring.Web.Extensions__ (~8 KB) [](https://www.nuget.org/packages/Spring.Web.Extensions/) [](#)
|
||||
* __Spring.Web.Extensions__ (~8
|
||||
KB) [](https://www.nuget.org/packages/Spring.Web.Extensions/) [](#)
|
||||
* Contents: ASP.NET AJAX Integartion
|
||||
* Dependencies: Spring.Core, Spring.Aop, System.Web.Extensions
|
||||
|
||||
* __Spring.Web.Mvc5__ (~8 KB) [](https://www.nuget.org/packages/Spring.Web.Mvc5/) [](#)
|
||||
* __Spring.Web.Mvc5__ (~8
|
||||
KB) [](https://www.nuget.org/packages/Spring.Web.Mvc5/) [](#)
|
||||
* Contents: ASP.NET MVC5 and WebAPI Integartion
|
||||
* Dependencies: Spring.Core, Spring.Web
|
||||
|
||||
* __Spring.Testing.NUnit__ (~24 KB) [](https://www.nuget.org/packages/Spring.Testing.NUnit/) [](#)
|
||||
* __Spring.Testing.NUnit__ (~24
|
||||
KB) [](https://www.nuget.org/packages/Spring.Testing.NUnit/) [](#)
|
||||
* Contents: NUnit Integration
|
||||
* Dependencies: Spring.Core, Spring.Data, NUnit
|
||||
|
||||
* __Spring.Testing.Microsoft__ (~24 KB) [](https://www.nuget.org/packages/Spring.Testing.Microsoft/) [](#)
|
||||
* __Spring.Testing.Microsoft__ (~24
|
||||
KB) [](https://www.nuget.org/packages/Spring.Testing.Microsoft/) [](#)
|
||||
* Contents: MSTest Integration
|
||||
* Dependencies: Spring.Core, Spring.Data, MSTest
|
||||
|
||||
* __Spring.Messaging__ (~65 KB) [](https://www.nuget.org/packages/Spring.Messaging/) [](#)
|
||||
* __Spring.Messaging__ (~65
|
||||
KB) [](https://www.nuget.org/packages/Spring.Messaging/) [](#)
|
||||
* Contents: MSMQ Integration
|
||||
* Dependencies: Spring.Core, Spring.Data, System.Messaging
|
||||
|
||||
* __Spring.Messaging.Nms__ (~100 KB) [](https://www.nuget.org/packages/Spring.Messaging.Nms/) [](#)
|
||||
* __Spring.Messaging.Nms__ (~100
|
||||
KB) [](https://www.nuget.org/packages/Spring.Messaging.Nms/) [](#)
|
||||
* Contents: NMS Integration
|
||||
* Dependencies: Spring.Core, Spring.Data, Apache NMS
|
||||
|
||||
* __Spring.Scheduling.Quartz3__ (~44 KB) [](https://www.nuget.org/packages/Spring.Scheduling.Quartz3/) [](#)
|
||||
* __Spring.Scheduling.Quartz3__ (~44
|
||||
KB) [](https://www.nuget.org/packages/Spring.Scheduling.Quartz3/) [](#)
|
||||
* Contents: Quartz32.x Integration
|
||||
* Dependencies: Spring.Core, Spring.Data, Quartz
|
||||
|
||||
* __Spring.Template.Velocity__ (~44 KB) [](https://www.nuget.org/packages/Spring.Template.Velocity/) [](#)
|
||||
* __Spring.Template.Velocity__ (~44
|
||||
KB) [](https://www.nuget.org/packages/Spring.Template.Velocity/) [](#)
|
||||
* Contents: NVelocity Integration
|
||||
* Dependencies: Spring.Core, NVelocity
|
||||
|
||||
|
||||
## WHERE TO START?
|
||||
|
||||
Documentation can be found in the "docs" directory:
|
||||
|
||||
* The Spring reference documentation
|
||||
|
||||
Documented sample applications can be found in "examples":
|
||||
|
||||
* IoCQuickStart.MovieFinder - A simple example demonstrating basic IoC container behavior.
|
||||
* IoCQuickStart.AppContext - Show use of various IApplicationContext features.
|
||||
* IoCQuickStart.EventRegistry - Show use of loosely coupled eventing features.
|
||||
@@ -166,7 +187,8 @@ Documented sample applications can be found in "examples":
|
||||
VS.NET
|
||||
------
|
||||
|
||||
Visual Studio 2022 is required to open and build the solution. The free community version of Visual Studio should suffice.
|
||||
Visual Studio 2022 is required to open and build the solution. The free community version of Visual Studio should
|
||||
suffice.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
||||
@@ -5,4 +5,4 @@ public partial class Build
|
||||
Target Ci => _ => _
|
||||
.DependsOn(Compile, Test, Pack)
|
||||
.Executes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using Nuke.Common;
|
||||
using Nuke.Common.IO;
|
||||
using Nuke.Common.Tooling;
|
||||
using Nuke.Common.Tools.DotNet;
|
||||
|
||||
using static Nuke.Common.Tools.DotNet.DotNetTasks;
|
||||
|
||||
public partial class Build
|
||||
@@ -39,5 +38,4 @@ public partial class Build
|
||||
|
||||
bool PushCompleteOnFailure => true;
|
||||
int PushDegreeOfParallelism => 5;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
using System.Linq;
|
||||
using Nuke.Common;
|
||||
using Nuke.Common.Tools.DotNet;
|
||||
|
||||
using static Nuke.Common.Tools.DotNet.DotNetTasks;
|
||||
|
||||
public partial class Build
|
||||
{
|
||||
[Parameter]
|
||||
readonly bool TestFull = false;
|
||||
[Parameter]
|
||||
readonly bool TestIntegrationData = false;
|
||||
[Parameter]
|
||||
readonly bool TestIntegrationEms = false;
|
||||
[Parameter]
|
||||
readonly bool TestIntegrationNms = false;
|
||||
[Parameter]
|
||||
readonly bool TestIntegrationMsMq = false;
|
||||
[Parameter] readonly bool TestFull = false;
|
||||
[Parameter] readonly bool TestIntegrationData = false;
|
||||
[Parameter] readonly bool TestIntegrationEms = false;
|
||||
[Parameter] readonly bool TestIntegrationNms = false;
|
||||
[Parameter] readonly bool TestIntegrationMsMq = false;
|
||||
|
||||
Target Test => _ => _
|
||||
.DependsOn(Restore)
|
||||
@@ -55,5 +49,4 @@ public partial class Build
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,17 +27,13 @@ partial class Build : NukeBuild
|
||||
/// - JetBrains Rider https://nuke.build/rider
|
||||
/// - Microsoft VisualStudio https://nuke.build/visualstudio
|
||||
/// - Microsoft VSCode https://nuke.build/vscode
|
||||
public static int Main() => Execute<Build>(x => x.Compile);
|
||||
|
||||
public static int Main () => Execute<Build>(x => x.Compile);
|
||||
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;
|
||||
|
||||
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
|
||||
readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;
|
||||
[Parameter("Build EMS")] readonly bool BuildEms = false;
|
||||
|
||||
[Parameter("Build EMS")]
|
||||
readonly bool BuildEms = false;
|
||||
|
||||
[Parameter("Version")]
|
||||
readonly string ProjectVersion = "3.1.0";
|
||||
[Parameter("Version")] readonly string ProjectVersion = "3.1.0";
|
||||
|
||||
[Solution] readonly Solution Solution;
|
||||
[GitRepository] readonly GitRepository GitRepository;
|
||||
@@ -180,35 +176,10 @@ partial class Build : NukeBuild
|
||||
var binDirectory = RootDirectory / "bin";
|
||||
binDirectory.CreateOrCleanDirectory();
|
||||
|
||||
var moduleNames = new[]
|
||||
{
|
||||
"Common.Logging",
|
||||
"Common.Logging.Core",
|
||||
"Spring.Core",
|
||||
"Spring.Aop",
|
||||
"Spring.Data",
|
||||
"Spring.Data.NHibernate*",
|
||||
"Spring.Web",
|
||||
"Spring.Web.Mvc5",
|
||||
"Spring.Web.Extensions",
|
||||
"Spring.Services",
|
||||
"Spring.Testing.NUnit",
|
||||
"Spring.Testing.Microsoft",
|
||||
"Spring.Messaging.Ems",
|
||||
"Spring.Messaging.Nms",
|
||||
"Spring.Messaging",
|
||||
"Spring.Scheduling.Quartz3",
|
||||
"Spring.Template.Velocity",
|
||||
"Spring.Web.Conversation.NHibernate5",
|
||||
};
|
||||
var moduleNames = new[] { "Common.Logging", "Common.Logging.Core", "Spring.Core", "Spring.Aop", "Spring.Data", "Spring.Data.NHibernate*", "Spring.Web", "Spring.Web.Mvc5", "Spring.Web.Extensions", "Spring.Services", "Spring.Testing.NUnit", "Spring.Testing.Microsoft", "Spring.Messaging.Ems", "Spring.Messaging.Nms", "Spring.Messaging", "Spring.Scheduling.Quartz3", "Spring.Template.Velocity", "Spring.Web.Conversation.NHibernate5", };
|
||||
|
||||
var patterns = moduleNames
|
||||
.SelectMany(x => new []
|
||||
{
|
||||
"**/" + Configuration + "/**/" + x + ".dll",
|
||||
"**/" + Configuration + "/**/" + x + ".xml",
|
||||
"**/" + Configuration + "/**/" + x + ".pdb"
|
||||
})
|
||||
.SelectMany(x => new[] { "**/" + Configuration + "/**/" + x + ".dll", "**/" + Configuration + "/**/" + x + ".xml", "**/" + Configuration + "/**/" + x + ".pdb" })
|
||||
.ToArray();
|
||||
|
||||
foreach (var file in BuildDirectory.GlobFiles(patterns))
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
<CleanedProjectName>$(MSBuildProjectName.Replace('.2010', ''))</CleanedProjectName>
|
||||
|
||||
<CleanedProjectName>$(MSBuildProjectName.Replace('.2010', ''))</CleanedProjectName>
|
||||
|
||||
<AssemblyName>$(CleanedProjectName)</AssemblyName>
|
||||
<PackageId>$(CleanedProjectName)</PackageId>
|
||||
<RootNamespace>Spring</RootNamespace>
|
||||
|
||||
@@ -20,35 +20,34 @@
|
||||
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Aop.Config
|
||||
namespace Spring.Aop.Config;
|
||||
|
||||
/// <summary>
|
||||
/// Namespace parser for the aop namespace.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using the <code>advisor</code> tag you can configure an <see cref="IAdvisor"/> and have it
|
||||
/// applied to all the relevant objects in your application context automatically. The
|
||||
/// <code>advisor</code> tag supports only referenced <see cref="IPointcut"/>s.
|
||||
/// </remarks>
|
||||
/// <author>Rob harrop</author>
|
||||
/// <author>Adrian Colyer</author>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
[
|
||||
NamespaceParser(
|
||||
Namespace = "http://www.springframework.net/aop",
|
||||
SchemaLocationAssemblyHint = typeof(AopNamespaceParser),
|
||||
SchemaLocation = "/Spring.Aop.Config/spring-aop-1.1.xsd"
|
||||
)
|
||||
]
|
||||
public class AopNamespaceParser : NamespaceParserSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// Namespace parser for the aop namespace.
|
||||
/// Register the <see cref="IObjectDefinitionParser"/> for the '<code>config</code>' tag.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using the <code>advisor</code> tag you can configure an <see cref="IAdvisor"/> and have it
|
||||
/// applied to all the relevant objects in your application context automatically. The
|
||||
/// <code>advisor</code> tag supports only referenced <see cref="IPointcut"/>s.
|
||||
/// </remarks>
|
||||
/// <author>Rob harrop</author>
|
||||
/// <author>Adrian Colyer</author>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
[
|
||||
NamespaceParser(
|
||||
Namespace = "http://www.springframework.net/aop",
|
||||
SchemaLocationAssemblyHint = typeof (AopNamespaceParser),
|
||||
SchemaLocation = "/Spring.Aop.Config/spring-aop-1.1.xsd"
|
||||
)
|
||||
]
|
||||
public class AopNamespaceParser : NamespaceParserSupport
|
||||
public override void Init()
|
||||
{
|
||||
/// <summary>
|
||||
/// Register the <see cref="IObjectDefinitionParser"/> for the '<code>config</code>' tag.
|
||||
/// </summary>
|
||||
public override void Init()
|
||||
{
|
||||
RegisterObjectDefinitionParser("config", new ConfigObjectDefinitionParser());
|
||||
}
|
||||
RegisterObjectDefinitionParser("config", new ConfigObjectDefinitionParser());
|
||||
}
|
||||
}
|
||||
@@ -29,67 +29,66 @@ using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Config
|
||||
namespace Spring.Aop.Config;
|
||||
|
||||
/// <summary>
|
||||
/// Utility class for handling registration of auto-proxy creators used internally by the
|
||||
/// <code>aop</code> and <code>tx</code> namespace tags.
|
||||
/// </summary>
|
||||
/// <author>Rob Harrop</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
public class AopNamespaceUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class for handling registration of auto-proxy creators used internally by the
|
||||
/// <code>aop</code> and <code>tx</code> namespace tags.
|
||||
/// The object name of the internally managed auto-proxy creator.
|
||||
/// </summary>
|
||||
/// <author>Rob Harrop</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
public class AopNamespaceUtils
|
||||
public static readonly string AUTO_PROXY_CREATOR_OBJECT_NAME = "Spring.Aop.Config.InternalAutoProxyCreator";
|
||||
|
||||
/// <summary>
|
||||
/// The type of the APC that handles advisors with object role <see cref="ObjectRole.ROLE_INFRASTRUCTURE"/>.
|
||||
/// </summary>
|
||||
private static readonly Type InfrastructureAutoProxyCreatorType = typeof(InfrastructureAdvisorAutoProxyCreator);
|
||||
|
||||
/// <summary>
|
||||
/// Registers the internal auto proxy creator if necessary.
|
||||
/// </summary>
|
||||
/// <param name="parserContext">The parser context.</param>
|
||||
/// <param name="sourceElement">The source element.</param>
|
||||
public static void RegisterAutoProxyCreatorIfNecessary(ParserContext parserContext, XmlElement sourceElement)
|
||||
{
|
||||
/// <summary>
|
||||
/// The object name of the internally managed auto-proxy creator.
|
||||
/// </summary>
|
||||
public static readonly string AUTO_PROXY_CREATOR_OBJECT_NAME = "Spring.Aop.Config.InternalAutoProxyCreator";
|
||||
AssertUtils.ArgumentNotNull(parserContext, "parserContext");
|
||||
IObjectDefinitionRegistry registry = parserContext.Registry;
|
||||
RegisterAutoProxyCreatorIfNecessary(registry);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type of the APC that handles advisors with object role <see cref="ObjectRole.ROLE_INFRASTRUCTURE"/>.
|
||||
/// </summary>
|
||||
private static readonly Type InfrastructureAutoProxyCreatorType = typeof(InfrastructureAdvisorAutoProxyCreator);
|
||||
/// <summary>
|
||||
/// Registers the internal auto proxy creator if necessary.
|
||||
/// </summary>
|
||||
public static void RegisterAutoProxyCreatorIfNecessary(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(registry, "registry");
|
||||
|
||||
/// <summary>
|
||||
/// Registers the internal auto proxy creator if necessary.
|
||||
/// </summary>
|
||||
/// <param name="parserContext">The parser context.</param>
|
||||
/// <param name="sourceElement">The source element.</param>
|
||||
public static void RegisterAutoProxyCreatorIfNecessary(ParserContext parserContext, XmlElement sourceElement)
|
||||
if (!registry.ContainsObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME))
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(parserContext, "parserContext");
|
||||
IObjectDefinitionRegistry registry = parserContext.Registry;
|
||||
RegisterAutoProxyCreatorIfNecessary(registry);
|
||||
RootObjectDefinition objectDefinition = new RootObjectDefinition(InfrastructureAutoProxyCreatorType);
|
||||
objectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
objectDefinition.PropertyValues.Add("order", int.MaxValue);
|
||||
registry.RegisterObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME, objectDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the internal auto proxy creator if necessary.
|
||||
/// </summary>
|
||||
public static void RegisterAutoProxyCreatorIfNecessary(IObjectDefinitionRegistry registry)
|
||||
/// <summary>
|
||||
/// Forces the auto proxy creator to use decorator proxy.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry.</param>
|
||||
public static void ForceAutoProxyCreatorToUseDecoratorProxy(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
if (registry.ContainsObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME))
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(registry, "registry");
|
||||
|
||||
if (!registry.ContainsObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME))
|
||||
{
|
||||
RootObjectDefinition objectDefinition = new RootObjectDefinition(InfrastructureAutoProxyCreatorType);
|
||||
objectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
objectDefinition.PropertyValues.Add("order", int.MaxValue);
|
||||
registry.RegisterObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME, objectDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces the auto proxy creator to use decorator proxy.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry.</param>
|
||||
public static void ForceAutoProxyCreatorToUseDecoratorProxy(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
if (registry.ContainsObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME))
|
||||
{
|
||||
IObjectDefinition definition = registry.GetObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME);
|
||||
definition.PropertyValues.Add("ProxyTargetType", true);
|
||||
}
|
||||
IObjectDefinition definition = registry.GetObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME);
|
||||
definition.PropertyValues.Add("ProxyTargetType", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
using System.Xml;
|
||||
using Spring.Aop.Support;
|
||||
using Spring.Objects.Factory.Config;
|
||||
@@ -26,134 +25,129 @@ using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Config
|
||||
namespace Spring.Aop.Config;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IObjectDefinitionParser"/> for the <code><aop:config></code> tag.
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
public class ConfigObjectDefinitionParser : IObjectDefinitionParser
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IObjectDefinitionParser"/> for the <code><aop:config></code> tag.
|
||||
/// The '<code>proxy-target-type</code>' attribute
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
public class ConfigObjectDefinitionParser : IObjectDefinitionParser
|
||||
private static readonly string PROXY_TARGET_TYPE = "proxy-target-type";
|
||||
|
||||
private static readonly string ID = "id";
|
||||
|
||||
private static readonly string ORDER_PROPERTY = "order";
|
||||
|
||||
private static readonly string ADVICE_REF = "advice-ref";
|
||||
|
||||
private static readonly string ADVICE_OBJECT_NAME = "adviceObjectName";
|
||||
|
||||
private static readonly string POINTCUT_REF = "pointcut-ref";
|
||||
|
||||
#region IObjectDefinitionParser Members
|
||||
|
||||
/// <summary>
|
||||
/// Parse the specified XmlElement and register the resulting
|
||||
/// ObjectDefinitions with the <see cref="ParserContext.Registry"/> IObjectDefinitionRegistry
|
||||
/// embedded in the supplied <see cref="ParserContext"/>
|
||||
/// </summary>
|
||||
/// <param name="element">The element to be parsed.</param>
|
||||
/// <param name="parserContext">The object encapsulating the current state of the parsing process.
|
||||
/// Provides access to a IObjectDefinitionRegistry</param>
|
||||
/// <returns>The primary object definition.</returns>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method is never invoked if the parser is namespace aware
|
||||
/// and was called to process the root node.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
|
||||
{
|
||||
/// <summary>
|
||||
/// The '<code>proxy-target-type</code>' attribute
|
||||
/// </summary>
|
||||
private static readonly string PROXY_TARGET_TYPE = "proxy-target-type";
|
||||
ConfigureAutoProxyCreator(parserContext, element);
|
||||
XmlNodeList advisorNodes = element.GetElementsByTagName("advisor", element.NamespaceURI);
|
||||
|
||||
private static readonly string ID = "id";
|
||||
|
||||
private static readonly string ORDER_PROPERTY = "order";
|
||||
|
||||
private static readonly string ADVICE_REF = "advice-ref";
|
||||
|
||||
private static readonly string ADVICE_OBJECT_NAME = "adviceObjectName";
|
||||
|
||||
private static readonly string POINTCUT_REF = "pointcut-ref";
|
||||
|
||||
|
||||
#region IObjectDefinitionParser Members
|
||||
|
||||
/// <summary>
|
||||
/// Parse the specified XmlElement and register the resulting
|
||||
/// ObjectDefinitions with the <see cref="ParserContext.Registry"/> IObjectDefinitionRegistry
|
||||
/// embedded in the supplied <see cref="ParserContext"/>
|
||||
/// </summary>
|
||||
/// <param name="element">The element to be parsed.</param>
|
||||
/// <param name="parserContext">The object encapsulating the current state of the parsing process.
|
||||
/// Provides access to a IObjectDefinitionRegistry</param>
|
||||
/// <returns>The primary object definition.</returns>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method is never invoked if the parser is namespace aware
|
||||
/// and was called to process the root node.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
|
||||
//XmlNodeList advisorNodes = element.SelectNodes("*[local-name()='advisor' and namespace-uri()='" + element.NamespaceURI + "']");
|
||||
foreach (XmlElement advisorElement in advisorNodes)
|
||||
{
|
||||
ConfigureAutoProxyCreator(parserContext, element);
|
||||
XmlNodeList advisorNodes = element.GetElementsByTagName("advisor", element.NamespaceURI);
|
||||
ParseAdvisor(advisorElement, parserContext);
|
||||
}
|
||||
|
||||
//XmlNodeList advisorNodes = element.SelectNodes("*[local-name()='advisor' and namespace-uri()='" + element.NamespaceURI + "']");
|
||||
foreach (XmlElement advisorElement in advisorNodes)
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the supplied advisor element and registers the resulting <see cref="IAdvisor"/>
|
||||
/// </summary>
|
||||
/// <param name="advisorElement">The advisor element.</param>
|
||||
/// <param name="parserContext">The parser context.</param>
|
||||
private void ParseAdvisor(XmlElement advisorElement, ParserContext parserContext)
|
||||
{
|
||||
AbstractObjectDefinition advisorDef = CreateAdvisorObjectDefinition(advisorElement, parserContext);
|
||||
string id = advisorElement.GetAttribute(ID);
|
||||
|
||||
string pointcutObjectName = ParsePointcutProperty(advisorElement, parserContext);
|
||||
advisorDef.PropertyValues.Add(POINTCUT_REF, new RuntimeObjectReference(pointcutObjectName));
|
||||
string advisorObjectName = id;
|
||||
if (StringUtils.HasText(advisorObjectName))
|
||||
{
|
||||
parserContext.Registry.RegisterObjectDefinition(advisorObjectName, advisorDef);
|
||||
}
|
||||
else
|
||||
{
|
||||
parserContext.ReaderContext.RegisterWithGeneratedName(advisorDef);
|
||||
}
|
||||
}
|
||||
|
||||
private string ParsePointcutProperty(XmlElement element, ParserContext parserContext)
|
||||
{
|
||||
if (element.HasAttribute(POINTCUT_REF))
|
||||
{
|
||||
string pointcutRef = element.GetAttribute(POINTCUT_REF);
|
||||
if (!StringUtils.HasText(pointcutRef))
|
||||
{
|
||||
ParseAdvisor(advisorElement, parserContext);
|
||||
parserContext.ReaderContext.ReportException(element, "advisor", "'pointcut-ref' attribute contains empty value.");
|
||||
}
|
||||
|
||||
return pointcutRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
parserContext.ReaderContext.ReportException(element, "advisor", "'must define 'pointcut-ref' on <advisor> tag.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the supplied advisor element and registers the resulting <see cref="IAdvisor"/>
|
||||
/// </summary>
|
||||
/// <param name="advisorElement">The advisor element.</param>
|
||||
/// <param name="parserContext">The parser context.</param>
|
||||
private void ParseAdvisor(XmlElement advisorElement, ParserContext parserContext)
|
||||
{
|
||||
AbstractObjectDefinition advisorDef = CreateAdvisorObjectDefinition(advisorElement, parserContext);
|
||||
string id = advisorElement.GetAttribute(ID);
|
||||
|
||||
string pointcutObjectName = ParsePointcutProperty(advisorElement, parserContext);
|
||||
advisorDef.PropertyValues.Add(POINTCUT_REF, new RuntimeObjectReference(pointcutObjectName));
|
||||
string advisorObjectName = id;
|
||||
if (StringUtils.HasText(advisorObjectName))
|
||||
{
|
||||
parserContext.Registry.RegisterObjectDefinition(advisorObjectName, advisorDef);
|
||||
}
|
||||
else
|
||||
{
|
||||
parserContext.ReaderContext.RegisterWithGeneratedName(advisorDef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string ParsePointcutProperty(XmlElement element, ParserContext parserContext)
|
||||
{
|
||||
if (element.HasAttribute(POINTCUT_REF))
|
||||
{
|
||||
string pointcutRef = element.GetAttribute(POINTCUT_REF);
|
||||
if (!StringUtils.HasText(pointcutRef))
|
||||
{
|
||||
parserContext.ReaderContext.ReportException(element, "advisor", "'pointcut-ref' attribute contains empty value.");
|
||||
}
|
||||
return pointcutRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
parserContext.ReaderContext.ReportException(element, "advisor", "'must define 'pointcut-ref' on <advisor> tag.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private AbstractObjectDefinition CreateAdvisorObjectDefinition(XmlElement advisorElement, ParserContext parserContext)
|
||||
{
|
||||
ObjectDefinitionBuilder advisorDefinitionBuilder =
|
||||
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof(DefaultObjectFactoryPointcutAdvisor));
|
||||
advisorDefinitionBuilder.RawObjectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
|
||||
if (advisorElement.HasAttribute(ORDER_PROPERTY))
|
||||
{
|
||||
advisorDefinitionBuilder.AddPropertyValue(ORDER_PROPERTY, advisorElement.GetAttribute(ORDER_PROPERTY));
|
||||
}
|
||||
|
||||
advisorDefinitionBuilder.AddPropertyValue(ADVICE_OBJECT_NAME, advisorElement.GetAttribute(ADVICE_REF));
|
||||
|
||||
|
||||
return advisorDefinitionBuilder.ObjectDefinition;
|
||||
}
|
||||
|
||||
|
||||
private static void ConfigureAutoProxyCreator(ParserContext parserContext, XmlElement element)
|
||||
{
|
||||
AopNamespaceUtils.RegisterAutoProxyCreatorIfNecessary(parserContext, element);
|
||||
|
||||
bool proxyTargetClass =
|
||||
parserContext.ParserHelper.IsTrueStringValue(element.GetAttribute(PROXY_TARGET_TYPE));
|
||||
if (proxyTargetClass)
|
||||
{
|
||||
AopNamespaceUtils.ForceAutoProxyCreatorToUseDecoratorProxy(parserContext.Registry);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
private AbstractObjectDefinition CreateAdvisorObjectDefinition(XmlElement advisorElement, ParserContext parserContext)
|
||||
{
|
||||
ObjectDefinitionBuilder advisorDefinitionBuilder =
|
||||
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof(DefaultObjectFactoryPointcutAdvisor));
|
||||
advisorDefinitionBuilder.RawObjectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
|
||||
if (advisorElement.HasAttribute(ORDER_PROPERTY))
|
||||
{
|
||||
advisorDefinitionBuilder.AddPropertyValue(ORDER_PROPERTY, advisorElement.GetAttribute(ORDER_PROPERTY));
|
||||
}
|
||||
|
||||
advisorDefinitionBuilder.AddPropertyValue(ADVICE_OBJECT_NAME, advisorElement.GetAttribute(ADVICE_REF));
|
||||
|
||||
return advisorDefinitionBuilder.ObjectDefinition;
|
||||
}
|
||||
|
||||
private static void ConfigureAutoProxyCreator(ParserContext parserContext, XmlElement element)
|
||||
{
|
||||
AopNamespaceUtils.RegisterAutoProxyCreatorIfNecessary(parserContext, element);
|
||||
|
||||
bool proxyTargetClass =
|
||||
parserContext.ParserHelper.IsTrueStringValue(element.GetAttribute(PROXY_TARGET_TYPE));
|
||||
if (proxyTargetClass)
|
||||
{
|
||||
AopNamespaceUtils.ForceAutoProxyCreatorToUseDecoratorProxy(parserContext.Registry);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<xsd:schema xmlns="http://www.springframework.net/aop"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:objects="http://www.springframework.net"
|
||||
xmlns:tool="http://www.springframework.net/tool"
|
||||
targetNamespace="http://www.springframework.net/aop"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:objects="http://www.springframework.net"
|
||||
xmlns:tool="http://www.springframework.net/tool"
|
||||
targetNamespace="http://www.springframework.net/aop"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.net"/>
|
||||
<xsd:import namespace="http://www.springframework.net/tool"/>
|
||||
<xsd:import namespace="http://www.springframework.net" />
|
||||
<xsd:import namespace="http://www.springframework.net/tool" />
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for the Spring Framework's AOP support.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="config">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
<xsd:element name="config">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A section (compartmentalization) of AOP-specific configuration (including
|
||||
aspects, pointcuts, etc).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="advisor" type="advisorType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="net:Spring.Aop.IAdvisor"><![CDATA[
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="advisor" type="advisorType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="net:Spring.Aop.IAdvisor"><![CDATA[
|
||||
A named advisor definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="proxy-target-type" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="proxy-target-type" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Are decorator-based (inheritance) proxies to be created? By default, composition-based proxies are created.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="advisorType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="Spring.Aop.IAdvisor"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<!-- Rick : ID type written explicitly as opposed to being imported (c.f. [SPR-2290] -->
|
||||
<xsd:attribute name="id" type="xsd:ID"/>
|
||||
<xsd:attribute name="advice-ref" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
<xsd:complexType name="advisorType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="Spring.Aop.IAdvisor" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<!-- Rick : ID type written explicitly as opposed to being imported (c.f. [SPR-2290] -->
|
||||
<xsd:attribute name="id" type="xsd:ID" />
|
||||
<xsd:attribute name="advice-ref" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to an advice bean.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.aop.Advisor"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="pointcut-ref" type="pointcutRefType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.aop.Advisor" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="pointcut-ref" type="pointcutRefType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to a pointcut definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:int">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:int">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
|
||||
Controls the ordering of the execution of this advice when multiple
|
||||
advice executes at a specific joinpoint.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="pointcutRefType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.aop.Pointcut"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="pointcutRefType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.aop.Pointcut" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
|
||||
@@ -23,300 +23,302 @@
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using AopAlliance.Intercept;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Convenience base class for <see cref="AopAlliance.Intercept.IMethodInvocation"/>
|
||||
/// implementations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses can override the
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation.InvokeJoinpoint()"/>
|
||||
/// method to change this behavior, so this is a useful/ base class for
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInvocation"/> implementations.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <author>Rick Evans (.NET)</author>
|
||||
/// <author>Bruno Baia (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractMethodInvocation : IMethodInvocation
|
||||
{
|
||||
/// <summary>
|
||||
/// Convenience base class for <see cref="AopAlliance.Intercept.IMethodInvocation"/>
|
||||
/// implementations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses can override the
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation.InvokeJoinpoint()"/>
|
||||
/// method to change this behavior, so this is a useful/ base class for
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInvocation"/> implementations.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <author>Rick Evans (.NET)</author>
|
||||
/// <author>Bruno Baia (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractMethodInvocation : IMethodInvocation
|
||||
{
|
||||
/// <summary>
|
||||
/// The arguments (if any = may be <see lang="null"/>) to the method
|
||||
/// that is to be invoked.
|
||||
/// </summary>
|
||||
private object[] arguments;
|
||||
/// <summary>
|
||||
/// The arguments (if any = may be <see lang="null"/>) to the method
|
||||
/// that is to be invoked.
|
||||
/// </summary>
|
||||
private object[] arguments;
|
||||
|
||||
/// <summary>
|
||||
/// The target object that the method is to be invoked on.
|
||||
/// </summary>
|
||||
private readonly object target;
|
||||
/// <summary>
|
||||
/// The target object that the method is to be invoked on.
|
||||
/// </summary>
|
||||
private readonly object target;
|
||||
|
||||
/// <summary>
|
||||
/// The AOP proxy for the target object.
|
||||
/// </summary>
|
||||
private object proxy;
|
||||
/// <summary>
|
||||
/// The AOP proxy for the target object.
|
||||
/// </summary>
|
||||
private object proxy;
|
||||
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked.
|
||||
/// </summary>
|
||||
private MethodInfo method;
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked.
|
||||
/// </summary>
|
||||
private MethodInfo method;
|
||||
|
||||
/// <summary>
|
||||
/// The list of <see cref="AopAlliance.Intercept.IMethodInterceptor"/> and
|
||||
/// <cref see="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// that need dynamic checks.
|
||||
/// </summary>
|
||||
private IList interceptors;
|
||||
/// <summary>
|
||||
/// The list of <see cref="AopAlliance.Intercept.IMethodInterceptor"/> and
|
||||
/// <cref see="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// that need dynamic checks.
|
||||
/// </summary>
|
||||
private IList interceptors;
|
||||
|
||||
/// <summary>
|
||||
/// The declaring type of the method that is to be invoked.
|
||||
/// </summary>
|
||||
private Type targetType;
|
||||
/// <summary>
|
||||
/// The declaring type of the method that is to be invoked.
|
||||
/// </summary>
|
||||
private Type targetType;
|
||||
|
||||
/// <summary>
|
||||
/// The index from 0 of the current interceptor we're invoking.
|
||||
/// </summary>
|
||||
private int currentInterceptorIndex;
|
||||
/// <summary>
|
||||
/// The index from 0 of the current interceptor we're invoking.
|
||||
/// </summary>
|
||||
private int currentInterceptorIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an abstract class, and as such exposes no publicly visible
|
||||
/// constructors.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// <note type="implementnotes">
|
||||
/// The <paramref name="interceptors"/> list can also contain any
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>s
|
||||
/// that need evaluation at runtime.
|
||||
/// <see cref="Spring.Aop.IMethodMatcher"/>s included in an
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// must already have been found to have matched as far as was possible
|
||||
/// <b>statically</b>. Passing an array might be about 10% faster, but
|
||||
/// would complicate the code, and it would work only for static
|
||||
/// pointcuts.
|
||||
/// </note>
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="proxy">The AOP proxy.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="method">the target method.</param>
|
||||
/// <param name="arguments">The target method's arguments.</param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.</param>
|
||||
/// <param name="interceptors">
|
||||
/// The list of interceptors that are to be applied. May be
|
||||
/// <cref lang="null"/>.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the <paramref name="target"/> is <see lang="null"/>.
|
||||
/// </exception>
|
||||
protected AbstractMethodInvocation(object proxy, object target,
|
||||
MethodInfo method, object[] arguments, Type targetType, IList interceptors)
|
||||
{
|
||||
// EE: There is not necessarily always a target - e.g. for DynamicEntities
|
||||
// moved this check to InvokeJoinpoint()
|
||||
AssertUtils.ArgumentNotNull(method, "method");
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an abstract class, and as such exposes no publicly visible
|
||||
/// constructors.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// <note type="implementnotes">
|
||||
/// The <paramref name="interceptors"/> list can also contain any
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>s
|
||||
/// that need evaluation at runtime.
|
||||
/// <see cref="Spring.Aop.IMethodMatcher"/>s included in an
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// must already have been found to have matched as far as was possible
|
||||
/// <b>statically</b>. Passing an array might be about 10% faster, but
|
||||
/// would complicate the code, and it would work only for static
|
||||
/// pointcuts.
|
||||
/// </note>
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="proxy">The AOP proxy.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="method">the target method.</param>
|
||||
/// <param name="arguments">The target method's arguments.</param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.</param>
|
||||
/// <param name="interceptors">
|
||||
/// The list of interceptors that are to be applied. May be
|
||||
/// <cref lang="null"/>.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the <paramref name="target"/> is <see lang="null"/>.
|
||||
/// </exception>
|
||||
protected AbstractMethodInvocation(object proxy, object target,
|
||||
MethodInfo method, object[] arguments, Type targetType, IList interceptors)
|
||||
{
|
||||
// EE: There is not necessarily always a target - e.g. for DynamicEntities
|
||||
// moved this check to InvokeJoinpoint()
|
||||
AssertUtils.ArgumentNotNull(method, "method");
|
||||
|
||||
this.proxy = proxy;
|
||||
this.target = target;
|
||||
this.method = method;
|
||||
this.targetType = targetType;
|
||||
this.arguments = arguments;
|
||||
this.interceptors = interceptors;
|
||||
}
|
||||
this.proxy = proxy;
|
||||
this.target = target;
|
||||
this.method = method;
|
||||
this.targetType = targetType;
|
||||
this.arguments = arguments;
|
||||
this.interceptors = interceptors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the method invocation that is to be invoked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// May or may not correspond with a method invoked on an underlying
|
||||
/// implementation of that interface.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInvocation.Method"/>
|
||||
public virtual MethodInfo Method
|
||||
{
|
||||
get { return method; }
|
||||
protected set { method = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the method invocation that is to be invoked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// May or may not correspond with a method invoked on an underlying
|
||||
/// implementation of that interface.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInvocation.Method"/>
|
||||
public virtual MethodInfo Method
|
||||
{
|
||||
get { return method; }
|
||||
protected set { method = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the static part of this joinpoint.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The proxied member's information.
|
||||
/// </value>
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.StaticPart"/>
|
||||
public virtual MemberInfo StaticPart
|
||||
{
|
||||
get { return Method; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the static part of this joinpoint.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The proxied member's information.
|
||||
/// </value>
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.StaticPart"/>
|
||||
public virtual MemberInfo StaticPart
|
||||
{
|
||||
get { return Method; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the proxy that this interception was made through.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The proxy that this interception was made through.
|
||||
/// </value>
|
||||
public virtual object Proxy
|
||||
{
|
||||
get { return this.proxy; }
|
||||
protected set { this.proxy = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the target object for the invocation.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target object for this method invocation.
|
||||
/// </value>
|
||||
public virtual object Target
|
||||
{
|
||||
get { return this.target; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the type of the target object.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type of the target object.
|
||||
/// </value>
|
||||
public virtual Type TargetType
|
||||
{
|
||||
get { return this.targetType; }
|
||||
protected set { this.targetType = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the proxy that this interception was made through.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The proxy that this interception was made through.
|
||||
/// </value>
|
||||
public virtual object Proxy
|
||||
{
|
||||
get { return this.proxy; }
|
||||
protected set { this.proxy = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the arguments (if any - may be <cref lang="null"/>)
|
||||
/// to the method that is to be invoked.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The arguments (if any - may be <cref lang="null"/>) to the
|
||||
/// method that is to be invoked.
|
||||
/// </value>
|
||||
/// <see cref="AopAlliance.Intercept.IInvocation.Arguments"/>
|
||||
public virtual object[] Arguments
|
||||
{
|
||||
get { return this.arguments; }
|
||||
set { this.arguments = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the target object for the invocation.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target object for this method invocation.
|
||||
/// </value>
|
||||
public virtual object Target
|
||||
{
|
||||
get { return this.target; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The list of method interceptors.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// May be <see lang="null"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual IList Interceptors
|
||||
{
|
||||
get { return this.interceptors; }
|
||||
set { this.interceptors = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the type of the target object.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type of the target object.
|
||||
/// </value>
|
||||
public virtual Type TargetType
|
||||
{
|
||||
get { return this.targetType; }
|
||||
protected set { this.targetType = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target object.
|
||||
/// </summary>
|
||||
public virtual object This
|
||||
{
|
||||
get { return this.target; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets and sets the arguments (if any - may be <cref lang="null"/>)
|
||||
/// to the method that is to be invoked.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The arguments (if any - may be <cref lang="null"/>) to the
|
||||
/// method that is to be invoked.
|
||||
/// </value>
|
||||
/// <see cref="AopAlliance.Intercept.IInvocation.Arguments"/>
|
||||
public virtual object[] Arguments
|
||||
{
|
||||
get { return this.arguments; }
|
||||
set { this.arguments = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The index from 0 of the current interceptor we're invoking.
|
||||
/// </summary>
|
||||
protected int CurrentInterceptorIndex
|
||||
{
|
||||
get { return currentInterceptorIndex; }
|
||||
set { currentInterceptorIndex = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The list of method interceptors.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// May be <see lang="null"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual IList Interceptors
|
||||
{
|
||||
get { return this.interceptors; }
|
||||
set { this.interceptors = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proceeds to the next interceptor in the chain.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The return value of the method invocation.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If any of the interceptors at the joinpoint throws an exception.
|
||||
/// </exception>
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/>
|
||||
public virtual object Proceed()
|
||||
{
|
||||
if (this.interceptors == null ||
|
||||
this.currentInterceptorIndex == this.interceptors.Count)
|
||||
{
|
||||
AssertJoinpoint();
|
||||
return InvokeJoinpoint();
|
||||
}
|
||||
object interceptor = this.interceptors[this.currentInterceptorIndex];
|
||||
InterceptorAndDynamicMethodMatcher dynamicMatcher
|
||||
= interceptor as InterceptorAndDynamicMethodMatcher;
|
||||
IMethodInvocation nextInvocation = PrepareMethodInvocationForProceed(this);
|
||||
if (dynamicMatcher != null)
|
||||
{
|
||||
// evaluate dynamic method matcher here: static part will already have
|
||||
// been evaluated and found to match...
|
||||
if (dynamicMatcher.MethodMatcher.Matches(
|
||||
/// <summary>
|
||||
/// Gets the target object.
|
||||
/// </summary>
|
||||
public virtual object This
|
||||
{
|
||||
get { return this.target; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The index from 0 of the current interceptor we're invoking.
|
||||
/// </summary>
|
||||
protected int CurrentInterceptorIndex
|
||||
{
|
||||
get { return currentInterceptorIndex; }
|
||||
set { currentInterceptorIndex = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proceeds to the next interceptor in the chain.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The return value of the method invocation.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If any of the interceptors at the joinpoint throws an exception.
|
||||
/// </exception>
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/>
|
||||
public virtual object Proceed()
|
||||
{
|
||||
if (this.interceptors == null ||
|
||||
this.currentInterceptorIndex == this.interceptors.Count)
|
||||
{
|
||||
AssertJoinpoint();
|
||||
return InvokeJoinpoint();
|
||||
}
|
||||
|
||||
object interceptor = this.interceptors[this.currentInterceptorIndex];
|
||||
InterceptorAndDynamicMethodMatcher dynamicMatcher
|
||||
= interceptor as InterceptorAndDynamicMethodMatcher;
|
||||
IMethodInvocation nextInvocation = PrepareMethodInvocationForProceed(this);
|
||||
if (dynamicMatcher != null)
|
||||
{
|
||||
// evaluate dynamic method matcher here: static part will already have
|
||||
// been evaluated and found to match...
|
||||
if (dynamicMatcher.MethodMatcher.Matches(
|
||||
nextInvocation.Method, nextInvocation.TargetType, nextInvocation.Arguments))
|
||||
{
|
||||
return dynamicMatcher.Interceptor.Invoke(nextInvocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dynamic match failed; skip this interceptor and invoke the next in the chain...
|
||||
return nextInvocation.Proceed();
|
||||
}
|
||||
{
|
||||
return dynamicMatcher.Interceptor.Invoke(nextInvocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's an interceptor so we just invoke it: the pointcut will have
|
||||
// been evaluated statically before this object was constructed...
|
||||
return ((IMethodInterceptor)interceptor).Invoke(nextInvocation);
|
||||
// dynamic match failed; skip this interceptor and invoke the next in the chain...
|
||||
return nextInvocation.Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a new <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance
|
||||
/// for the next Proceed method call.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The current <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The new <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance to use.
|
||||
/// </returns>
|
||||
/// <see cref="Spring.Aop.Framework.ReflectiveMethodInvocation.PrepareMethodInvocationForProceed"/>
|
||||
protected abstract IMethodInvocation PrepareMethodInvocationForProceed(
|
||||
IMethodInvocation invocation);
|
||||
|
||||
/// <summary>
|
||||
/// Performs sanity checks, whether the actual joinpoint may be invoked
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default checks that the underlying target is not null and the called method is implemented
|
||||
/// by the target's type.
|
||||
/// </remarks>
|
||||
/// <exception cref="ArgumentNullException">if <see cref="target"/> is <c>null</c>.</exception>
|
||||
/// <exception cref="NotSupportedException">if the <see cref="target"/> 's type does not implement <see cref="method"/>.</exception>
|
||||
protected virtual void AssertJoinpoint()
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(target, "target");
|
||||
// it's an interceptor so we just invoke it: the pointcut will have
|
||||
// been evaluated statically before this object was constructed...
|
||||
return ((IMethodInterceptor) interceptor).Invoke(nextInvocation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a new <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance
|
||||
/// for the next Proceed method call.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The current <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The new <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance to use.
|
||||
/// </returns>
|
||||
/// <see cref="Spring.Aop.Framework.ReflectiveMethodInvocation.PrepareMethodInvocationForProceed"/>
|
||||
protected abstract IMethodInvocation PrepareMethodInvocationForProceed(
|
||||
IMethodInvocation invocation);
|
||||
|
||||
/// <summary>
|
||||
/// Performs sanity checks, whether the actual joinpoint may be invoked
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default checks that the underlying target is not null and the called method is implemented
|
||||
/// by the target's type.
|
||||
/// </remarks>
|
||||
/// <exception cref="ArgumentNullException">if <see cref="target"/> is <c>null</c>.</exception>
|
||||
/// <exception cref="NotSupportedException">if the <see cref="target"/> 's type does not implement <see cref="method"/>.</exception>
|
||||
protected virtual void AssertJoinpoint()
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(target, "target");
|
||||
// if (this.method != null
|
||||
// && !this.method.DeclaringType.IsAssignableFrom(target.GetType()))
|
||||
// {
|
||||
@@ -324,56 +326,56 @@ namespace Spring.Aop.Framework
|
||||
// // Since no interceptor has handled the call, we throw a sensible exception here.
|
||||
// throw new NotSupportedException(string.Format("Interface method '{0}.{1}()' was not handled by any interceptor and the underlying target type '{2}' does not implement this method.", method.DeclaringType.FullName, method.Name, target.GetType().FullName));
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the joinpoint.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses can override this to use custom invocation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The return value of the invocation of the joinpoint.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If invoking the joinpoint resulted in an exception.
|
||||
/// </exception>
|
||||
/// <see cref="Spring.Aop.Framework.ReflectiveMethodInvocation.InvokeJoinpoint"/>
|
||||
protected abstract object InvokeJoinpoint();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="System.String"/> that represents the current
|
||||
/// invocation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// <note type="implementnotes">
|
||||
/// Does <b>not</b> invoke <see cref="System.Object.ToString()"/> on the
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation.This"/> target
|
||||
/// object, as that too may be proxied.
|
||||
/// </note>
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents the current invocation.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder("Invocation: method '");
|
||||
buffer.Append(Method.Name).Append("', ").Append("arguments ");
|
||||
buffer.Append(Arguments != null ? StringUtils.CollectionToCommaDelimitedString(Arguments) : "[none]");
|
||||
buffer.Append("; ");
|
||||
if (Target == null)
|
||||
{
|
||||
buffer.Append("target is null.");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.Append("target is of Type [").Append(TargetType.FullName).Append(']');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the joinpoint.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses can override this to use custom invocation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The return value of the invocation of the joinpoint.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If invoking the joinpoint resulted in an exception.
|
||||
/// </exception>
|
||||
/// <see cref="Spring.Aop.Framework.ReflectiveMethodInvocation.InvokeJoinpoint"/>
|
||||
protected abstract object InvokeJoinpoint();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="System.String"/> that represents the current
|
||||
/// invocation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// <note type="implementnotes">
|
||||
/// Does <b>not</b> invoke <see cref="System.Object.ToString()"/> on the
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation.This"/> target
|
||||
/// object, as that too may be proxied.
|
||||
/// </note>
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents the current invocation.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder("Invocation: method '");
|
||||
buffer.Append(Method.Name).Append("', ").Append("arguments ");
|
||||
buffer.Append(Arguments != null ? StringUtils.CollectionToCommaDelimitedString(Arguments) : "[none]");
|
||||
buffer.Append("; ");
|
||||
if (Target == null)
|
||||
{
|
||||
buffer.Append("target is null.");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.Append("target is of Type [").Append(TargetType.FullName).Append(']');
|
||||
}
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,85 +24,85 @@ using Spring.Objects.Factory.Config;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Objects.Factory.Config.IObjectPostProcessor"/> implementation
|
||||
/// that registers instances of any non-default
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> instances with the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.GlobalAdvisorAdapterRegistry"/>
|
||||
/// singleton.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The only requirement for it to work is that it needs to be defined
|
||||
/// in an application context along with any arbitrary "non-native" Spring.NET
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> instances that need
|
||||
/// to be recognized by Spring.NET's AOP framework.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Dmitriy Kopylenko</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public class AdvisorAdapterRegistrationManager : IObjectPostProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Objects.Factory.Config.IObjectPostProcessor"/> implementation
|
||||
/// that registers instances of any non-default
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> instances with the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.GlobalAdvisorAdapterRegistry"/>
|
||||
/// singleton.
|
||||
/// Apply this <see cref="Spring.Objects.Factory.Config.IObjectPostProcessor"/>
|
||||
/// to the given new object instance <i>before</i> any object initialization callbacks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The only requirement for it to work is that it needs to be defined
|
||||
/// in an application context along with any arbitrary "non-native" Spring.NET
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> instances that need
|
||||
/// to be recognized by Spring.NET's AOP framework.
|
||||
/// Does nothing, simply returns the supplied <paramref name="instance"/> as is.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Dmitriy Kopylenko</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public class AdvisorAdapterRegistrationManager : IObjectPostProcessor
|
||||
/// <param name="instance">
|
||||
/// The new object instance.
|
||||
/// </param>
|
||||
/// <param name="name">
|
||||
/// The name of the object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The object instance to use, either the original or a wrapped one.
|
||||
/// </returns>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of errors.
|
||||
/// </exception>
|
||||
public virtual object PostProcessBeforeInitialization(object instance, string name)
|
||||
{
|
||||
/// <summary>
|
||||
/// Apply this <see cref="Spring.Objects.Factory.Config.IObjectPostProcessor"/>
|
||||
/// to the given new object instance <i>before</i> any object initialization callbacks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Does nothing, simply returns the supplied <paramref name="instance"/> as is.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="instance">
|
||||
/// The new object instance.
|
||||
/// </param>
|
||||
/// <param name="name">
|
||||
/// The name of the object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The object instance to use, either the original or a wrapped one.
|
||||
/// </returns>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of errors.
|
||||
/// </exception>
|
||||
public virtual object PostProcessBeforeInitialization(object instance, string name)
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply this <see cref="Spring.Objects.Factory.Config.IObjectPostProcessor"/> to the
|
||||
/// given new object instance <i>after</i> any object initialization callbacks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Registers the supplied <paramref name="instance"/> with the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.GlobalAdvisorAdapterRegistry"/>
|
||||
/// singleton if it is an <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>
|
||||
/// instance.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="instance">
|
||||
/// The new object instance.
|
||||
/// </param>
|
||||
/// <param name="objectName">
|
||||
/// The name of the object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The object instance to use, either the original or a wrapped one.
|
||||
/// </returns>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of errors.
|
||||
/// </exception>
|
||||
public virtual object PostProcessAfterInitialization(object instance, string objectName)
|
||||
{
|
||||
IAdvisorAdapter adapter = instance as IAdvisorAdapter;
|
||||
if (adapter != null)
|
||||
{
|
||||
return instance;
|
||||
GlobalAdvisorAdapterRegistry.Instance.RegisterAdvisorAdapter(adapter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply this <see cref="Spring.Objects.Factory.Config.IObjectPostProcessor"/> to the
|
||||
/// given new object instance <i>after</i> any object initialization callbacks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Registers the supplied <paramref name="instance"/> with the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.GlobalAdvisorAdapterRegistry"/>
|
||||
/// singleton if it is an <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>
|
||||
/// instance.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="instance">
|
||||
/// The new object instance.
|
||||
/// </param>
|
||||
/// <param name="objectName">
|
||||
/// The name of the object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The object instance to use, either the original or a wrapped one.
|
||||
/// </returns>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of errors.
|
||||
/// </exception>
|
||||
public virtual object PostProcessAfterInitialization(object instance, string objectName)
|
||||
{
|
||||
IAdvisorAdapter adapter = instance as IAdvisorAdapter;
|
||||
if (adapter != null)
|
||||
{
|
||||
GlobalAdvisorAdapterRegistry.Instance.RegisterAdvisorAdapter(adapter);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,55 +25,54 @@ using AopAlliance.Intercept;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> implementation
|
||||
/// to enable <see cref="Spring.Aop.IAfterReturningAdvice"/> to be used in the
|
||||
/// Spring.NET AOP framework.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
internal class AfterReturningAdviceAdapter : IAdvisorAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> implementation
|
||||
/// to enable <see cref="Spring.Aop.IAfterReturningAdvice"/> to be used in the
|
||||
/// Spring.NET AOP framework.
|
||||
/// Returns <see langword="true"/> if the supplied
|
||||
/// <paramref name="advice"/> is an instance of the
|
||||
/// <see cref="Spring.Aop.IAfterReturningAdvice"/> interface.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
internal class AfterReturningAdviceAdapter : IAdvisorAdapter
|
||||
/// <param name="advice">The advice to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="advice"/> is
|
||||
/// an instance of the <see cref="Spring.Aop.IAfterReturningAdvice"/> interface;
|
||||
/// <see langword="false"/> if not or if the supplied
|
||||
/// <paramref name="advice"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
public virtual bool SupportsAdvice(IAdvice advice)
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the supplied
|
||||
/// <paramref name="advice"/> is an instance of the
|
||||
/// <see cref="Spring.Aop.IAfterReturningAdvice"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="advice">The advice to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="advice"/> is
|
||||
/// an instance of the <see cref="Spring.Aop.IAfterReturningAdvice"/> interface;
|
||||
/// <see langword="false"/> if not or if the supplied
|
||||
/// <paramref name="advice"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
public virtual bool SupportsAdvice(IAdvice advice)
|
||||
{
|
||||
return advice is IAfterReturningAdvice;
|
||||
}
|
||||
return advice is IAfterReturningAdvice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.AfterReturningAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="advisor">
|
||||
/// The advisor exposing the <see cref="AopAlliance.Aop.IAdvice"/> that
|
||||
/// is to be wrapped.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> wrapped within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.AfterReturningAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </returns>
|
||||
public virtual IInterceptor GetInterceptor(IAdvisor advisor)
|
||||
{
|
||||
IAfterReturningAdvice advice = (IAfterReturningAdvice) advisor.Advice;
|
||||
return new AfterReturningAdviceInterceptor(advice);
|
||||
}
|
||||
/// <summary>
|
||||
/// Wraps the supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.AfterReturningAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="advisor">
|
||||
/// The advisor exposing the <see cref="AopAlliance.Aop.IAdvice"/> that
|
||||
/// is to be wrapped.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> wrapped within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.AfterReturningAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </returns>
|
||||
public virtual IInterceptor GetInterceptor(IAdvisor advisor)
|
||||
{
|
||||
IAfterReturningAdvice advice = (IAfterReturningAdvice) advisor.Advice;
|
||||
return new AfterReturningAdviceInterceptor(advice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,71 +25,70 @@ using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// Interceptor to wrap an <see cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// A more efficient alternative solution in cases where there is no
|
||||
/// interception advice and therefore no need to create an
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInvocation"/> object may be
|
||||
/// offered in future.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Used internally by the AOP framework: application developers should not need
|
||||
/// to use this class directly.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public sealed class AfterReturningAdviceInterceptor : IMethodInterceptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Interceptor to wrap an <see cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// A more efficient alternative solution in cases where there is no
|
||||
/// interception advice and therefore no need to create an
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInvocation"/> object may be
|
||||
/// offered in future.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Used internally by the AOP framework: application developers should not need
|
||||
/// to use this class directly.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public sealed class AfterReturningAdviceInterceptor : IMethodInterceptor
|
||||
{
|
||||
private IAfterReturningAdvice advice;
|
||||
private IAfterReturningAdvice advice;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.AfterReturningAdviceInterceptor"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The advice to be applied after a target method successfully
|
||||
/// returns.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="advice"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public AfterReturningAdviceInterceptor(IAfterReturningAdvice advice)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(advice, "advice");
|
||||
this.advice = advice;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.AfterReturningAdviceInterceptor"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The advice to be applied after a target method successfully
|
||||
/// returns.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="advice"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public AfterReturningAdviceInterceptor(IAfterReturningAdvice advice)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(advice, "advice");
|
||||
this.advice = advice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes interceptor after the target method successfully returns.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The method invocation that is being intercepted.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The result of the call to the
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/> method of
|
||||
/// the supplied <paramref name="invocation"/>; this return value may
|
||||
/// well have been intercepted by the interceptor.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If any of the interceptors in the chain or the target object itself
|
||||
/// throws an exception.
|
||||
/// </exception>
|
||||
public object Invoke(IMethodInvocation invocation)
|
||||
{
|
||||
object returnValue = invocation.Proceed();
|
||||
advice.AfterReturning(
|
||||
returnValue, invocation.Method, invocation.Arguments, invocation.This);
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Executes interceptor after the target method successfully returns.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The method invocation that is being intercepted.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The result of the call to the
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/> method of
|
||||
/// the supplied <paramref name="invocation"/>; this return value may
|
||||
/// well have been intercepted by the interceptor.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If any of the interceptors in the chain or the target object itself
|
||||
/// throws an exception.
|
||||
/// </exception>
|
||||
public object Invoke(IMethodInvocation invocation)
|
||||
{
|
||||
object returnValue = invocation.Proceed();
|
||||
advice.AfterReturning(
|
||||
returnValue, invocation.Method, invocation.Arguments, invocation.This);
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,55 +25,54 @@ using AopAlliance.Intercept;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> implementation
|
||||
/// to enable <see cref="Spring.Aop.IMethodBeforeAdvice"/> to be used in the
|
||||
/// Spring.NET AOP framework.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
internal class BeforeAdviceAdapter : IAdvisorAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> implementation
|
||||
/// to enable <see cref="Spring.Aop.IMethodBeforeAdvice"/> to be used in the
|
||||
/// Spring.NET AOP framework.
|
||||
/// Returns <see langword="true"/> if the supplied
|
||||
/// <paramref name="advice"/> is an instance of the
|
||||
/// <see cref="Spring.Aop.IMethodBeforeAdvice"/> interface.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
internal class BeforeAdviceAdapter : IAdvisorAdapter
|
||||
/// <param name="advice">The advice to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="advice"/> is
|
||||
/// an instance of the <see cref="Spring.Aop.IMethodBeforeAdvice"/> interface;
|
||||
/// <see langword="false"/> if not or if the supplied
|
||||
/// <paramref name="advice"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
public virtual bool SupportsAdvice(IAdvice advice)
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the supplied
|
||||
/// <paramref name="advice"/> is an instance of the
|
||||
/// <see cref="Spring.Aop.IMethodBeforeAdvice"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="advice">The advice to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="advice"/> is
|
||||
/// an instance of the <see cref="Spring.Aop.IMethodBeforeAdvice"/> interface;
|
||||
/// <see langword="false"/> if not or if the supplied
|
||||
/// <paramref name="advice"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
public virtual bool SupportsAdvice(IAdvice advice)
|
||||
{
|
||||
return advice is IMethodBeforeAdvice;
|
||||
}
|
||||
return advice is IMethodBeforeAdvice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.MethodBeforeAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="advisor">
|
||||
/// The advisor exposing the <see cref="AopAlliance.Aop.IAdvice"/> that
|
||||
/// is to be wrapped.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> wrapped within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.MethodBeforeAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </returns>
|
||||
public virtual IInterceptor GetInterceptor(IAdvisor advisor)
|
||||
{
|
||||
IMethodBeforeAdvice advice = (IMethodBeforeAdvice) advisor.Advice;
|
||||
return new MethodBeforeAdviceInterceptor(advice);
|
||||
}
|
||||
/// <summary>
|
||||
/// Wraps the supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.MethodBeforeAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="advisor">
|
||||
/// The advisor exposing the <see cref="AopAlliance.Aop.IAdvice"/> that
|
||||
/// is to be wrapped.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> wrapped within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.MethodBeforeAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </returns>
|
||||
public virtual IInterceptor GetInterceptor(IAdvisor advisor)
|
||||
{
|
||||
IMethodBeforeAdvice advice = (IMethodBeforeAdvice) advisor.Advice;
|
||||
return new MethodBeforeAdviceInterceptor(advice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,126 +26,131 @@ using Spring.Aop.Support;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapterRegistry"/>
|
||||
/// interface.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class DefaultAdvisorAdapterRegistry : IAdvisorAdapterRegistry
|
||||
{
|
||||
private readonly IList<IAdvisorAdapter> adapters = new List<IAdvisorAdapter>();
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.DefaultAdvisorAdapterRegistry"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This constructor will also register the well-known
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> types.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>
|
||||
public DefaultAdvisorAdapterRegistry()
|
||||
/// <summary>
|
||||
/// Default implementation of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapterRegistry"/>
|
||||
/// interface.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class DefaultAdvisorAdapterRegistry : IAdvisorAdapterRegistry
|
||||
{
|
||||
private readonly IList<IAdvisorAdapter> adapters = new List<IAdvisorAdapter>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.DefaultAdvisorAdapterRegistry"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This constructor will also register the well-known
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> types.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>
|
||||
public DefaultAdvisorAdapterRegistry()
|
||||
{
|
||||
// register well-known adapters...
|
||||
RegisterAdvisorAdapter(new BeforeAdviceAdapter());
|
||||
RegisterAdvisorAdapter(new AfterReturningAdviceAdapter());
|
||||
RegisterAdvisorAdapter(new ThrowsAdviceAdapter());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="Spring.Aop.IAdvisor"/> wrapping the supplied
|
||||
/// <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The object that should be an advice, such as
|
||||
/// <see cref="Spring.Aop.IBeforeAdvice"/> or
|
||||
/// <see cref="Spring.Aop.IThrowsAdvice"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An <see cref="Spring.Aop.IAdvisor"/> wrapping the supplied
|
||||
/// <paramref name="advice"/>. Never returns <cref lang="null"/>. If
|
||||
/// the <paramref name="advice"/> parameter is an
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>, it will simply be returned.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownAdviceTypeException">
|
||||
/// If no registered
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> can wrap
|
||||
/// the supplied <paramref name="advice"/>.
|
||||
/// </exception>
|
||||
public virtual IAdvisor Wrap(object advice)
|
||||
{
|
||||
if (advice is IAdvisor)
|
||||
{
|
||||
// register well-known adapters...
|
||||
RegisterAdvisorAdapter(new BeforeAdviceAdapter());
|
||||
RegisterAdvisorAdapter(new AfterReturningAdviceAdapter());
|
||||
RegisterAdvisorAdapter(new ThrowsAdviceAdapter());
|
||||
return (IAdvisor) advice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="Spring.Aop.IAdvisor"/> wrapping the supplied
|
||||
/// <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The object that should be an advice, such as
|
||||
/// <see cref="Spring.Aop.IBeforeAdvice"/> or
|
||||
/// <see cref="Spring.Aop.IThrowsAdvice"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An <see cref="Spring.Aop.IAdvisor"/> wrapping the supplied
|
||||
/// <paramref name="advice"/>. Never returns <cref lang="null"/>. If
|
||||
/// the <paramref name="advice"/> parameter is an
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>, it will simply be returned.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownAdviceTypeException">
|
||||
/// If no registered
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> can wrap
|
||||
/// the supplied <paramref name="advice"/>.
|
||||
/// </exception>
|
||||
public virtual IAdvisor Wrap(object advice)
|
||||
{
|
||||
if (advice is IAdvisor)
|
||||
{
|
||||
return (IAdvisor) advice;
|
||||
}
|
||||
if (!(advice is IAdvice))
|
||||
{
|
||||
throw new UnknownAdviceTypeException(advice);
|
||||
}
|
||||
IAdvice adviceObject = (IAdvice) advice;
|
||||
if (adviceObject is IInterceptor)
|
||||
{
|
||||
// so well-known it doesn't even need an adapter...
|
||||
return new DefaultPointcutAdvisor(adviceObject);
|
||||
}
|
||||
foreach (IAdvisorAdapter adapter in this.adapters)
|
||||
{
|
||||
// check that it is supported...
|
||||
if (adapter.SupportsAdvice(adviceObject))
|
||||
{
|
||||
return new DefaultPointcutAdvisor(adviceObject);
|
||||
}
|
||||
}
|
||||
throw new UnknownAdviceTypeException(advice);
|
||||
}
|
||||
if (!(advice is IAdvice))
|
||||
{
|
||||
throw new UnknownAdviceTypeException(advice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="AopAlliance.Intercept.IInterceptor"/> to
|
||||
/// allow the use of the supplied <paramref name="advisor"/> in an
|
||||
/// interception-based framework.
|
||||
/// </summary>
|
||||
/// <param name="advisor">The advisor to find an interceptor for.</param>
|
||||
/// <returns>
|
||||
/// An interceptor to expose this advisor's behaviour.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownAdviceTypeException">
|
||||
/// If the advisor type is not understood by any registered
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>.
|
||||
/// </exception>
|
||||
public virtual IInterceptor GetInterceptor(IAdvisor advisor)
|
||||
{
|
||||
IAdvice advice = advisor.Advice;
|
||||
if (advice is IInterceptor)
|
||||
{
|
||||
return (IInterceptor) advice;
|
||||
}
|
||||
foreach (IAdvisorAdapter adapter in this.adapters)
|
||||
{
|
||||
if (adapter.SupportsAdvice(advice))
|
||||
{
|
||||
return adapter.GetInterceptor(advisor);
|
||||
}
|
||||
}
|
||||
throw new UnknownAdviceTypeException(advice);
|
||||
}
|
||||
IAdvice adviceObject = (IAdvice) advice;
|
||||
if (adviceObject is IInterceptor)
|
||||
{
|
||||
// so well-known it doesn't even need an adapter...
|
||||
return new DefaultPointcutAdvisor(adviceObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the given <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>.
|
||||
/// </summary>
|
||||
/// <param name="adapter">
|
||||
/// An <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> that
|
||||
/// understands the particular advisor and advice types.
|
||||
/// </param>
|
||||
public virtual void RegisterAdvisorAdapter(IAdvisorAdapter adapter)
|
||||
{
|
||||
this.adapters.Add(adapter);
|
||||
}
|
||||
}
|
||||
foreach (IAdvisorAdapter adapter in this.adapters)
|
||||
{
|
||||
// check that it is supported...
|
||||
if (adapter.SupportsAdvice(adviceObject))
|
||||
{
|
||||
return new DefaultPointcutAdvisor(adviceObject);
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnknownAdviceTypeException(advice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="AopAlliance.Intercept.IInterceptor"/> to
|
||||
/// allow the use of the supplied <paramref name="advisor"/> in an
|
||||
/// interception-based framework.
|
||||
/// </summary>
|
||||
/// <param name="advisor">The advisor to find an interceptor for.</param>
|
||||
/// <returns>
|
||||
/// An interceptor to expose this advisor's behaviour.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownAdviceTypeException">
|
||||
/// If the advisor type is not understood by any registered
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>.
|
||||
/// </exception>
|
||||
public virtual IInterceptor GetInterceptor(IAdvisor advisor)
|
||||
{
|
||||
IAdvice advice = advisor.Advice;
|
||||
if (advice is IInterceptor)
|
||||
{
|
||||
return (IInterceptor) advice;
|
||||
}
|
||||
|
||||
foreach (IAdvisorAdapter adapter in this.adapters)
|
||||
{
|
||||
if (adapter.SupportsAdvice(advice))
|
||||
{
|
||||
return adapter.GetInterceptor(advisor);
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnknownAdviceTypeException(advice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the given <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>.
|
||||
/// </summary>
|
||||
/// <param name="adapter">
|
||||
/// An <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> that
|
||||
/// understands the particular advisor and advice types.
|
||||
/// </param>
|
||||
public virtual void RegisterAdvisorAdapter(IAdvisorAdapter adapter)
|
||||
{
|
||||
this.adapters.Add(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,48 +18,47 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// Provides Singleton-style access to the default
|
||||
/// <see cref="IAdvisorAdapterRegistry"/> instance.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public sealed class GlobalAdvisorAdapterRegistry : DefaultAdvisorAdapterRegistry
|
||||
{
|
||||
private static readonly GlobalAdvisorAdapterRegistry instance
|
||||
= new GlobalAdvisorAdapterRegistry();
|
||||
|
||||
/// <summary>
|
||||
/// Provides Singleton-style access to the default
|
||||
/// <see cref="IAdvisorAdapterRegistry"/> instance.
|
||||
/// The default <see cref="IAdvisorAdapterRegistry"/> instance.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public sealed class GlobalAdvisorAdapterRegistry : DefaultAdvisorAdapterRegistry
|
||||
public static GlobalAdvisorAdapterRegistry Instance
|
||||
{
|
||||
private static readonly GlobalAdvisorAdapterRegistry instance
|
||||
= new GlobalAdvisorAdapterRegistry();
|
||||
|
||||
/// <summary>
|
||||
/// The default <see cref="IAdvisorAdapterRegistry"/> instance.
|
||||
/// </summary>
|
||||
public static GlobalAdvisorAdapterRegistry Instance
|
||||
{
|
||||
get { return instance; }
|
||||
}
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
// CLOVER:OFF
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.GlobalAdvisorAdapterRegistry"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This contructor is marked as <see langword="private"/> to enforce the
|
||||
/// Singleton pattern
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private GlobalAdvisorAdapterRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
// CLOVER:ON
|
||||
|
||||
#endregion
|
||||
get { return instance; }
|
||||
}
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
// CLOVER:OFF
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.GlobalAdvisorAdapterRegistry"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This contructor is marked as <see langword="private"/> to enforce the
|
||||
/// Singleton pattern
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private GlobalAdvisorAdapterRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
// CLOVER:ON
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -25,74 +25,73 @@ using AopAlliance.Intercept;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
{
|
||||
/// <summary>
|
||||
/// Permits the handling of new advisors and advice types as extensions to
|
||||
/// the Spring AOP framework.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Implementors can create AOP Alliance
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/>s from custom advice
|
||||
/// types, enabling these advice types to be used in the Spring.NET AOP
|
||||
/// framework, which uses interception under the covers.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// There is no need for most Spring.NET users to implement this interface;
|
||||
/// do so only if you need to introduce more
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> or <see cref="AopAlliance.Aop.IAdvice"/>
|
||||
/// types to Spring.NET.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisorAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// Does this adapter understand the supplied <paramref name="advice"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Is it valid to invoke the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapterRegistry.Wrap"/>
|
||||
/// method with the given advice as an argument?
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advice">
|
||||
/// <see cref="AopAlliance.Aop.IAdvice"/> such as
|
||||
/// <see cref="Spring.Aop.IBeforeAdvice"/>.
|
||||
/// </param>
|
||||
/// <returns><see langword="true"/> if this adapter understands the
|
||||
/// supplied <paramref name="advice"/>.
|
||||
/// </returns>
|
||||
bool SupportsAdvice(IAdvice advice);
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// Return an AOP Alliance
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> exposing the
|
||||
/// behaviour of the given advice to an interception-based AOP
|
||||
/// framework.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Don't worry about any <see cref="Spring.Aop.IPointcut"/>
|
||||
/// contained in the supplied <see cref="Spring.Aop.IAdvisor"/>;
|
||||
/// the AOP framework will take care of checking the pointcut.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">
|
||||
/// The advice. The
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter.SupportsAdvice"/>
|
||||
/// method must have previously returned <see langword="true"/> on the
|
||||
/// supplied <paramref name="advisor"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An AOP Alliance
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> exposing the
|
||||
/// behaviour of the given advice to an interception-based AOP
|
||||
/// framework.
|
||||
/// </returns>
|
||||
IInterceptor GetInterceptor(IAdvisor advisor);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Permits the handling of new advisors and advice types as extensions to
|
||||
/// the Spring AOP framework.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Implementors can create AOP Alliance
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/>s from custom advice
|
||||
/// types, enabling these advice types to be used in the Spring.NET AOP
|
||||
/// framework, which uses interception under the covers.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// There is no need for most Spring.NET users to implement this interface;
|
||||
/// do so only if you need to introduce more
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> or <see cref="AopAlliance.Aop.IAdvice"/>
|
||||
/// types to Spring.NET.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisorAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// Does this adapter understand the supplied <paramref name="advice"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Is it valid to invoke the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapterRegistry.Wrap"/>
|
||||
/// method with the given advice as an argument?
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advice">
|
||||
/// <see cref="AopAlliance.Aop.IAdvice"/> such as
|
||||
/// <see cref="Spring.Aop.IBeforeAdvice"/>.
|
||||
/// </param>
|
||||
/// <returns><see langword="true"/> if this adapter understands the
|
||||
/// supplied <paramref name="advice"/>.
|
||||
/// </returns>
|
||||
bool SupportsAdvice(IAdvice advice);
|
||||
|
||||
/// <summary>
|
||||
/// Return an AOP Alliance
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> exposing the
|
||||
/// behaviour of the given advice to an interception-based AOP
|
||||
/// framework.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Don't worry about any <see cref="Spring.Aop.IPointcut"/>
|
||||
/// contained in the supplied <see cref="Spring.Aop.IAdvisor"/>;
|
||||
/// the AOP framework will take care of checking the pointcut.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">
|
||||
/// The advice. The
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter.SupportsAdvice"/>
|
||||
/// method must have previously returned <see langword="true"/> on the
|
||||
/// supplied <paramref name="advisor"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An AOP Alliance
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> exposing the
|
||||
/// behaviour of the given advice to an interception-based AOP
|
||||
/// framework.
|
||||
/// </returns>
|
||||
IInterceptor GetInterceptor(IAdvisor advisor);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -24,89 +24,88 @@ using AopAlliance.Intercept;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// A registry of
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> instances.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Implementations <b>must</b> also automatically register adapters for
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> types.
|
||||
/// </p>
|
||||
/// <note>
|
||||
/// This is an SPI interface, that should not need to be implemented by any
|
||||
/// Spring.NET user.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisorAdapterRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// A registry of
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> instances.
|
||||
/// Returns an <see cref="Spring.Aop.IAdvisor"/> wrapping the supplied
|
||||
/// <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The object that should be an advice, such as
|
||||
/// <see cref="Spring.Aop.IBeforeAdvice"/> or
|
||||
/// <see cref="Spring.Aop.IThrowsAdvice"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An <see cref="Spring.Aop.IAdvisor"/> wrapping the supplied
|
||||
/// <paramref name="advice"/>. Never returns <cref lang="null"/>. If
|
||||
/// the <paramref name="advice"/> parameter is an
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>, it will simply be returned.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownAdviceTypeException">
|
||||
/// If no registered
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> can wrap
|
||||
/// the supplied <paramref name="advice"/>.
|
||||
/// </exception>
|
||||
IAdvisor Wrap(object advice);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="AopAlliance.Intercept.IInterceptor"/> to
|
||||
/// allow the use of the supplied <paramref name="advisor"/> in an
|
||||
/// interception-based framework.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Implementations <b>must</b> also automatically register adapters for
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> types.
|
||||
/// Don't worry about the pointcut associated with the
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>; if it's an
|
||||
/// <see cref="Spring.Aop.IPointcutAdvisor"/>, just return an
|
||||
/// interceptor.
|
||||
/// </p>
|
||||
/// <note>
|
||||
/// This is an SPI interface, that should not need to be implemented by any
|
||||
/// Spring.NET user.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisorAdapterRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns an <see cref="Spring.Aop.IAdvisor"/> wrapping the supplied
|
||||
/// <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The object that should be an advice, such as
|
||||
/// <see cref="Spring.Aop.IBeforeAdvice"/> or
|
||||
/// <see cref="Spring.Aop.IThrowsAdvice"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An <see cref="Spring.Aop.IAdvisor"/> wrapping the supplied
|
||||
/// <paramref name="advice"/>. Never returns <cref lang="null"/>. If
|
||||
/// the <paramref name="advice"/> parameter is an
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>, it will simply be returned.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownAdviceTypeException">
|
||||
/// If no registered
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> can wrap
|
||||
/// the supplied <paramref name="advice"/>.
|
||||
/// </exception>
|
||||
IAdvisor Wrap(object advice);
|
||||
/// <param name="advisor">
|
||||
/// The advisor to find an interceptor for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An interceptor to expose this advisor's behaviour.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownAdviceTypeException">
|
||||
/// If the advisor type is not understood by any registered
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>.
|
||||
/// </exception>
|
||||
IInterceptor GetInterceptor(IAdvisor advisor);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="AopAlliance.Intercept.IInterceptor"/> to
|
||||
/// allow the use of the supplied <paramref name="advisor"/> in an
|
||||
/// interception-based framework.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Don't worry about the pointcut associated with the
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>; if it's an
|
||||
/// <see cref="Spring.Aop.IPointcutAdvisor"/>, just return an
|
||||
/// interceptor.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">
|
||||
/// The advisor to find an interceptor for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An interceptor to expose this advisor's behaviour.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownAdviceTypeException">
|
||||
/// If the advisor type is not understood by any registered
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>.
|
||||
/// </exception>
|
||||
IInterceptor GetInterceptor(IAdvisor advisor);
|
||||
|
||||
/// <summary>
|
||||
/// Register the given <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Note that it is not necessary to register adapters for
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> instances: these
|
||||
/// must be automatically recognized by an
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapterRegistry"/>
|
||||
/// implementation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="adapter">
|
||||
/// An <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> that
|
||||
/// understands the particular advisor and advice types.
|
||||
/// </param>
|
||||
void RegisterAdvisorAdapter(IAdvisorAdapter adapter);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Register the given <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Note that it is not necessary to register adapters for
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> instances: these
|
||||
/// must be automatically recognized by an
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapterRegistry"/>
|
||||
/// implementation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="adapter">
|
||||
/// An <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> that
|
||||
/// understands the particular advisor and advice types.
|
||||
/// </param>
|
||||
void RegisterAdvisorAdapter(IAdvisorAdapter adapter);
|
||||
}
|
||||
|
||||
@@ -25,67 +25,66 @@ using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> implementation that
|
||||
/// wraps <see cref="Spring.Aop.IMethodBeforeAdvice"/> instances.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// In the future Spring.NET may also offer a more efficient alternative
|
||||
/// solution in cases where there is no interception advice and therefore
|
||||
/// no need to create an <see cref="AopAlliance.Intercept.IMethodInvocation"/>
|
||||
/// object.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Used internally by the Spring.NET AOP framework: application developers
|
||||
/// should not need to use this class directly.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
internal sealed class MethodBeforeAdviceInterceptor : IMethodInterceptor
|
||||
{
|
||||
private IMethodBeforeAdvice advice;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/> implementation that
|
||||
/// wraps <see cref="Spring.Aop.IMethodBeforeAdvice"/> instances.
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.MethodBeforeAdviceInterceptor"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// In the future Spring.NET may also offer a more efficient alternative
|
||||
/// solution in cases where there is no interception advice and therefore
|
||||
/// no need to create an <see cref="AopAlliance.Intercept.IMethodInvocation"/>
|
||||
/// object.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Used internally by the Spring.NET AOP framework: application developers
|
||||
/// should not need to use this class directly.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
internal sealed class MethodBeforeAdviceInterceptor : IMethodInterceptor
|
||||
/// <param name="advice">
|
||||
/// The <see cref="Spring.Aop.IMethodBeforeAdvice"/> that is to be wrapped.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="advice"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public MethodBeforeAdviceInterceptor(IMethodBeforeAdvice advice)
|
||||
{
|
||||
private IMethodBeforeAdvice advice;
|
||||
AssertUtils.ArgumentNotNull(advice, "advice");
|
||||
this.advice = advice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.MethodBeforeAdviceInterceptor"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="Spring.Aop.IMethodBeforeAdvice"/> that is to be wrapped.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="advice"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public MethodBeforeAdviceInterceptor(IMethodBeforeAdvice advice)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(advice, "advice");
|
||||
this.advice = advice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes interceptor before the target method successfully returns.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The method invocation that is being intercepted.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The result of the call to the
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/> method of
|
||||
/// the supplied <paramref name="invocation"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If any of the interceptors in the chain or the target object itself
|
||||
/// throws an exception.
|
||||
/// </exception>
|
||||
public object Invoke(IMethodInvocation invocation)
|
||||
{
|
||||
advice.Before(invocation.Method, invocation.Arguments, invocation.This);
|
||||
return invocation.Proceed();
|
||||
}
|
||||
/// <summary>
|
||||
/// Executes interceptor before the target method successfully returns.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The method invocation that is being intercepted.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The result of the call to the
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/> method of
|
||||
/// the supplied <paramref name="invocation"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If any of the interceptors in the chain or the target object itself
|
||||
/// throws an exception.
|
||||
/// </exception>
|
||||
public object Invoke(IMethodInvocation invocation)
|
||||
{
|
||||
advice.Before(invocation.Method, invocation.Arguments, invocation.This);
|
||||
return invocation.Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,54 +25,53 @@ using AopAlliance.Intercept;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> implementation
|
||||
/// to enable <see cref="Spring.Aop.IThrowsAdvice"/> to be used in the
|
||||
/// Spring.NET AOP framework.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
internal class ThrowsAdviceAdapter : IAdvisorAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.IAdvisorAdapter"/> implementation
|
||||
/// to enable <see cref="Spring.Aop.IThrowsAdvice"/> to be used in the
|
||||
/// Spring.NET AOP framework.
|
||||
/// Returns <see langword="true"/> if the supplied
|
||||
/// <paramref name="advice"/> is an instance of the
|
||||
/// <see cref="Spring.Aop.IThrowsAdvice"/> interface.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
internal class ThrowsAdviceAdapter : IAdvisorAdapter
|
||||
/// <param name="advice">The advice to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="advice"/> is
|
||||
/// an instance of the <see cref="Spring.Aop.IThrowsAdvice"/> interface;
|
||||
/// <see langword="false"/> if not or if the supplied
|
||||
/// <paramref name="advice"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
public virtual bool SupportsAdvice(IAdvice advice)
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the supplied
|
||||
/// <paramref name="advice"/> is an instance of the
|
||||
/// <see cref="Spring.Aop.IThrowsAdvice"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="advice">The advice to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="advice"/> is
|
||||
/// an instance of the <see cref="Spring.Aop.IThrowsAdvice"/> interface;
|
||||
/// <see langword="false"/> if not or if the supplied
|
||||
/// <paramref name="advice"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
public virtual bool SupportsAdvice(IAdvice advice)
|
||||
{
|
||||
return advice is IThrowsAdvice;
|
||||
}
|
||||
return advice is IThrowsAdvice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="advisor">
|
||||
/// The advisor exposing the <see cref="AopAlliance.Aop.IAdvice"/> that
|
||||
/// is to be wrapped.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> wrapped within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </returns>
|
||||
public virtual IInterceptor GetInterceptor(IAdvisor advisor)
|
||||
{
|
||||
return new ThrowsAdviceInterceptor(advisor.Advice);
|
||||
}
|
||||
/// <summary>
|
||||
/// Wraps the supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="advisor">
|
||||
/// The advisor exposing the <see cref="AopAlliance.Aop.IAdvice"/> that
|
||||
/// is to be wrapped.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The supplied <paramref name="advisor"/>'s
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/> wrapped within a
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor"/>
|
||||
/// instance.
|
||||
/// </returns>
|
||||
public virtual IInterceptor GetInterceptor(IAdvisor advisor)
|
||||
{
|
||||
return new ThrowsAdviceInterceptor(advisor.Advice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,290 +28,292 @@ using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>Interceptor to wrap an after throwing advice.</summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Implementations of the <see cref="Spring.Aop.IThrowsAdvice"/> interface
|
||||
/// <b>must</b> define methods of the form...
|
||||
/// <code lang="C#">
|
||||
/// AfterThrowing([MethodInfo method, Object[] args, Object target], Exception subclass);
|
||||
/// </code>
|
||||
/// The method name is fixed (i.e. your methods <b>must</b> be named
|
||||
/// <c>AfterThrowing</c>. The first three arguments (<i>as a whole</i>) are
|
||||
/// optional, and only useful if futher information about the joinpoint is
|
||||
/// required. The return type <i>can</i> be anything, but is almost always
|
||||
/// <see langword="void"/> by convention.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Please note that the object encapsulating the throws advice does not
|
||||
/// need to implement the <see cref="Spring.Aop.IThrowsAdvice"/> interface.
|
||||
/// Throws advice methods are discovered via reflection... the
|
||||
/// <see cref="Spring.Aop.IThrowsAdvice"/> interface serves merely to
|
||||
/// <i>discover</i> objects that are to be considered as throws advice.
|
||||
/// Other mechanisms for discovering throws advice such as attributes are
|
||||
/// also equally valid... all that this class cares about is that a throws
|
||||
/// advice object implement one or more methods with a valid throws advice
|
||||
/// signature (see above, and the examples below).
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This is a framework class that should not normally need to be used
|
||||
/// directly by Spring.NET users.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <p>
|
||||
/// Find below some examples of valid <see cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// method signatures...
|
||||
/// </p>
|
||||
/// <code language="C#">
|
||||
/// public class GlobalExceptionHandlingAdvice : IThrowsAdvice
|
||||
/// {
|
||||
/// public void AfterThrowing(Exception ex) {
|
||||
/// // handles absolutely any and every Exception...
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// <code language="C#">
|
||||
/// public class RemotingExceptionHandlingAdvice : IThrowsAdvice
|
||||
/// {
|
||||
/// public void AfterThrowing(RemotingException ex) {
|
||||
/// // handles any and every RemotingException (and subclasses of RemotingException)...
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// <code language="C#">
|
||||
/// using System.Data;
|
||||
///
|
||||
/// public class DataExceptionHandlingAdvice
|
||||
/// {
|
||||
/// public void AfterThrowing(ConstraintException ex) {
|
||||
/// // specialised handling of ConstraintExceptions
|
||||
/// }
|
||||
///
|
||||
/// public void AfterThrowing(NoNullAllowedException ex) {
|
||||
/// // specialised handling of NoNullAllowedExceptions
|
||||
/// }
|
||||
///
|
||||
/// public void AfterThrowing(DataException ex) {
|
||||
/// // handles all other DataExceptions...
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
[Serializable]
|
||||
public sealed class ThrowsAdviceInterceptor : IMethodInterceptor
|
||||
{
|
||||
/// <summary>Interceptor to wrap an after throwing advice.</summary>
|
||||
private static readonly ILogger<ThrowsAdviceInterceptor> log = LogManager.GetLogger<ThrowsAdviceInterceptor>();
|
||||
|
||||
private const string SpecialThrowingMethodName = "AfterThrowing";
|
||||
|
||||
private readonly object throwsAdvice;
|
||||
|
||||
/// <summary>
|
||||
/// The mapping of exception Types to MethodInfo handlers.
|
||||
/// </summary>
|
||||
private readonly IDictionary exceptionHandlers;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Implementations of the <see cref="Spring.Aop.IThrowsAdvice"/> interface
|
||||
/// <b>must</b> define methods of the form...
|
||||
/// <code lang="C#">
|
||||
/// AfterThrowing([MethodInfo method, Object[] args, Object target], Exception subclass);
|
||||
/// </code>
|
||||
/// The method name is fixed (i.e. your methods <b>must</b> be named
|
||||
/// <c>AfterThrowing</c>. The first three arguments (<i>as a whole</i>) are
|
||||
/// optional, and only useful if futher information about the joinpoint is
|
||||
/// required. The return type <i>can</i> be anything, but is almost always
|
||||
/// <see langword="void"/> by convention.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Please note that the object encapsulating the throws advice does not
|
||||
/// need to implement the <see cref="Spring.Aop.IThrowsAdvice"/> interface.
|
||||
/// Throws advice methods are discovered via reflection... the
|
||||
/// <see cref="Spring.Aop.IThrowsAdvice"/> interface serves merely to
|
||||
/// <i>discover</i> objects that are to be considered as throws advice.
|
||||
/// Other mechanisms for discovering throws advice such as attributes are
|
||||
/// also equally valid... all that this class cares about is that a throws
|
||||
/// advice object implement one or more methods with a valid throws advice
|
||||
/// signature (see above, and the examples below).
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This is a framework class that should not normally need to be used
|
||||
/// directly by Spring.NET users.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <p>
|
||||
/// Find below some examples of valid <see cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// method signatures...
|
||||
/// </p>
|
||||
/// <code language="C#">
|
||||
/// public class GlobalExceptionHandlingAdvice : IThrowsAdvice
|
||||
/// {
|
||||
/// public void AfterThrowing(Exception ex) {
|
||||
/// // handles absolutely any and every Exception...
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// <code language="C#">
|
||||
/// public class RemotingExceptionHandlingAdvice : IThrowsAdvice
|
||||
/// {
|
||||
/// public void AfterThrowing(RemotingException ex) {
|
||||
/// // handles any and every RemotingException (and subclasses of RemotingException)...
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// <code language="C#">
|
||||
/// using System.Data;
|
||||
///
|
||||
/// public class DataExceptionHandlingAdvice
|
||||
/// {
|
||||
/// public void AfterThrowing(ConstraintException ex) {
|
||||
/// // specialised handling of ConstraintExceptions
|
||||
/// }
|
||||
///
|
||||
/// public void AfterThrowing(NoNullAllowedException ex) {
|
||||
/// // specialised handling of NoNullAllowedExceptions
|
||||
/// }
|
||||
///
|
||||
/// public void AfterThrowing(DataException ex) {
|
||||
/// // handles all other DataExceptions...
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
[Serializable]
|
||||
public sealed class ThrowsAdviceInterceptor : IMethodInterceptor
|
||||
/// <param name="advice">
|
||||
/// The throws advice to check for exception handler methods.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="advice"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If no (0) handler methods were discovered on the supplied <paramref name="advice"/>;
|
||||
/// or if more than one handler method suitable for a particular
|
||||
/// <see cref="System.Exception"/> type was discovered on the supplied
|
||||
/// <paramref name="advice"/>.
|
||||
/// </exception>
|
||||
public ThrowsAdviceInterceptor(object advice)
|
||||
{
|
||||
private static readonly ILogger<ThrowsAdviceInterceptor> log = LogManager.GetLogger<ThrowsAdviceInterceptor>();
|
||||
|
||||
private const string SpecialThrowingMethodName = "AfterThrowing";
|
||||
|
||||
private readonly object throwsAdvice;
|
||||
|
||||
/// <summary>
|
||||
/// The mapping of exception Types to MethodInfo handlers.
|
||||
/// </summary>
|
||||
private readonly IDictionary exceptionHandlers;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
/// <param name="advice">
|
||||
/// The throws advice to check for exception handler methods.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="advice"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If no (0) handler methods were discovered on the supplied <paramref name="advice"/>;
|
||||
/// or if more than one handler method suitable for a particular
|
||||
/// <see cref="System.Exception"/> type was discovered on the supplied
|
||||
/// <paramref name="advice"/>.
|
||||
/// </exception>
|
||||
public ThrowsAdviceInterceptor(object advice)
|
||||
AssertUtils.ArgumentNotNull(advice, "advice");
|
||||
this.exceptionHandlers = new Hashtable();
|
||||
this.throwsAdvice = advice;
|
||||
MapAllExceptionHandlingMethods(advice);
|
||||
if (exceptionHandlers.Count == 0)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(advice, "advice");
|
||||
this.exceptionHandlers = new Hashtable();
|
||||
this.throwsAdvice = advice;
|
||||
MapAllExceptionHandlingMethods(advice);
|
||||
if (exceptionHandlers.Count == 0)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"At least one handler method must be found in class ["
|
||||
+ advice.GetType().FullName + "].");
|
||||
}
|
||||
throw new ArgumentException(
|
||||
"At least one handler method must be found in class ["
|
||||
+ advice.GetType().FullName + "].");
|
||||
}
|
||||
}
|
||||
|
||||
private void MapAllExceptionHandlingMethods(object advice)
|
||||
private void MapAllExceptionHandlingMethods(object advice)
|
||||
{
|
||||
MethodInfo[] methods = advice.GetType().GetMethods();
|
||||
foreach (MethodInfo method in methods)
|
||||
{
|
||||
MethodInfo[] methods = advice.GetType().GetMethods();
|
||||
foreach (MethodInfo method in methods)
|
||||
int numParams = method.GetParameters().Length;
|
||||
if (method.Name.Equals(SpecialThrowingMethodName)
|
||||
&& (numParams == 1 || numParams == 4))
|
||||
{
|
||||
int numParams = method.GetParameters().Length;
|
||||
if (method.Name.Equals(SpecialThrowingMethodName)
|
||||
&& (numParams == 1 || numParams == 4))
|
||||
Type lastParametersType = method.GetParameters()[numParams - 1].ParameterType;
|
||||
if (typeof(Exception).IsAssignableFrom(lastParametersType))
|
||||
{
|
||||
Type lastParametersType = method.GetParameters()[numParams - 1].ParameterType;
|
||||
if (typeof (Exception).IsAssignableFrom(lastParametersType))
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if(log.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
log.LogDebug("Found exception handler method: " + method);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
if(this.exceptionHandlers.Contains(lastParametersType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Throws advice handler method for the [" +
|
||||
lastParametersType + "] type already exists; don't define " +
|
||||
"both single and multiple argument methods for the same " +
|
||||
"Exception type in the same class.");
|
||||
}
|
||||
this.exceptionHandlers[lastParametersType] = method;
|
||||
log.LogDebug("Found exception handler method: " + method);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
if (this.exceptionHandlers.Contains(lastParametersType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Throws advice handler method for the [" +
|
||||
lastParametersType + "] type already exists; don't define " +
|
||||
"both single and multiple argument methods for the same " +
|
||||
"Exception type in the same class.");
|
||||
}
|
||||
|
||||
this.exceptionHandlers[lastParametersType] = method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience property that returns the number of exception handler
|
||||
/// methods managed by this interceptor.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The number of exception handler methods managed by this interceptor.
|
||||
/// </value>
|
||||
public int HandlerMethodCount
|
||||
/// <summary>
|
||||
/// Convenience property that returns the number of exception handler
|
||||
/// methods managed by this interceptor.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The number of exception handler methods managed by this interceptor.
|
||||
/// </value>
|
||||
public int HandlerMethodCount
|
||||
{
|
||||
get { return exceptionHandlers.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes interceptor if (and only if) the supplied
|
||||
/// <paramref name="invocation"/> throws an exception that is mapped to
|
||||
/// an appropriate exception handler.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The method invocation that is being intercepted.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The result of the call to the
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/> method of
|
||||
/// the supplied <paramref name="invocation"/> (this assumes no
|
||||
/// exception was thrown by the call to the supplied <paramref name="invocation"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If any of the interceptors in the chain or the target object itself
|
||||
/// throws an exception.
|
||||
/// </exception>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor.Invoke"/>
|
||||
public object Invoke(IMethodInvocation invocation)
|
||||
{
|
||||
try
|
||||
{
|
||||
get { return exceptionHandlers.Count; }
|
||||
return invocation.Proceed();
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
// bah, this is a tad gross...
|
||||
Exception realException = ex.InnerException;
|
||||
LookupAndInvokeAnyHandler(realException, invocation);
|
||||
throw realException;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LookupAndInvokeAnyHandler(ex, invocation);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void LookupAndInvokeAnyHandler(Exception ex, IMethodInvocation invocation)
|
||||
{
|
||||
MethodInfo handlerMethod = GetExceptionHandler(ex);
|
||||
if (handlerMethod != null)
|
||||
{
|
||||
InvokeHandlerMethod(invocation, ex, handlerMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the exception handler (if any) that has been mapped to the
|
||||
/// supplied <paramref name="exception"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Will return <cref lang="null"/> if not found.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The exception handler for the <see cref="System.Type"/> of the
|
||||
/// supplied <paramref name="exception"/> given exception.
|
||||
/// </returns>
|
||||
/// <param name="exception">exception that was thrown</param>
|
||||
private MethodInfo GetExceptionHandler(Exception exception)
|
||||
{
|
||||
Type exceptionClass = exception.GetType();
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (log.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
log.LogDebug("Trying to find handler for exception of type [" + exception.GetType().Name + "].");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes interceptor if (and only if) the supplied
|
||||
/// <paramref name="invocation"/> throws an exception that is mapped to
|
||||
/// an appropriate exception handler.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The method invocation that is being intercepted.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The result of the call to the
|
||||
/// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/> method of
|
||||
/// the supplied <paramref name="invocation"/> (this assumes no
|
||||
/// exception was thrown by the call to the supplied <paramref name="invocation"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If any of the interceptors in the chain or the target object itself
|
||||
/// throws an exception.
|
||||
/// </exception>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor.Invoke"/>
|
||||
public object Invoke(IMethodInvocation invocation)
|
||||
#endregion
|
||||
|
||||
MethodInfo handler = (MethodInfo) this.exceptionHandlers[exceptionClass];
|
||||
while (handler == null && !exceptionClass.Equals(typeof(Exception)))
|
||||
{
|
||||
try
|
||||
{
|
||||
return invocation.Proceed();
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
// bah, this is a tad gross...
|
||||
Exception realException = ex.InnerException;
|
||||
LookupAndInvokeAnyHandler(realException, invocation);
|
||||
throw realException;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LookupAndInvokeAnyHandler(ex, invocation);
|
||||
throw;
|
||||
}
|
||||
exceptionClass = exceptionClass.BaseType;
|
||||
handler = (MethodInfo) this.exceptionHandlers[exceptionClass];
|
||||
}
|
||||
|
||||
private void LookupAndInvokeAnyHandler(Exception ex, IMethodInvocation invocation)
|
||||
return handler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes handler method with appropriate number of parameters
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The original method invocation that was intercepted.
|
||||
/// </param>
|
||||
/// <param name="triggeringException">
|
||||
/// The exception that triggered this interceptor.
|
||||
/// </param>
|
||||
/// <param name="handlerMethod">
|
||||
/// The exception handler method to invoke.
|
||||
/// </param>
|
||||
private void InvokeHandlerMethod(
|
||||
IMethodInvocation invocation, Exception triggeringException, MethodInfo handlerMethod)
|
||||
{
|
||||
object[] handlerArgs;
|
||||
if (handlerMethod.GetParameters().Length == 1)
|
||||
{
|
||||
MethodInfo handlerMethod = GetExceptionHandler(ex);
|
||||
if (handlerMethod != null)
|
||||
{
|
||||
InvokeHandlerMethod(invocation, ex, handlerMethod);
|
||||
}
|
||||
handlerArgs = new object[] { triggeringException };
|
||||
}
|
||||
else
|
||||
{
|
||||
handlerArgs = new object[] { invocation.Method, invocation.Arguments, invocation.This, triggeringException };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the exception handler (if any) that has been mapped to the
|
||||
/// supplied <paramref name="exception"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Will return <cref lang="null"/> if not found.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The exception handler for the <see cref="System.Type"/> of the
|
||||
/// supplied <paramref name="exception"/> given exception.
|
||||
/// </returns>
|
||||
/// <param name="exception">exception that was thrown</param>
|
||||
private MethodInfo GetExceptionHandler(Exception exception)
|
||||
try
|
||||
{
|
||||
Type exceptionClass = exception.GetType();
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if(log.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
log.LogDebug("Trying to find handler for exception of type [" + exception.GetType().Name + "].");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
MethodInfo handler = (MethodInfo) this.exceptionHandlers[exceptionClass];
|
||||
while (handler == null && !exceptionClass.Equals(typeof(Exception)))
|
||||
{
|
||||
exceptionClass = exceptionClass.BaseType;
|
||||
handler = (MethodInfo) this.exceptionHandlers[exceptionClass];
|
||||
}
|
||||
return handler;
|
||||
handlerMethod.Invoke(this.throwsAdvice, handlerArgs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes handler method with appropriate number of parameters
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The original method invocation that was intercepted.
|
||||
/// </param>
|
||||
/// <param name="triggeringException">
|
||||
/// The exception that triggered this interceptor.
|
||||
/// </param>
|
||||
/// <param name="handlerMethod">
|
||||
/// The exception handler method to invoke.
|
||||
/// </param>
|
||||
private void InvokeHandlerMethod(
|
||||
IMethodInvocation invocation, Exception triggeringException, MethodInfo handlerMethod)
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
object[] handlerArgs;
|
||||
if (handlerMethod.GetParameters().Length == 1)
|
||||
{
|
||||
handlerArgs = new object[] {triggeringException};
|
||||
}
|
||||
else
|
||||
{
|
||||
handlerArgs = new object[] {invocation.Method, invocation.Arguments, invocation.This, triggeringException};
|
||||
}
|
||||
try
|
||||
{
|
||||
handlerMethod.Invoke(this.throwsAdvice, handlerArgs);
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
throw ReflectionUtils.UnwrapTargetInvocationException(ex);
|
||||
}
|
||||
throw ReflectionUtils.UnwrapTargetInvocationException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,69 +24,68 @@ using System.Runtime.Serialization;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.Adapter
|
||||
namespace Spring.Aop.Framework.Adapter;
|
||||
|
||||
/// <summary>
|
||||
/// Exception thrown when an attempt is made to use an unsupported
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> or <see cref="AopAlliance.Aop.IAdvice"/>
|
||||
/// type.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class UnknownAdviceTypeException : ArgumentException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception thrown when an attempt is made to use an unsupported
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> or <see cref="AopAlliance.Aop.IAdvice"/>
|
||||
/// type.
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.UnknownAdviceTypeException"/> class.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class UnknownAdviceTypeException : ArgumentException
|
||||
public UnknownAdviceTypeException()
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.UnknownAdviceTypeException"/> class.
|
||||
/// </summary>
|
||||
public UnknownAdviceTypeException()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.UnknownAdviceTypeException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advice">The advice that caused the exception.</param>
|
||||
public UnknownAdviceTypeException(object advice)
|
||||
: base("No adapter for IAdvice of type ["
|
||||
+ (advice != null ? advice.GetType().FullName : "null") + "].")
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.UnknownAdviceTypeException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advice">The advice that caused the exception.</param>
|
||||
public UnknownAdviceTypeException(object advice)
|
||||
: base("No adapter for IAdvice of type ["
|
||||
+ (advice != null ? advice.GetType().FullName : "null") + "].")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.UnknownAdviceTypeException"/> class with
|
||||
/// the specified message.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// A message about the exception.
|
||||
/// </param>
|
||||
public UnknownAdviceTypeException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.UnknownAdviceTypeException"/> class with
|
||||
/// the specified message.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// A message about the exception.
|
||||
/// </param>
|
||||
public UnknownAdviceTypeException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.UnknownAdviceTypeException"/> class with
|
||||
/// the specified message and root cause.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// A message about the exception.
|
||||
/// </param>
|
||||
/// <param name="rootCause">
|
||||
/// The root exception that is being wrapped.
|
||||
/// </param>
|
||||
public UnknownAdviceTypeException(string message, Exception rootCause)
|
||||
: base(message, rootCause)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.UnknownAdviceTypeException"/> class with
|
||||
/// the specified message and root cause.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// A message about the exception.
|
||||
/// </param>
|
||||
/// <param name="rootCause">
|
||||
/// The root exception that is being wrapped.
|
||||
/// </param>
|
||||
public UnknownAdviceTypeException(string message, Exception rootCause)
|
||||
: base(message, rootCause)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected UnknownAdviceTypeException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected UnknownAdviceTypeException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,101 +21,99 @@
|
||||
#region Imports
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
using AopAlliance.Intercept;
|
||||
|
||||
using Spring.Aop.Framework.Adapter;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Utility methods for use by
|
||||
/// <see cref="Spring.Aop.Framework.IAdvisorChainFactory"/> implementations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Not intended to be used directly by applications.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public sealed class AdvisorChainFactoryUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility methods for use by
|
||||
/// <see cref="Spring.Aop.Framework.IAdvisorChainFactory"/> implementations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Not intended to be used directly by applications.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public sealed class AdvisorChainFactoryUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the list of
|
||||
/// <see langword="static"/> interceptors and dynamic interception
|
||||
/// advice that may apply to the supplied <paramref name="method"/>
|
||||
/// invocation.
|
||||
/// </summary>
|
||||
/// <param name="config">The proxy configuration.</param>
|
||||
/// <param name="proxy">The object proxy.</param>
|
||||
/// <param name="method">
|
||||
/// The method to evaluate interceptors for.
|
||||
/// </param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="System.Collections.IList"/> of
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInterceptor"/> (if there's
|
||||
/// a dynamic method matcher that needs evaluation at runtime).
|
||||
/// </returns>
|
||||
public static IList<object> CalculateInterceptors(
|
||||
IAdvised config, object proxy, MethodInfo method, Type targetType)
|
||||
{
|
||||
IList<object> interceptors = new List<object>(config.Advisors.Count);
|
||||
foreach (IAdvisor advisor in config.Advisors)
|
||||
{
|
||||
if (advisor is IPointcutAdvisor)
|
||||
{
|
||||
IPointcutAdvisor pointcutAdvisor = (IPointcutAdvisor) advisor;
|
||||
if (pointcutAdvisor.Pointcut.TypeFilter.Matches(targetType))
|
||||
{
|
||||
IMethodInterceptor interceptor =
|
||||
(IMethodInterceptor) GlobalAdvisorAdapterRegistry.Instance.GetInterceptor(advisor);
|
||||
IMethodMatcher mm = pointcutAdvisor.Pointcut.MethodMatcher;
|
||||
if (mm.Matches(method, targetType))
|
||||
{
|
||||
if (mm.IsRuntime)
|
||||
{
|
||||
// Creating a new object instance in the GetInterceptor() method
|
||||
// isn't a problem as we normally cache created chains...
|
||||
interceptors.Add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
|
||||
}
|
||||
else
|
||||
{
|
||||
interceptors.Add(interceptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return interceptors;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the list of
|
||||
/// <see langword="static"/> interceptors and dynamic interception
|
||||
/// advice that may apply to the supplied <paramref name="method"/>
|
||||
/// invocation.
|
||||
/// </summary>
|
||||
/// <param name="config">The proxy configuration.</param>
|
||||
/// <param name="proxy">The object proxy.</param>
|
||||
/// <param name="method">
|
||||
/// The method to evaluate interceptors for.
|
||||
/// </param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="System.Collections.IList"/> of
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInterceptor"/> (if there's
|
||||
/// a dynamic method matcher that needs evaluation at runtime).
|
||||
/// </returns>
|
||||
public static IList<object> CalculateInterceptors(
|
||||
IAdvised config, object proxy, MethodInfo method, Type targetType)
|
||||
{
|
||||
IList<object> interceptors = new List<object>(config.Advisors.Count);
|
||||
foreach (IAdvisor advisor in config.Advisors)
|
||||
{
|
||||
if (advisor is IPointcutAdvisor)
|
||||
{
|
||||
IPointcutAdvisor pointcutAdvisor = (IPointcutAdvisor) advisor;
|
||||
if (pointcutAdvisor.Pointcut.TypeFilter.Matches(targetType))
|
||||
{
|
||||
IMethodInterceptor interceptor =
|
||||
(IMethodInterceptor) GlobalAdvisorAdapterRegistry.Instance.GetInterceptor(advisor);
|
||||
IMethodMatcher mm = pointcutAdvisor.Pointcut.MethodMatcher;
|
||||
if (mm.Matches(method, targetType))
|
||||
{
|
||||
if (mm.IsRuntime)
|
||||
{
|
||||
// Creating a new object instance in the GetInterceptor() method
|
||||
// isn't a problem as we normally cache created chains...
|
||||
interceptors.Add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
|
||||
}
|
||||
else
|
||||
{
|
||||
interceptors.Add(interceptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
return interceptors;
|
||||
}
|
||||
|
||||
// CLOVER:OFF
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AdvisorChainFactoryUtils"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a utility class, and as such has no publicly visible
|
||||
/// constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private AdvisorChainFactoryUtils()
|
||||
{
|
||||
}
|
||||
// CLOVER:OFF
|
||||
|
||||
// CLOVER:ON
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AdvisorChainFactoryUtils"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a utility class, and as such has no publicly visible
|
||||
/// constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private AdvisorChainFactoryUtils()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
// CLOVER:ON
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -24,57 +24,56 @@ using System.Runtime.Serialization;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Thrown in response to the misconfiguration of an AOP proxy.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class AopConfigException : ApplicationException
|
||||
{
|
||||
/// <summary>
|
||||
/// Thrown in response to the misconfiguration of an AOP proxy.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class AopConfigException : ApplicationException
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AopConfigException"/> class.
|
||||
/// </summary>
|
||||
public AopConfigException ()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AopConfigException"/> class.
|
||||
/// </summary>
|
||||
public AopConfigException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AopConfigException"/> class with
|
||||
/// the specified message.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// A message about the exception.
|
||||
/// </param>
|
||||
public AopConfigException (string message) : base(message)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AopConfigException"/> class with
|
||||
/// the specified message.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// A message about the exception.
|
||||
/// </param>
|
||||
public AopConfigException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AopConfigException"/> class with
|
||||
/// the specified message and root cause.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// A message about the exception.
|
||||
/// </param>
|
||||
/// <param name="rootCause">
|
||||
/// The root exception that is being wrapped.
|
||||
/// </param>
|
||||
public AopConfigException (string message, Exception rootCause)
|
||||
: base(message, rootCause)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AopConfigException"/> class with
|
||||
/// the specified message and root cause.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// A message about the exception.
|
||||
/// </param>
|
||||
/// <param name="rootCause">
|
||||
/// The root exception that is being wrapped.
|
||||
/// </param>
|
||||
public AopConfigException(string message, Exception rootCause)
|
||||
: base(message, rootCause)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected AopConfigException (
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base (info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected AopConfigException(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,165 +24,166 @@ using System.Collections;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// This class contains various <see langword="static"/> methods used to
|
||||
/// obtain information about the current AOP invocation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The <see langword="static"/>
|
||||
/// <see cref="Spring.Aop.Framework.AopContext.CurrentProxy"/> property is
|
||||
/// usable if the AOP framework is configured to expose the current proxy
|
||||
/// (not the default)... it returns the AOP proxy in use. Target objects or
|
||||
/// advice can use this to make advised calls. They can also use it to find
|
||||
/// advice configuration.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// To expose the current proxy, set the <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/>
|
||||
/// property on the controlling proxy to <see langword="true"/>.
|
||||
/// The default value for the <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/> property
|
||||
/// is <see langword="false"/>, for performance reasons.
|
||||
/// </p>
|
||||
/// <note>
|
||||
/// The AOP framework does not expose proxies by default, as there is a
|
||||
/// performance cost in doing so.
|
||||
/// </note>
|
||||
/// <p>
|
||||
/// The functionality in this class might be used by a target object that
|
||||
/// needed access to resources on the invocation. However, this approach
|
||||
/// should not be used when there is a reasonable alternative, as it makes
|
||||
/// application code dependent on usage under AOP and the Spring.NET AOP
|
||||
/// framework.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public sealed class AopContext
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains various <see langword="static"/> methods used to
|
||||
/// obtain information about the current AOP invocation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The <see langword="static"/>
|
||||
/// <see cref="Spring.Aop.Framework.AopContext.CurrentProxy"/> property is
|
||||
/// usable if the AOP framework is configured to expose the current proxy
|
||||
/// (not the default)... it returns the AOP proxy in use. Target objects or
|
||||
/// advice can use this to make advised calls. They can also use it to find
|
||||
/// advice configuration.
|
||||
/// </p>
|
||||
[ThreadStatic] private static Stack tls_ProxyStack;
|
||||
|
||||
/// <summary>
|
||||
/// The AOP proxy stack associated with this thread.
|
||||
/// </summary>
|
||||
private static Stack ProxyStack
|
||||
{
|
||||
get
|
||||
{
|
||||
if (tls_ProxyStack == null)
|
||||
{
|
||||
tls_ProxyStack = new Stack();
|
||||
}
|
||||
|
||||
return tls_ProxyStack;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the current call is executed under control of an AOP proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// To expose the current proxy, set the <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/>
|
||||
/// property on the controlling proxy to <see langword="true"/>.
|
||||
/// The default value for the <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/> property
|
||||
/// Will be <cref lang="null"/> unless the
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/> property
|
||||
/// on the controlling proxy has been set to <see langword="true"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// The default value for the
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/> property
|
||||
/// is <see langword="false"/>, for performance reasons.
|
||||
/// </p>
|
||||
/// <note>
|
||||
/// The AOP framework does not expose proxies by default, as there is a
|
||||
/// performance cost in doing so.
|
||||
/// </note>
|
||||
/// <p>
|
||||
/// The functionality in this class might be used by a target object that
|
||||
/// needed access to resources on the invocation. However, this approach
|
||||
/// should not be used when there is a reasonable alternative, as it makes
|
||||
/// application code dependent on usage under AOP and the Spring.NET AOP
|
||||
/// framework.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public sealed class AopContext
|
||||
{
|
||||
[ThreadStatic]
|
||||
private static Stack tls_ProxyStack;
|
||||
|
||||
/// <summary>
|
||||
/// The AOP proxy stack associated with this thread.
|
||||
/// </summary>
|
||||
private static Stack ProxyStack
|
||||
/// </remarks>
|
||||
public static bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
return (tls_ProxyStack != null && tls_ProxyStack.Count > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current AOP proxy.
|
||||
/// </summary>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the proxy stack is empty.
|
||||
/// </exception>
|
||||
public static object CurrentProxy
|
||||
{
|
||||
get
|
||||
{
|
||||
Stack proxyStack = ProxyStack;
|
||||
if (proxyStack.Count == 0)
|
||||
{
|
||||
if (tls_ProxyStack == null)
|
||||
{
|
||||
tls_ProxyStack = new Stack();
|
||||
}
|
||||
return tls_ProxyStack;
|
||||
throw new AopConfigException(
|
||||
"Cannot find proxy: Set the 'ExposeProxy' property " +
|
||||
"to 'true' on IAdvised to make it available.");
|
||||
}
|
||||
|
||||
return proxyStack.Peek();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current proxy by pushing it to the proxy stack.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method is for internal use only, and should never be called by
|
||||
/// client code.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="proxy">
|
||||
/// The proxy to put on top of the proxy stack.
|
||||
/// </param>
|
||||
public static void PushProxy(object proxy)
|
||||
{
|
||||
ProxyStack.Push(proxy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the current proxy from the proxy stack, making the previous
|
||||
/// proxy (if any) the current proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method is for internal use only, and should never be called by
|
||||
/// client code.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the proxy stack is empty.
|
||||
/// </exception>
|
||||
public static void PopProxy()
|
||||
{
|
||||
Stack proxyStack = ProxyStack;
|
||||
if (proxyStack.Count == 0)
|
||||
{
|
||||
throw new AopConfigException(
|
||||
"Proxy stack empty. Always call 'PushProxy' before 'PopProxy'.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the current call is executed under control of an AOP proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Will be <cref lang="null"/> unless the
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/> property
|
||||
/// on the controlling proxy has been set to <see langword="true"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// The default value for the
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/> property
|
||||
/// is <see langword="false"/>, for performance reasons.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public static bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return (tls_ProxyStack != null && tls_ProxyStack.Count > 0);
|
||||
}
|
||||
}
|
||||
proxyStack.Pop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current AOP proxy.
|
||||
/// </summary>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the proxy stack is empty.
|
||||
/// </exception>
|
||||
public static object CurrentProxy
|
||||
{
|
||||
get
|
||||
{
|
||||
Stack proxyStack = ProxyStack;
|
||||
if (proxyStack.Count == 0)
|
||||
{
|
||||
throw new AopConfigException(
|
||||
"Cannot find proxy: Set the 'ExposeProxy' property " +
|
||||
"to 'true' on IAdvised to make it available.");
|
||||
}
|
||||
return proxyStack.Peek();
|
||||
}
|
||||
}
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current proxy by pushing it to the proxy stack.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method is for internal use only, and should never be called by
|
||||
/// client code.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="proxy">
|
||||
/// The proxy to put on top of the proxy stack.
|
||||
/// </param>
|
||||
public static void PushProxy(object proxy)
|
||||
{
|
||||
ProxyStack.Push(proxy);
|
||||
}
|
||||
// CLOVER:OFF
|
||||
|
||||
/// <summary>
|
||||
/// Removes the current proxy from the proxy stack, making the previous
|
||||
/// proxy (if any) the current proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method is for internal use only, and should never be called by
|
||||
/// client code.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the proxy stack is empty.
|
||||
/// </exception>
|
||||
public static void PopProxy()
|
||||
{
|
||||
Stack proxyStack = ProxyStack;
|
||||
if (proxyStack.Count == 0)
|
||||
{
|
||||
throw new AopConfigException(
|
||||
"Proxy stack empty. Always call 'PushProxy' before 'PopProxy'.");
|
||||
}
|
||||
proxyStack.Pop();
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AopContext"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a utility class, and as such exposes no public constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private AopContext()
|
||||
{
|
||||
}
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
// CLOVER:ON
|
||||
|
||||
// CLOVER:OFF
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.AopContext"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a utility class, and as such exposes no public constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private AopContext()
|
||||
{
|
||||
}
|
||||
|
||||
// CLOVER:ON
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -21,389 +21,395 @@
|
||||
#region Imports
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
using Spring.Collections;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Utility methods used by the AOP framework.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Not intended to be used directly by applications.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public sealed class AopUtils
|
||||
{
|
||||
// This is a leaky abstraction as we have hardcoded known IAopProxyFactory implementations.
|
||||
private const string COMPOSITION_PROXY_TYPE_NAME = "CompositionAopProxy";
|
||||
|
||||
private const string DECORATOR_PROXY_TYPE_NAME = "DecoratorAopProxy";
|
||||
|
||||
private const string INHERITANCE_PROXY_TYPE_NAME = "InheritanceAopProxy";
|
||||
|
||||
/// <summary>
|
||||
/// Utility methods used by the AOP framework.
|
||||
/// Is the supplied <paramref name="objectType"/> an AOP proxy?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return whether the given type is either a composition-based or a decorator-based proxy type.
|
||||
/// </remarks>
|
||||
/// <param name="objectType">The type to be checked.</param>
|
||||
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is an AOP proxy type.</returns>
|
||||
public static bool IsAopProxyType(Type objectType)
|
||||
{
|
||||
return IsCompositionAopProxyType(objectType) || IsDecoratorAopProxyType(objectType) || IsInheritanceAopProxyType(objectType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="instance"/> an AOP proxy?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return whether the given object is either
|
||||
/// a composition-based proxy or a decorator-based proxy.
|
||||
/// </remarks>
|
||||
/// <param name="instance">The instance to be checked.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
|
||||
/// an AOP proxy.
|
||||
/// </returns>
|
||||
public static bool IsAopProxy(object instance)
|
||||
{
|
||||
return IsCompositionAopProxy(instance) || IsDecoratorAopProxy(instance) || IsInheritanceAopProxy(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="instance"/> a composition-based AOP proxy?
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to be checked.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
|
||||
/// an composition-based AOP proxy.
|
||||
/// </returns>
|
||||
public static bool IsCompositionAopProxy(Object instance)
|
||||
{
|
||||
return ((instance != null) && IsCompositionAopProxyType(instance.GetType()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="objectType"/> a composition based AOP proxy type?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return whether the given type is a composition-based proxy type.
|
||||
/// </remarks>
|
||||
/// <param name="objectType">The type to be checked.</param>
|
||||
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is a composition based AOP proxy type.</returns>
|
||||
public static bool IsCompositionAopProxyType(Type objectType)
|
||||
{
|
||||
return ((objectType != null) && objectType.FullName.StartsWith(COMPOSITION_PROXY_TYPE_NAME));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="instance"/> a decorator-based AOP proxy?
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to be checked.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
|
||||
/// an decorator-based AOP proxy.
|
||||
/// </returns>
|
||||
public static bool IsDecoratorAopProxy(Object instance)
|
||||
{
|
||||
return ((instance != null) && IsDecoratorAopProxyType(instance.GetType()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="objectType"/> a composition based AOP proxy type?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return whether the given type is a composition-based proxy type.
|
||||
/// </remarks>
|
||||
/// <param name="objectType">The type to be checked.</param>
|
||||
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is a composition based AOP proxy type.</returns>
|
||||
public static bool IsDecoratorAopProxyType(Type objectType)
|
||||
{
|
||||
return ((objectType != null) && objectType.FullName.StartsWith(DECORATOR_PROXY_TYPE_NAME));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="instance"/> an inheritance based AOP proxy?
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to be checked.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
|
||||
/// an inheritacne based AOP proxy.
|
||||
/// </returns>
|
||||
public static bool IsInheritanceAopProxy(Object instance)
|
||||
{
|
||||
return instance != null && IsInheritanceAopProxyType(instance.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="objectType"/> an inheritance based AOP proxy type?
|
||||
/// </summary>
|
||||
/// <param name="objectType">The type to be checked.</param>
|
||||
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is an inheritance based AOP proxy type.</returns>
|
||||
public static bool IsInheritanceAopProxyType(Type objectType)
|
||||
{
|
||||
return ((objectType != null) && objectType.FullName.StartsWith(INHERITANCE_PROXY_TYPE_NAME));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the interfaces that the <see cref="System.Type"/> of the
|
||||
/// supplied <paramref name="instance"/> implements.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Not intended to be used directly by applications.
|
||||
/// This includes interfaces implemented by any superclasses.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public sealed class AopUtils
|
||||
/// <param name="instance">
|
||||
/// The object to analyse for interfaces.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// All of the interfaces that the <see cref="System.Type"/> of the
|
||||
/// supplied <paramref name="instance"/> implements; or an empty
|
||||
/// array if the supplied <paramref name="instance"/> is
|
||||
/// <see langword="null"/>.
|
||||
/// </returns>
|
||||
public static Type[] GetAllInterfaces(object instance)
|
||||
{
|
||||
// This is a leaky abstraction as we have hardcoded known IAopProxyFactory implementations.
|
||||
private const string COMPOSITION_PROXY_TYPE_NAME = "CompositionAopProxy";
|
||||
|
||||
private const string DECORATOR_PROXY_TYPE_NAME = "DecoratorAopProxy";
|
||||
|
||||
private const string INHERITANCE_PROXY_TYPE_NAME = "InheritanceAopProxy";
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="objectType"/> an AOP proxy?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return whether the given type is either a composition-based or a decorator-based proxy type.
|
||||
/// </remarks>
|
||||
/// <param name="objectType">The type to be checked.</param>
|
||||
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is an AOP proxy type.</returns>
|
||||
public static bool IsAopProxyType(Type objectType)
|
||||
if (instance != null)
|
||||
{
|
||||
return IsCompositionAopProxyType(objectType) || IsDecoratorAopProxyType(objectType) || IsInheritanceAopProxyType(objectType);
|
||||
Type type = instance.GetType();
|
||||
return GetAllInterfacesFromType(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="instance"/> an AOP proxy?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return whether the given object is either
|
||||
/// a composition-based proxy or a decorator-based proxy.
|
||||
/// </remarks>
|
||||
/// <param name="instance">The instance to be checked.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
|
||||
/// an AOP proxy.
|
||||
/// </returns>
|
||||
public static bool IsAopProxy(object instance)
|
||||
{
|
||||
return IsCompositionAopProxy(instance) || IsDecoratorAopProxy(instance) || IsInheritanceAopProxy(instance);
|
||||
}
|
||||
return Type.EmptyTypes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="instance"/> a composition-based AOP proxy?
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to be checked.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
|
||||
/// an composition-based AOP proxy.
|
||||
/// </returns>
|
||||
public static bool IsCompositionAopProxy(Object instance)
|
||||
/// <summary>
|
||||
/// Gets all of the interfaces that the
|
||||
/// supplied <see cref="System.Type"/> implements.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This includes interfaces implemented by any superclasses.
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The type to analyse for interfaces.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// All of the interfaces that the supplied <see cref="System.Type"/> implements.
|
||||
/// </returns>
|
||||
public static Type[] GetAllInterfacesFromType(Type type)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(type, "type");
|
||||
ISet interfaces = new HybridSet();
|
||||
do
|
||||
{
|
||||
return ((instance != null) && IsCompositionAopProxyType(instance.GetType()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="objectType"/> a composition based AOP proxy type?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return whether the given type is a composition-based proxy type.
|
||||
/// </remarks>
|
||||
/// <param name="objectType">The type to be checked.</param>
|
||||
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is a composition based AOP proxy type.</returns>
|
||||
public static bool IsCompositionAopProxyType(Type objectType)
|
||||
{
|
||||
return ((objectType != null) && objectType.FullName.StartsWith(COMPOSITION_PROXY_TYPE_NAME));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="instance"/> a decorator-based AOP proxy?
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to be checked.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
|
||||
/// an decorator-based AOP proxy.
|
||||
/// </returns>
|
||||
public static bool IsDecoratorAopProxy(Object instance)
|
||||
{
|
||||
return ((instance != null) && IsDecoratorAopProxyType(instance.GetType()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="objectType"/> a composition based AOP proxy type?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Return whether the given type is a composition-based proxy type.
|
||||
/// </remarks>
|
||||
/// <param name="objectType">The type to be checked.</param>
|
||||
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is a composition based AOP proxy type.</returns>
|
||||
public static bool IsDecoratorAopProxyType(Type objectType)
|
||||
{
|
||||
return ((objectType != null) && objectType.FullName.StartsWith(DECORATOR_PROXY_TYPE_NAME));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="instance"/> an inheritance based AOP proxy?
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to be checked.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
|
||||
/// an inheritacne based AOP proxy.
|
||||
/// </returns>
|
||||
public static bool IsInheritanceAopProxy(Object instance)
|
||||
{
|
||||
return instance != null && IsInheritanceAopProxyType(instance.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="objectType"/> an inheritance based AOP proxy type?
|
||||
/// </summary>
|
||||
/// <param name="objectType">The type to be checked.</param>
|
||||
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is an inheritance based AOP proxy type.</returns>
|
||||
public static bool IsInheritanceAopProxyType(Type objectType)
|
||||
{
|
||||
return ((objectType != null) && objectType.FullName.StartsWith(INHERITANCE_PROXY_TYPE_NAME));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the interfaces that the <see cref="System.Type"/> of the
|
||||
/// supplied <paramref name="instance"/> implements.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This includes interfaces implemented by any superclasses.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="instance">
|
||||
/// The object to analyse for interfaces.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// All of the interfaces that the <see cref="System.Type"/> of the
|
||||
/// supplied <paramref name="instance"/> implements; or an empty
|
||||
/// array if the supplied <paramref name="instance"/> is
|
||||
/// <see langword="null"/>.
|
||||
/// </returns>
|
||||
public static Type[] GetAllInterfaces(object instance)
|
||||
{
|
||||
if (instance != null)
|
||||
Type[] ifcs = type.GetInterfaces();
|
||||
foreach (Type ifc in ifcs)
|
||||
{
|
||||
Type type = instance.GetType();
|
||||
return GetAllInterfacesFromType(type);
|
||||
}
|
||||
return Type.EmptyTypes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the interfaces that the
|
||||
/// supplied <see cref="System.Type"/> implements.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This includes interfaces implemented by any superclasses.
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The type to analyse for interfaces.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// All of the interfaces that the supplied <see cref="System.Type"/> implements.
|
||||
/// </returns>
|
||||
public static Type[] GetAllInterfacesFromType(Type type)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(type, "type");
|
||||
ISet interfaces = new HybridSet();
|
||||
do
|
||||
{
|
||||
Type[] ifcs = type.GetInterfaces();
|
||||
foreach (Type ifc in ifcs)
|
||||
{
|
||||
interfaces.Add(ifc);
|
||||
}
|
||||
type = type.BaseType;
|
||||
} while (type != null);
|
||||
|
||||
if (interfaces.Count > 0)
|
||||
{
|
||||
Type[] types = new Type[interfaces.Count];
|
||||
interfaces.CopyTo(types, 0);
|
||||
return types;
|
||||
}
|
||||
return Type.EmptyTypes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="pointcut"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out a
|
||||
/// pointcut for a class.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Invoking this method with a <paramref name="targetType"/> that is
|
||||
/// an interface type will always yield a <see langword="false"/>
|
||||
/// return value.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="pointcut">The pointcut being tested.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the pointcut can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IPointcut pointcut, Type targetType, Type[] proxyInterfaces)
|
||||
{
|
||||
return CanApply(pointcut, targetType, proxyInterfaces, false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="pointcut"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out a
|
||||
/// pointcut for a class.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Invoking this method with a <paramref name="targetType"/> that is
|
||||
/// an interface type will always yield a <see langword="false"/>
|
||||
/// return value.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="pointcut">The pointcut being tested.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <param name="hasIntroductions">whether or not the advisor chain for the target object includes any introductions.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the pointcut can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IPointcut pointcut, Type targetType, Type[] proxyInterfaces, bool hasIntroductions)
|
||||
{
|
||||
if (!pointcut.TypeFilter.Matches(targetType))
|
||||
{
|
||||
return false;
|
||||
interfaces.Add(ifc);
|
||||
}
|
||||
|
||||
// It may apply to the class
|
||||
// Check whether it can apply on any method
|
||||
// Checks public methods, including inherited methods
|
||||
MethodInfo[] methods = targetType.GetMethods();
|
||||
for (int i = 0; i < methods.Length; ++i)
|
||||
{
|
||||
MethodInfo m = methods[i];
|
||||
// If we're looking only at interfaces and this method
|
||||
// isn't on any of them, skip it
|
||||
if (proxyInterfaces != null
|
||||
&& !ReflectionUtils.MethodIsOnOneOfTheseInterfaces(m, proxyInterfaces))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pointcut.MethodMatcher.Matches(m, targetType))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
type = type.BaseType;
|
||||
} while (type != null);
|
||||
|
||||
if (interfaces.Count > 0)
|
||||
{
|
||||
Type[] types = new Type[interfaces.Count];
|
||||
interfaces.CopyTo(types, 0);
|
||||
return types;
|
||||
}
|
||||
|
||||
return Type.EmptyTypes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="pointcut"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out a
|
||||
/// pointcut for a class.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Invoking this method with a <paramref name="targetType"/> that is
|
||||
/// an interface type will always yield a <see langword="false"/>
|
||||
/// return value.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="pointcut">The pointcut being tested.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the pointcut can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IPointcut pointcut, Type targetType, Type[] proxyInterfaces)
|
||||
{
|
||||
return CanApply(pointcut, targetType, proxyInterfaces, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="pointcut"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out a
|
||||
/// pointcut for a class.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Invoking this method with a <paramref name="targetType"/> that is
|
||||
/// an interface type will always yield a <see langword="false"/>
|
||||
/// return value.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="pointcut">The pointcut being tested.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <param name="hasIntroductions">whether or not the advisor chain for the target object includes any introductions.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the pointcut can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IPointcut pointcut, Type targetType, Type[] proxyInterfaces, bool hasIntroductions)
|
||||
{
|
||||
if (!pointcut.TypeFilter.Matches(targetType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="advisor"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out an
|
||||
/// advisor for a class.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">The advisor to check.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advisor can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IAdvisor advisor, Type targetType, Type[] proxyInterfaces)
|
||||
// It may apply to the class
|
||||
// Check whether it can apply on any method
|
||||
// Checks public methods, including inherited methods
|
||||
MethodInfo[] methods = targetType.GetMethods();
|
||||
for (int i = 0; i < methods.Length; ++i)
|
||||
{
|
||||
return CanApply(advisor, targetType, proxyInterfaces, false);
|
||||
MethodInfo m = methods[i];
|
||||
// If we're looking only at interfaces and this method
|
||||
// isn't on any of them, skip it
|
||||
if (proxyInterfaces != null
|
||||
&& !ReflectionUtils.MethodIsOnOneOfTheseInterfaces(m, proxyInterfaces))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pointcut.MethodMatcher.Matches(m, targetType))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="advisor"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out an
|
||||
/// advisor for a class.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">The advisor to check.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <param name="hasIntroductions">whether or not the advisor chain for the target object includes any introductions.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advisor can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IAdvisor advisor, Type targetType, Type[] proxyInterfaces, bool hasIntroductions)
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="advisor"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out an
|
||||
/// advisor for a class.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">The advisor to check.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advisor can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IAdvisor advisor, Type targetType, Type[] proxyInterfaces)
|
||||
{
|
||||
return CanApply(advisor, targetType, proxyInterfaces, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="advisor"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out an
|
||||
/// advisor for a class.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">The advisor to check.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <param name="hasIntroductions">whether or not the advisor chain for the target object includes any introductions.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advisor can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IAdvisor advisor, Type targetType, Type[] proxyInterfaces, bool hasIntroductions)
|
||||
{
|
||||
if (advisor is IIntroductionAdvisor)
|
||||
{
|
||||
if (advisor is IIntroductionAdvisor)
|
||||
{
|
||||
return ((IIntroductionAdvisor)advisor).TypeFilter.Matches(targetType);
|
||||
}
|
||||
else if (advisor is IPointcutAdvisor)
|
||||
{
|
||||
IPointcutAdvisor pca = (IPointcutAdvisor)advisor;
|
||||
return CanApply(pca.Pointcut, targetType, proxyInterfaces, hasIntroductions);
|
||||
}
|
||||
// no pointcut specified so assume it applies...
|
||||
return true;
|
||||
return ((IIntroductionAdvisor) advisor).TypeFilter.Matches(targetType);
|
||||
}
|
||||
else if (advisor is IPointcutAdvisor)
|
||||
{
|
||||
IPointcutAdvisor pca = (IPointcutAdvisor) advisor;
|
||||
return CanApply(pca.Pointcut, targetType, proxyInterfaces, hasIntroductions);
|
||||
}
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
// no pointcut specified so assume it applies...
|
||||
return true;
|
||||
}
|
||||
|
||||
// CLOVER:OFF
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AopUtils"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a utility class, and as such has no publicly
|
||||
/// visible constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private AopUtils()
|
||||
// CLOVER:OFF
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AopUtils"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a utility class, and as such has no publicly
|
||||
/// visible constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
private AopUtils()
|
||||
{
|
||||
}
|
||||
|
||||
// CLOVER:ON
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the target.
|
||||
/// </summary>
|
||||
/// <param name="candidate">The candidate.</param>
|
||||
/// <returns></returns>
|
||||
public static Type GetTargetType(object candidate)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(candidate, "candidate", "Candidate object must not be null");
|
||||
if (candidate is ITargetSource)
|
||||
{
|
||||
return ((ITargetSource) candidate).TargetType;
|
||||
}
|
||||
|
||||
// CLOVER:ON
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the target.
|
||||
/// </summary>
|
||||
/// <param name="candidate">The candidate.</param>
|
||||
/// <returns></returns>
|
||||
public static Type GetTargetType(object candidate)
|
||||
if (candidate is IAdvised)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(candidate, "candidate", "Candidate object must not be null");
|
||||
if (candidate is ITargetSource)
|
||||
{
|
||||
return ((ITargetSource)candidate).TargetType;
|
||||
}
|
||||
if (candidate is IAdvised)
|
||||
{
|
||||
return ((IAdvised)candidate).TargetSource.TargetType;
|
||||
}
|
||||
if (IsDecoratorAopProxy(candidate))
|
||||
{
|
||||
return candidate.GetType().BaseType;
|
||||
}
|
||||
return candidate.GetType();
|
||||
return ((IAdvised) candidate).TargetSource.TargetType;
|
||||
}
|
||||
|
||||
if (IsDecoratorAopProxy(candidate))
|
||||
{
|
||||
return candidate.GetType().BaseType;
|
||||
}
|
||||
|
||||
return candidate.GetType();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,242 +23,246 @@ using Spring.Core;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Config;
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract IObjectPostProcessor implementation that creates AOP proxies.
|
||||
/// This class is completely generic; it contains no special code to handle
|
||||
/// any particular aspects, such as pooling aspects.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>Subclasses must implement the abstract FindCandidateAdvisors() method
|
||||
/// to return a list of Advisors applying to any object. Subclasses can also
|
||||
/// override the inherited ShouldSkip() method to exclude certain objects
|
||||
/// from autoproxying, but they must be careful to invoke the ShouldSkip()
|
||||
/// method of this class, which tries to avoid circular reference problems
|
||||
/// and infinite loops.</p>
|
||||
/// <p>Advisors or advices requiring ordering should implement the Ordered interface.
|
||||
/// This class sorts advisors by Ordered order value. Advisors that don't implement
|
||||
/// the Ordered interface will be considered to be unordered, and will appear
|
||||
/// at the end of the advisor chain in undefined order.</p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.Framework.AutoProxy.AbstractAdvisorAutoProxyCreator.FindCandidateAdvisors"/>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public abstract class AbstractAdvisorAutoProxyCreator : AbstractAutoProxyCreator
|
||||
{
|
||||
private IAdvisorRetrievalHelper _advisorRetrievalHelper;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract IObjectPostProcessor implementation that creates AOP proxies.
|
||||
/// This class is completely generic; it contains no special code to handle
|
||||
/// any particular aspects, such as pooling aspects.
|
||||
/// We override this method to ensure that all candidate advisors are materialized
|
||||
/// under a stack trace including this object. Otherwise, the dependencies won't
|
||||
/// be apparent to the circular-reference prevention strategy in AbstractObjectFactory.
|
||||
/// </summary>
|
||||
public override IObjectFactory ObjectFactory
|
||||
{
|
||||
set
|
||||
{
|
||||
if (!(value is IConfigurableListableObjectFactory))
|
||||
{
|
||||
throw new InvalidOperationException("Can not use AdvisorAutoProxyCreator without a ConfigurableListableObjectFactory");
|
||||
}
|
||||
|
||||
base.ObjectFactory = value;
|
||||
InitObjectFactory((IConfigurableListableObjectFactory) value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An new <see cref="IConfigurableListableObjectFactory"/> was set. Initialize this creator instance
|
||||
/// according to the specified object factory.
|
||||
/// </summary>
|
||||
/// <param name="objectFactory"></param>
|
||||
protected virtual void InitObjectFactory(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
_advisorRetrievalHelper = CreateAdvisorRetrievalHelper(objectFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the <see cref="IAdvisorRetrievalHelper"/> for retrieving the list of
|
||||
/// applicable advisor objects. The default implementation calls back into
|
||||
/// <see cref="IsEligibleAdvisorObject"/> thus it usually is sufficient to just
|
||||
/// override <see cref="IsEligibleAdvisorObject"/>. Override <see cref="CreateAdvisorRetrievalHelper"/>
|
||||
/// only if you know what you are doing!
|
||||
/// </summary>
|
||||
/// <param name="objectFactory"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual IAdvisorRetrievalHelper CreateAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
return new ObjectFactoryAdvisorRetrievalHelperAdapter(this, objectFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return whether the given object is to be proxied, what additional
|
||||
/// advices (e.g. AOP Alliance interceptors) and advisors to apply.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>Subclasses must implement the abstract FindCandidateAdvisors() method
|
||||
/// to return a list of Advisors applying to any object. Subclasses can also
|
||||
/// override the inherited ShouldSkip() method to exclude certain objects
|
||||
/// from autoproxying, but they must be careful to invoke the ShouldSkip()
|
||||
/// method of this class, which tries to avoid circular reference problems
|
||||
/// and infinite loops.</p>
|
||||
/// <p>Advisors or advices requiring ordering should implement the Ordered interface.
|
||||
/// This class sorts advisors by Ordered order value. Advisors that don't implement
|
||||
/// the Ordered interface will be considered to be unordered, and will appear
|
||||
/// at the end of the advisor chain in undefined order.</p>
|
||||
/// <p>The previous targetName of this method was "GetInterceptorAndAdvisorForObject".
|
||||
/// It has been renamed in the course of general terminology clarification
|
||||
/// in Spring 1.1. An AOP Alliance Interceptor is just a special form of
|
||||
/// Advice, so the generic Advice term is preferred now.</p>
|
||||
/// <p>The third parameter, customTargetSource, is new in Spring 1.1;
|
||||
/// add it to existing implementations of this method.</p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.Framework.AutoProxy.AbstractAdvisorAutoProxyCreator.FindCandidateAdvisors"/>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public abstract class AbstractAdvisorAutoProxyCreator : AbstractAutoProxyCreator
|
||||
/// <param name="targetType">the type of the target object</param>
|
||||
/// <param name="targetName">the name of the target object</param>
|
||||
/// <param name="customTargetSource">targetSource returned by TargetSource property:
|
||||
/// may be ignored. Will be null unless a custom target source is in use.</param>
|
||||
/// <returns>
|
||||
/// an array of additional interceptors for the particular object;
|
||||
/// or an empty array if no additional interceptors but just the common ones;
|
||||
/// or null if no proxy at all, not even with the common interceptors.
|
||||
/// </returns>
|
||||
protected override IList<object> GetAdvicesAndAdvisorsForObject(Type targetType, string targetName, ITargetSource customTargetSource)
|
||||
{
|
||||
private IAdvisorRetrievalHelper _advisorRetrievalHelper;
|
||||
|
||||
/// <summary>
|
||||
/// We override this method to ensure that all candidate advisors are materialized
|
||||
/// under a stack trace including this object. Otherwise, the dependencies won't
|
||||
/// be apparent to the circular-reference prevention strategy in AbstractObjectFactory.
|
||||
/// </summary>
|
||||
public override IObjectFactory ObjectFactory
|
||||
IList<IAdvisor> advisors = FindEligibleAdvisors(targetType, targetName);
|
||||
if (advisors.Count == 0)
|
||||
{
|
||||
set
|
||||
return DO_NOT_PROXY;
|
||||
}
|
||||
|
||||
return advisors.Cast<object>().ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all eligible advices and for autoproxying this class.
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>
|
||||
/// the empty list, not null, if there are no pointcuts or interceptors.
|
||||
/// The by-order sorted list of advisors otherwise
|
||||
/// </returns>
|
||||
protected IList<IAdvisor> FindEligibleAdvisors(Type targetType, string targetName)
|
||||
{
|
||||
List<IAdvisor> candidateAdvisors = FindCandidateAdvisors(targetType, targetName);
|
||||
List<IAdvisor> eligibleAdvisors = FindAdvisorsThatCanApply(candidateAdvisors, targetType, targetName);
|
||||
|
||||
ExtendAdvisors(eligibleAdvisors, targetType, targetName);
|
||||
SortAdvisors(eligibleAdvisors);
|
||||
|
||||
return eligibleAdvisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all possible advisor candidates to use in auto-proxying
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>the list of candidate advisors</returns>
|
||||
protected virtual List<IAdvisor> FindCandidateAdvisors(Type targetType, string targetName)
|
||||
{
|
||||
return _advisorRetrievalHelper.FindAdvisorObjects(targetType, targetName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// From the given list of candidate advisors, select the ones that are applicable
|
||||
/// to the given target specified by targetType and name.
|
||||
/// </summary>
|
||||
/// <param name="candidateAdvisors">the list of candidate advisors to date</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
/// <returns>the list of applicable advisors</returns>
|
||||
protected virtual List<IAdvisor> FindAdvisorsThatCanApply(List<IAdvisor> candidateAdvisors, Type targetType, string targetName)
|
||||
{
|
||||
if (candidateAdvisors.Count == 0)
|
||||
{
|
||||
return candidateAdvisors;
|
||||
}
|
||||
|
||||
List<IAdvisor> eligibleAdvisors = new List<IAdvisor>();
|
||||
foreach (IAdvisor candidate in candidateAdvisors)
|
||||
{
|
||||
if (candidate is IIntroductionAdvisor && AopUtils.CanApply(candidate, targetType, null))
|
||||
{
|
||||
if (!(value is IConfigurableListableObjectFactory))
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
throw new InvalidOperationException("Can not use AdvisorAutoProxyCreator without a ConfigurableListableObjectFactory");
|
||||
logger.LogInformation($"Candidate advisor [{candidate}] accepted for targetType [{targetType}]");
|
||||
}
|
||||
base.ObjectFactory = value;
|
||||
InitObjectFactory((IConfigurableListableObjectFactory)value);
|
||||
|
||||
eligibleAdvisors.Add(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An new <see cref="IConfigurableListableObjectFactory"/> was set. Initialize this creator instance
|
||||
/// according to the specified object factory.
|
||||
/// </summary>
|
||||
/// <param name="objectFactory"></param>
|
||||
protected virtual void InitObjectFactory(IConfigurableListableObjectFactory objectFactory)
|
||||
bool hasIntroductions = eligibleAdvisors.Count > 0;
|
||||
foreach (IAdvisor candidate in candidateAdvisors)
|
||||
{
|
||||
_advisorRetrievalHelper = CreateAdvisorRetrievalHelper(objectFactory);
|
||||
}
|
||||
if (candidate is IIntroductionAdvisor) continue;
|
||||
|
||||
/// <summary>
|
||||
/// Create the <see cref="IAdvisorRetrievalHelper"/> for retrieving the list of
|
||||
/// applicable advisor objects. The default implementation calls back into
|
||||
/// <see cref="IsEligibleAdvisorObject"/> thus it usually is sufficient to just
|
||||
/// override <see cref="IsEligibleAdvisorObject"/>. Override <see cref="CreateAdvisorRetrievalHelper"/>
|
||||
/// only if you know what you are doing!
|
||||
/// </summary>
|
||||
/// <param name="objectFactory"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual IAdvisorRetrievalHelper CreateAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
return new ObjectFactoryAdvisorRetrievalHelperAdapter(this, objectFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return whether the given object is to be proxied, what additional
|
||||
/// advices (e.g. AOP Alliance interceptors) and advisors to apply.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>The previous targetName of this method was "GetInterceptorAndAdvisorForObject".
|
||||
/// It has been renamed in the course of general terminology clarification
|
||||
/// in Spring 1.1. An AOP Alliance Interceptor is just a special form of
|
||||
/// Advice, so the generic Advice term is preferred now.</p>
|
||||
/// <p>The third parameter, customTargetSource, is new in Spring 1.1;
|
||||
/// add it to existing implementations of this method.</p>
|
||||
/// </remarks>
|
||||
/// <param name="targetType">the type of the target object</param>
|
||||
/// <param name="targetName">the name of the target object</param>
|
||||
/// <param name="customTargetSource">targetSource returned by TargetSource property:
|
||||
/// may be ignored. Will be null unless a custom target source is in use.</param>
|
||||
/// <returns>
|
||||
/// an array of additional interceptors for the particular object;
|
||||
/// or an empty array if no additional interceptors but just the common ones;
|
||||
/// or null if no proxy at all, not even with the common interceptors.
|
||||
/// </returns>
|
||||
protected override IList<object> GetAdvicesAndAdvisorsForObject(Type targetType, string targetName, ITargetSource customTargetSource)
|
||||
{
|
||||
IList<IAdvisor> advisors = FindEligibleAdvisors(targetType, targetName);
|
||||
if (advisors.Count == 0)
|
||||
if (AopUtils.CanApply(candidate, targetType, null, hasIntroductions))
|
||||
{
|
||||
return DO_NOT_PROXY;
|
||||
}
|
||||
return advisors.Cast<object>().ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all eligible advices and for autoproxying this class.
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>
|
||||
/// the empty list, not null, if there are no pointcuts or interceptors.
|
||||
/// The by-order sorted list of advisors otherwise
|
||||
/// </returns>
|
||||
protected IList<IAdvisor> FindEligibleAdvisors(Type targetType, string targetName)
|
||||
{
|
||||
List<IAdvisor> candidateAdvisors = FindCandidateAdvisors(targetType, targetName);
|
||||
List<IAdvisor> eligibleAdvisors = FindAdvisorsThatCanApply(candidateAdvisors, targetType, targetName);
|
||||
|
||||
ExtendAdvisors(eligibleAdvisors, targetType, targetName);
|
||||
SortAdvisors(eligibleAdvisors);
|
||||
|
||||
return eligibleAdvisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all possible advisor candidates to use in auto-proxying
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>the list of candidate advisors</returns>
|
||||
protected virtual List<IAdvisor> FindCandidateAdvisors(Type targetType, string targetName)
|
||||
{
|
||||
return _advisorRetrievalHelper.FindAdvisorObjects(targetType, targetName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// From the given list of candidate advisors, select the ones that are applicable
|
||||
/// to the given target specified by targetType and name.
|
||||
/// </summary>
|
||||
/// <param name="candidateAdvisors">the list of candidate advisors to date</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
/// <returns>the list of applicable advisors</returns>
|
||||
protected virtual List<IAdvisor> FindAdvisorsThatCanApply(List<IAdvisor> candidateAdvisors, Type targetType, string targetName)
|
||||
{
|
||||
if (candidateAdvisors.Count==0)
|
||||
{
|
||||
return candidateAdvisors;
|
||||
}
|
||||
|
||||
List<IAdvisor> eligibleAdvisors = new List<IAdvisor>();
|
||||
foreach(IAdvisor candidate in candidateAdvisors)
|
||||
{
|
||||
if (candidate is IIntroductionAdvisor && AopUtils.CanApply(candidate, targetType, null))
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
logger.LogInformation($"Candidate advisor [{candidate}] accepted for targetType [{targetType}]");
|
||||
}
|
||||
eligibleAdvisors.Add(candidate);
|
||||
logger.LogInformation($"Candidate advisor [{candidate}] accepted for targetType [{targetType}]");
|
||||
}
|
||||
|
||||
eligibleAdvisors.Add(candidate);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
logger.LogInformation($"Candidate advisor [{candidate}] rejected for targetType [{targetType}]");
|
||||
}
|
||||
}
|
||||
|
||||
bool hasIntroductions = eligibleAdvisors.Count > 0;
|
||||
foreach(IAdvisor candidate in candidateAdvisors)
|
||||
{
|
||||
if (candidate is IIntroductionAdvisor) continue;
|
||||
|
||||
if (AopUtils.CanApply(candidate, targetType, null, hasIntroductions))
|
||||
{
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
logger.LogInformation($"Candidate advisor [{candidate}] accepted for targetType [{targetType}]");
|
||||
}
|
||||
eligibleAdvisors.Add(candidate);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
logger.LogInformation($"Candidate advisor [{candidate}] rejected for targetType [{targetType}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
return eligibleAdvisors;
|
||||
}
|
||||
|
||||
return eligibleAdvisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the advisors.
|
||||
/// </summary>
|
||||
/// <param name="advisors">The advisors.</param>
|
||||
/// <returns></returns>
|
||||
protected virtual void SortAdvisors(List<IAdvisor> advisors)
|
||||
/// <summary>
|
||||
/// Sorts the advisors.
|
||||
/// </summary>
|
||||
/// <param name="advisors">The advisors.</param>
|
||||
/// <returns></returns>
|
||||
protected virtual void SortAdvisors(List<IAdvisor> advisors)
|
||||
{
|
||||
advisors.Sort(OrderComparator<IAdvisor>.Instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension hook that subclasses can override to add additional advisors for the given object,
|
||||
/// given the sorted advisors obtained to date.<br/>
|
||||
/// The default implementation does nothing.<br/>
|
||||
/// Typically used to add advisors that expose contextual information required by some of the later advisors.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The advisor list passed into this method is already reduced to advisors applying to this particular object.
|
||||
/// If you want to register additional common advisor candidates, override <see cref="FindCandidateAdvisors"/>.
|
||||
/// </remarks>
|
||||
/// <param name="advisors">Advisors that have already been identified as applying to a given object</param>
|
||||
/// <param name="objectType">the type of the object to be advised</param>
|
||||
/// <param name="objectName">the name of the object to be advised</param>
|
||||
protected virtual void ExtendAdvisors(IList<IAdvisor> advisors, Type objectType, string objectName)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the given advisor is eligible for the specified target. The default implementation
|
||||
/// always returns true.
|
||||
/// </summary>
|
||||
/// <param name="advisorName">the advisor name</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
protected virtual bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private class ObjectFactoryAdvisorRetrievalHelperAdapter : ObjectFactoryAdvisorRetrievalHelper
|
||||
{
|
||||
private readonly AbstractAdvisorAutoProxyCreator _owner;
|
||||
|
||||
public ObjectFactoryAdvisorRetrievalHelperAdapter(AbstractAdvisorAutoProxyCreator owner, IConfigurableListableObjectFactory owningFactory) : base(owningFactory)
|
||||
{
|
||||
advisors.Sort(OrderComparator<IAdvisor>.Instance);
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension hook that subclasses can override to add additional advisors for the given object,
|
||||
/// given the sorted advisors obtained to date.<br/>
|
||||
/// The default implementation does nothing.<br/>
|
||||
/// Typically used to add advisors that expose contextual information required by some of the later advisors.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The advisor list passed into this method is already reduced to advisors applying to this particular object.
|
||||
/// If you want to register additional common advisor candidates, override <see cref="FindCandidateAdvisors"/>.
|
||||
/// </remarks>
|
||||
/// <param name="advisors">Advisors that have already been identified as applying to a given object</param>
|
||||
/// <param name="objectType">the type of the object to be advised</param>
|
||||
/// <param name="objectName">the name of the object to be advised</param>
|
||||
protected virtual void ExtendAdvisors(IList<IAdvisor> advisors, Type objectType, string objectName)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the given advisor is eligible for the specified target. The default implementation
|
||||
/// always returns true.
|
||||
/// </summary>
|
||||
/// <param name="advisorName">the advisor name</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
protected virtual bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
|
||||
protected override bool IsEligibleObject(string advisorName, Type objectType, string objectName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private class ObjectFactoryAdvisorRetrievalHelperAdapter : ObjectFactoryAdvisorRetrievalHelper
|
||||
{
|
||||
private readonly AbstractAdvisorAutoProxyCreator _owner;
|
||||
|
||||
public ObjectFactoryAdvisorRetrievalHelperAdapter(AbstractAdvisorAutoProxyCreator owner, IConfigurableListableObjectFactory owningFactory) : base(owningFactory)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
protected override bool IsEligibleObject(string advisorName, Type objectType, string objectName)
|
||||
{
|
||||
return base.IsEligibleObject(advisorName, objectType, objectName)
|
||||
&& _owner.IsEligibleAdvisorObject(advisorName, objectType, objectName);
|
||||
}
|
||||
return base.IsEligibleObject(advisorName, objectType, objectName)
|
||||
&& _owner.IsEligibleAdvisorObject(advisorName, objectType, objectName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,55 +22,54 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// The base class for AutoProxyCreator implementations that mark objects
|
||||
/// eligible for proxying based on arbitrary criteria.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public abstract class AbstractFilteringAutoProxyCreator : AbstractAutoProxyCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class for AutoProxyCreator implementations that mark objects
|
||||
/// eligible for proxying based on arbitrary criteria.
|
||||
///Overridden to call <see cref="IsEligibleForProxying"/>.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public abstract class AbstractFilteringAutoProxyCreator : AbstractAutoProxyCreator
|
||||
/// <param name="targetType">the type of the object</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <returns>if remarkable to skip</returns>
|
||||
protected override bool ShouldSkip(Type targetType, string targetName)
|
||||
{
|
||||
/// <summary>
|
||||
///Overridden to call <see cref="IsEligibleForProxying"/>.
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <returns>if remarkable to skip</returns>
|
||||
protected override bool ShouldSkip( Type targetType, string targetName )
|
||||
{
|
||||
bool shouldSkip = !IsEligibleForProxying( targetType, targetName );
|
||||
return shouldSkip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override to always return <see cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Whether an object shall be proxied or not is determined by the result of <see cref="IsEligibleForProxying"/>.
|
||||
/// </remarks>
|
||||
/// <param name="targetType">ingored</param>
|
||||
/// <param name="targetName">ignored</param>
|
||||
/// <param name="customTargetSource">ignored</param>
|
||||
/// <returns>
|
||||
/// Always <see cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/> to indicate, that the object shall be proxied.
|
||||
/// </returns>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/>
|
||||
protected override IList<object> GetAdvicesAndAdvisorsForObject(Type targetType, string targetName, ITargetSource customTargetSource)
|
||||
{
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decide, whether the given object is eligible for proxying.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Override this method to allow or reject proxying for the given object.
|
||||
/// </remarks>
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.ShouldSkip"/>
|
||||
/// <returns>whether the given object shall be proxied.</returns>
|
||||
protected abstract bool IsEligibleForProxying( Type targetType, string targetName );
|
||||
bool shouldSkip = !IsEligibleForProxying(targetType, targetName);
|
||||
return shouldSkip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override to always return <see cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Whether an object shall be proxied or not is determined by the result of <see cref="IsEligibleForProxying"/>.
|
||||
/// </remarks>
|
||||
/// <param name="targetType">ingored</param>
|
||||
/// <param name="targetName">ignored</param>
|
||||
/// <param name="customTargetSource">ignored</param>
|
||||
/// <returns>
|
||||
/// Always <see cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/> to indicate, that the object shall be proxied.
|
||||
/// </returns>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/>
|
||||
protected override IList<object> GetAdvicesAndAdvisorsForObject(Type targetType, string targetName, ITargetSource customTargetSource)
|
||||
{
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decide, whether the given object is eligible for proxying.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Override this method to allow or reject proxying for the given object.
|
||||
/// </remarks>
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.ShouldSkip"/>
|
||||
/// <returns>whether the given object shall be proxied.</returns>
|
||||
protected abstract bool IsEligibleForProxying(Type targetType, string targetName);
|
||||
}
|
||||
|
||||
@@ -24,89 +24,89 @@ using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// An AutoProxyCreator, that identifies objects to be proxied by checking <see cref="Attribute"/>s defined on their type.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class AttributeAutoProxyCreator : AbstractFilteringAutoProxyCreator
|
||||
{
|
||||
private bool _checkInherited = false;
|
||||
private Type[] _attributeTypes = null;
|
||||
|
||||
/// <summary>
|
||||
/// An AutoProxyCreator, that identifies objects to be proxied by checking <see cref="Attribute"/>s defined on their type.
|
||||
/// Indicates, whether to consider base types for filtering when checking declared attributes. Defaults to <c>false</c>.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class AttributeAutoProxyCreator : AbstractFilteringAutoProxyCreator
|
||||
public bool CheckInherited
|
||||
{
|
||||
private bool _checkInherited = false;
|
||||
private Type[] _attributeTypes = null;
|
||||
get { return _checkInherited; }
|
||||
set { _checkInherited = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates, whether to consider base types for filtering when checking declared attributes. Defaults to <c>false</c>.
|
||||
/// </summary>
|
||||
public bool CheckInherited
|
||||
/// <summary>
|
||||
/// The list of attribute types marking object types as eligible for auto-proxying by this AutoProxyCreator. Must not be <c>null</c>.
|
||||
/// </summary>
|
||||
public Type[] AttributeTypes
|
||||
{
|
||||
get { return _attributeTypes; }
|
||||
set
|
||||
{
|
||||
get { return _checkInherited; }
|
||||
set { _checkInherited = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The list of attribute types marking object types as eligible for auto-proxying by this AutoProxyCreator. Must not be <c>null</c>.
|
||||
/// </summary>
|
||||
public Type[] AttributeTypes
|
||||
{
|
||||
get { return _attributeTypes; }
|
||||
set
|
||||
{
|
||||
AssertUtils.ArgumentNotNull( value, "AttributeTypes" );
|
||||
_attributeTypes = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines, whether the given object shall be proxied by matching <paramref name="targetType"/> against <see cref="AttributeTypes"/>.
|
||||
/// </summary>
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
protected override bool IsEligibleForProxying( Type targetType, string targetName )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(this.AttributeTypes, "AttributeTypes");
|
||||
|
||||
bool shallProxy = IsAnnotatedWithAnyOfAttribute( targetType, this.AttributeTypes, this.CheckInherited );
|
||||
return shallProxy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if <paramref name="objectType"/> is annotated with any of the attributes within the given list of <paramref name="attributeTypes"/>.
|
||||
/// </summary>
|
||||
/// <param name="objectType">the object's type</param>
|
||||
/// <param name="attributeTypes">the list of <see cref="Attribute"/> types to match agains.</param>
|
||||
/// <param name="checkInherited">whether to check base classes and intefaces for any of the given attributes.</param>
|
||||
/// <returns><see langword="true"/> if any of the attributes is found</returns>
|
||||
protected virtual bool IsAnnotatedWithAnyOfAttribute( Type objectType, Type[] attributeTypes, bool checkInherited )
|
||||
{
|
||||
foreach(Type attributeType in attributeTypes)
|
||||
{
|
||||
if (IsAnnotatedWithAttribute(objectType, attributeType, checkInherited))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if <paramref name="objectType"/> is annotated with the specified <paramref name="attributeType"/>.
|
||||
/// </summary>
|
||||
/// <param name="objectType">the object's type</param>
|
||||
/// <param name="attributeType">the <see cref="Attribute"/> type to match agains.</param>
|
||||
/// <param name="checkInherited">whether to check base classes and intefaces for the specified attribute.</param>
|
||||
/// <returns><see langword="true"/> if the attributes is found</returns>
|
||||
protected virtual bool IsAnnotatedWithAttribute( Type objectType, Type attributeType, bool checkInherited )
|
||||
{
|
||||
if (checkInherited)
|
||||
{
|
||||
return AttributeUtils.FindAttribute( objectType, attributeType ) != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
object[] atts = objectType.GetCustomAttributes( attributeType, false );
|
||||
return ArrayUtils.HasLength( atts );
|
||||
}
|
||||
AssertUtils.ArgumentNotNull(value, "AttributeTypes");
|
||||
_attributeTypes = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines, whether the given object shall be proxied by matching <paramref name="targetType"/> against <see cref="AttributeTypes"/>.
|
||||
/// </summary>
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
protected override bool IsEligibleForProxying(Type targetType, string targetName)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(this.AttributeTypes, "AttributeTypes");
|
||||
|
||||
bool shallProxy = IsAnnotatedWithAnyOfAttribute(targetType, this.AttributeTypes, this.CheckInherited);
|
||||
return shallProxy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if <paramref name="objectType"/> is annotated with any of the attributes within the given list of <paramref name="attributeTypes"/>.
|
||||
/// </summary>
|
||||
/// <param name="objectType">the object's type</param>
|
||||
/// <param name="attributeTypes">the list of <see cref="Attribute"/> types to match agains.</param>
|
||||
/// <param name="checkInherited">whether to check base classes and intefaces for any of the given attributes.</param>
|
||||
/// <returns><see langword="true"/> if any of the attributes is found</returns>
|
||||
protected virtual bool IsAnnotatedWithAnyOfAttribute(Type objectType, Type[] attributeTypes, bool checkInherited)
|
||||
{
|
||||
foreach (Type attributeType in attributeTypes)
|
||||
{
|
||||
if (IsAnnotatedWithAttribute(objectType, attributeType, checkInherited))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if <paramref name="objectType"/> is annotated with the specified <paramref name="attributeType"/>.
|
||||
/// </summary>
|
||||
/// <param name="objectType">the object's type</param>
|
||||
/// <param name="attributeType">the <see cref="Attribute"/> type to match agains.</param>
|
||||
/// <param name="checkInherited">whether to check base classes and intefaces for the specified attribute.</param>
|
||||
/// <returns><see langword="true"/> if the attributes is found</returns>
|
||||
protected virtual bool IsAnnotatedWithAttribute(Type objectType, Type attributeType, bool checkInherited)
|
||||
{
|
||||
if (checkInherited)
|
||||
{
|
||||
return AttributeUtils.FindAttribute(objectType, attributeType) != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
object[] atts = objectType.GetCustomAttributes(attributeType, false);
|
||||
return ArrayUtils.HasLength(atts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,116 +24,117 @@ using Spring.Objects.Factory;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// ObjectPostProcessor implementation that creates AOP proxies based on all candidate
|
||||
/// Advisors in the current IObjectFactory. This class is completely generic; it contains
|
||||
/// no special code to handle any particular aspects, such as pooling aspects.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
public class DefaultAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator, IObjectNameAware, IInitializingObject
|
||||
{
|
||||
/// <summary>
|
||||
/// ObjectPostProcessor implementation that creates AOP proxies based on all candidate
|
||||
/// Advisors in the current IObjectFactory. This class is completely generic; it contains
|
||||
/// no special code to handle any particular aspects, such as pooling aspects.
|
||||
/// Separator between prefix and remainder of object name
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
public class DefaultAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator, IObjectNameAware, IInitializingObject
|
||||
public const string Separator = ".";
|
||||
|
||||
private bool usePrefix;
|
||||
private string advisorObjectNamePrefix;
|
||||
private List<IAdvisor> cachedAdvisors;
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to exclude
|
||||
/// advisors with a certain prefix.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [use prefix]; otherwise, <c>false</c>.</value>
|
||||
public bool UsePrefix
|
||||
{
|
||||
/// <summary>
|
||||
/// Separator between prefix and remainder of object name
|
||||
/// </summary>
|
||||
public const string Separator = ".";
|
||||
get { return usePrefix; }
|
||||
set { usePrefix = value; }
|
||||
}
|
||||
|
||||
private bool usePrefix;
|
||||
private string advisorObjectNamePrefix;
|
||||
private List<IAdvisor> cachedAdvisors;
|
||||
/// <summary>
|
||||
/// Set the prefix for object names that will cause them to be included for
|
||||
/// auto-proxying by this object. This prefix should be set to avoid circular
|
||||
/// references. Default value is the object name of this object + a dot.
|
||||
/// </summary>
|
||||
/// <value>The advisor object name prefix.</value>
|
||||
public string AdvisorObjectNamePrefix
|
||||
{
|
||||
get { return advisorObjectNamePrefix; }
|
||||
set { advisorObjectNamePrefix = value; }
|
||||
}
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to exclude
|
||||
/// advisors with a certain prefix.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [use prefix]; otherwise, <c>false</c>.</value>
|
||||
public bool UsePrefix
|
||||
#region IObjectNameAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Set the name of the object in the object factory that created this object.
|
||||
/// </summary>
|
||||
/// <value>The name of the object in the factory.</value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="T:Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="M:Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public string ObjectName
|
||||
{
|
||||
set
|
||||
{
|
||||
get { return usePrefix; }
|
||||
set { usePrefix = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the prefix for object names that will cause them to be included for
|
||||
/// auto-proxying by this object. This prefix should be set to avoid circular
|
||||
/// references. Default value is the object name of this object + a dot.
|
||||
/// </summary>
|
||||
/// <value>The advisor object name prefix.</value>
|
||||
public string AdvisorObjectNamePrefix
|
||||
{
|
||||
get { return advisorObjectNamePrefix; }
|
||||
set { advisorObjectNamePrefix = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IObjectNameAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Set the name of the object in the object factory that created this object.
|
||||
/// </summary>
|
||||
/// <value>The name of the object in the factory.</value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="T:Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="M:Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public string ObjectName
|
||||
{
|
||||
set
|
||||
// If no infrastructure object name prefix has been set, override it.
|
||||
if (advisorObjectNamePrefix == null)
|
||||
{
|
||||
// If no infrastructure object name prefix has been set, override it.
|
||||
if (advisorObjectNamePrefix == null)
|
||||
{
|
||||
advisorObjectNamePrefix = value + Separator;
|
||||
}
|
||||
advisorObjectNamePrefix = value + Separator;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Find all possible advisor candidates to use in auto-proxying
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>the list of candidate advisors</returns>
|
||||
protected override List<IAdvisor> FindCandidateAdvisors(Type targetType, string targetName)
|
||||
{
|
||||
if (cachedAdvisors == null) {
|
||||
cachedAdvisors = base.FindCandidateAdvisors(targetType, targetName);
|
||||
}
|
||||
return cachedAdvisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the given advisor is eligible for the specified target.
|
||||
/// </summary>
|
||||
/// <param name="advisorName">the advisor name</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
protected override bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
|
||||
{
|
||||
return (!usePrefix || advisorName.StartsWith(advisorObjectNamePrefix))
|
||||
&& base.IsEligibleAdvisorObject(advisorName, targetType, targetName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate configuration
|
||||
/// </summary>
|
||||
public virtual void AfterPropertiesSet()
|
||||
{
|
||||
// eagerly resolve advisors at this stage already to prevent circular dep problems.
|
||||
// TODO (EE): fix instantiation process to make test "AdvisorAutoProxyCreatorCircularReferencesTests" work.
|
||||
cachedAdvisors = base.FindCandidateAdvisors(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Find all possible advisor candidates to use in auto-proxying
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>the list of candidate advisors</returns>
|
||||
protected override List<IAdvisor> FindCandidateAdvisors(Type targetType, string targetName)
|
||||
{
|
||||
if (cachedAdvisors == null)
|
||||
{
|
||||
cachedAdvisors = base.FindCandidateAdvisors(targetType, targetName);
|
||||
}
|
||||
|
||||
return cachedAdvisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the given advisor is eligible for the specified target.
|
||||
/// </summary>
|
||||
/// <param name="advisorName">the advisor name</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
protected override bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
|
||||
{
|
||||
return (!usePrefix || advisorName.StartsWith(advisorObjectNamePrefix))
|
||||
&& base.IsEligibleAdvisorObject(advisorName, targetType, targetName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate configuration
|
||||
/// </summary>
|
||||
public virtual void AfterPropertiesSet()
|
||||
{
|
||||
// eagerly resolve advisors at this stage already to prevent circular dep problems.
|
||||
// TODO (EE): fix instantiation process to make test "AdvisorAutoProxyCreatorCircularReferencesTests" work.
|
||||
cachedAdvisors = base.FindCandidateAdvisors(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Interface encapsulating the advisor retrieval strategy used by
|
||||
/// an <see cref="AbstractAdvisorAutoProxyCreator"/> to retrieve the
|
||||
/// applicable list of advisor objects.
|
||||
/// </summary>
|
||||
public interface IAdvisorRetrievalHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface encapsulating the advisor retrieval strategy used by
|
||||
/// an <see cref="AbstractAdvisorAutoProxyCreator"/> to retrieve the
|
||||
/// applicable list of advisor objects.
|
||||
/// Get the list of advisor objects to apply on the target.
|
||||
/// </summary>
|
||||
public interface IAdvisorRetrievalHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the list of advisor objects to apply on the target.
|
||||
/// </summary>
|
||||
List<IAdvisor> FindAdvisorObjects(Type targetType, string targetName);
|
||||
}
|
||||
List<IAdvisor> FindAdvisorObjects(Type targetType, string targetName);
|
||||
}
|
||||
|
||||
@@ -24,28 +24,27 @@ using Spring.Objects.Factory;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Implementations can create special target sources, such as pooling target
|
||||
/// sources, for particular objects. For example, they may base their choice
|
||||
/// on attributes, such as a pooling attribute, on the target type.
|
||||
/// </summary>
|
||||
/// <remarks><p>AbstractAutoProxyCreator can support a number of TargetSourceCreators,
|
||||
/// which will be applied in order.</p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
public interface ITargetSourceCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementations can create special target sources, such as pooling target
|
||||
/// sources, for particular objects. For example, they may base their choice
|
||||
/// on attributes, such as a pooling attribute, on the target type.
|
||||
/// Create a special TargetSource for the given object, if any.
|
||||
/// </summary>
|
||||
/// <remarks><p>AbstractAutoProxyCreator can support a number of TargetSourceCreators,
|
||||
/// which will be applied in order.</p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
public interface ITargetSourceCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a special TargetSource for the given object, if any.
|
||||
/// </summary>
|
||||
/// <param name="objectType">The type of the object to create a TargetSource for</param>
|
||||
/// <param name="objectName">the name of the object</param>
|
||||
/// <param name="factory">the containing factory</param>
|
||||
/// <returns>a special TargetSource or null if this TargetSourceCreator isn't
|
||||
/// interested in the particular object</returns>
|
||||
ITargetSource GetTargetSource(Type objectType, string objectName, IObjectFactory factory);
|
||||
}
|
||||
/// <param name="objectType">The type of the object to create a TargetSource for</param>
|
||||
/// <param name="objectName">the name of the object</param>
|
||||
/// <param name="factory">the containing factory</param>
|
||||
/// <returns>a special TargetSource or null if this TargetSourceCreator isn't
|
||||
/// interested in the particular object</returns>
|
||||
ITargetSource GetTargetSource(Type objectType, string objectName, IObjectFactory factory);
|
||||
}
|
||||
|
||||
@@ -20,41 +20,40 @@
|
||||
|
||||
using Spring.Objects.Factory.Config;
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// A special version of an APC that explicitely cares for infrastructure (=internal)
|
||||
/// advisors only
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class InfrastructureAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// A special version of an APC that explicitely cares for infrastructure (=internal)
|
||||
/// advisors only
|
||||
/// Overridden to create a special version of an <see cref="IAdvisorRetrievalHelper"/>
|
||||
/// that accepts only infrastructure advisor definitions
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class InfrastructureAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator
|
||||
/// <param name="objectFactory"></param>
|
||||
/// <returns></returns>
|
||||
protected override IAdvisorRetrievalHelper CreateAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
/// <summary>
|
||||
/// Overridden to create a special version of an <see cref="IAdvisorRetrievalHelper"/>
|
||||
/// that accepts only infrastructure advisor definitions
|
||||
/// </summary>
|
||||
/// <param name="objectFactory"></param>
|
||||
/// <returns></returns>
|
||||
protected override IAdvisorRetrievalHelper CreateAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory)
|
||||
return new InfrastructurAdvisorRetrievalHelper(this, objectFactory);
|
||||
}
|
||||
|
||||
private class InfrastructurAdvisorRetrievalHelper : ObjectFactoryAdvisorRetrievalHelper
|
||||
{
|
||||
private readonly InfrastructureAdvisorAutoProxyCreator _owner;
|
||||
|
||||
public InfrastructurAdvisorRetrievalHelper(InfrastructureAdvisorAutoProxyCreator owner, IConfigurableListableObjectFactory objectFactory)
|
||||
: base(objectFactory)
|
||||
{
|
||||
return new InfrastructurAdvisorRetrievalHelper(this, objectFactory);
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
private class InfrastructurAdvisorRetrievalHelper : ObjectFactoryAdvisorRetrievalHelper
|
||||
protected override bool IsEligibleObject(string advisorName, Type objectType, string objectName)
|
||||
{
|
||||
private readonly InfrastructureAdvisorAutoProxyCreator _owner;
|
||||
|
||||
public InfrastructurAdvisorRetrievalHelper(InfrastructureAdvisorAutoProxyCreator owner, IConfigurableListableObjectFactory objectFactory)
|
||||
: base(objectFactory)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
protected override bool IsEligibleObject(string advisorName, Type objectType, string objectName)
|
||||
{
|
||||
return this.ObjectFactory.ContainsObjectDefinition(advisorName)
|
||||
&& this.ObjectFactory.GetObjectDefinition(advisorName).Role == ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
}
|
||||
return this.ObjectFactory.ContainsObjectDefinition(advisorName)
|
||||
&& this.ObjectFactory.GetObjectDefinition(advisorName).Role == ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using AopAlliance.Aop;
|
||||
|
||||
using Spring.Util;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Config;
|
||||
@@ -27,310 +25,310 @@ using Spring.Aop.Framework.Adapter;
|
||||
using Spring.Aop.Framework.DynamicProxy;
|
||||
using Spring.Core;
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IObjectFactoryPostProcessor"/> implementation that replaces a group of objects
|
||||
/// with a 'true' inheritance based AOP mechanism that delegates
|
||||
/// to the given interceptors before invoking the object itself.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class InheritanceBasedAopConfigurer : IObjectFactoryPostProcessor, IObjectFactoryAware, IOrdered
|
||||
{
|
||||
private IList objectNames;
|
||||
private string[] interceptorNames = new string[0];
|
||||
private bool proxyTargetAttributes = true;
|
||||
private bool proxyDeclaredMembersOnly = true;
|
||||
private bool proxyInterfaces = false;
|
||||
|
||||
private IObjectFactory objectFactory;
|
||||
private int order = int.MaxValue;
|
||||
private IAdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.Instance;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IObjectFactoryPostProcessor"/> implementation that replaces a group of objects
|
||||
/// with a 'true' inheritance based AOP mechanism that delegates
|
||||
/// to the given interceptors before invoking the object itself.
|
||||
/// Set the names of the objects in IList fashioned way
|
||||
/// that should automatically get intercepted.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class InheritanceBasedAopConfigurer : IObjectFactoryPostProcessor, IObjectFactoryAware, IOrdered
|
||||
/// <remarks>
|
||||
/// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*"
|
||||
/// will match the object named "myObject" and all objects whose name start with "tx".
|
||||
/// </remarks>
|
||||
public virtual IList ObjectNames
|
||||
{
|
||||
private IList objectNames;
|
||||
private string[] interceptorNames = new string[0];
|
||||
private bool proxyTargetAttributes = true;
|
||||
private bool proxyDeclaredMembersOnly = true;
|
||||
private bool proxyInterfaces = false;
|
||||
set { objectNames = value; }
|
||||
}
|
||||
|
||||
private IObjectFactory objectFactory;
|
||||
private int order = int.MaxValue;
|
||||
private IAdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.Instance;
|
||||
/// <summary>
|
||||
/// Sets the common interceptors, a list of <see cref="AopAlliance.Aop.IAdvice"/>,
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> and introduction object names.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// If this property isn't set, there will be zero common interceptors.
|
||||
/// This is perfectly valid, if "specific" interceptors such as
|
||||
/// matching Advisors are all we want.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The list of <see cref="AopAlliance.Aop.IAdvice"/>,
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> and introduction object names.
|
||||
/// </value>
|
||||
/// <seealso cref="AopAlliance.Aop.IAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAdvisor"/>
|
||||
public virtual string[] InterceptorNames
|
||||
{
|
||||
set { interceptorNames = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the names of the objects in IList fashioned way
|
||||
/// that should automatically get intercepted.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*"
|
||||
/// will match the object named "myObject" and all objects whose name start with "tx".
|
||||
/// </remarks>
|
||||
public virtual IList ObjectNames
|
||||
/// <summary>
|
||||
/// Is target type attributes, method attributes, method's return type attributes
|
||||
/// and method's parameter attributes to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
public virtual bool ProxyTargetAttributes
|
||||
{
|
||||
get { return this.proxyTargetAttributes; }
|
||||
set { this.proxyTargetAttributes = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether inherited members should be proxied.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if inherited members should be proxied;
|
||||
/// otherwise, <see langword="false"/>.
|
||||
/// </value>
|
||||
public bool ProxyDeclaredMembersOnly
|
||||
{
|
||||
get { return proxyDeclaredMembersOnly; }
|
||||
set { proxyDeclaredMembersOnly = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether interfaces members should be proxied.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if interfaces members should be proxied;
|
||||
/// otherwise, <see langword="false"/>.
|
||||
/// </value>
|
||||
public bool ProxyInterfaces
|
||||
{
|
||||
get { return proxyInterfaces; }
|
||||
set { proxyInterfaces = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback that supplies the owning factory to an object instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Owning <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// (may not be <see langword="null"/>). The object can immediately
|
||||
/// call methods on the factory.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of initialization errors.
|
||||
/// </exception>
|
||||
public IObjectFactory ObjectFactory
|
||||
{
|
||||
set { objectFactory = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows for custom modification of an application context's object definitions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If the object name matches, replaces the type by a AOP proxied type based on inheritance.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory)
|
||||
{
|
||||
var objectDefinitionNames = factory.GetObjectDefinitionNames();
|
||||
for (int i = 0; i < objectDefinitionNames.Count; ++i)
|
||||
{
|
||||
set { objectNames = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the common interceptors, a list of <see cref="AopAlliance.Aop.IAdvice"/>,
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> and introduction object names.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// If this property isn't set, there will be zero common interceptors.
|
||||
/// This is perfectly valid, if "specific" interceptors such as
|
||||
/// matching Advisors are all we want.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The list of <see cref="AopAlliance.Aop.IAdvice"/>,
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> and introduction object names.
|
||||
/// </value>
|
||||
/// <seealso cref="AopAlliance.Aop.IAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAdvisor"/>
|
||||
public virtual string[] InterceptorNames
|
||||
{
|
||||
set { interceptorNames = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is target type attributes, method attributes, method's return type attributes
|
||||
/// and method's parameter attributes to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
public virtual bool ProxyTargetAttributes
|
||||
{
|
||||
get { return this.proxyTargetAttributes; }
|
||||
set { this.proxyTargetAttributes = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether inherited members should be proxied.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if inherited members should be proxied;
|
||||
/// otherwise, <see langword="false"/>.
|
||||
/// </value>
|
||||
public bool ProxyDeclaredMembersOnly
|
||||
{
|
||||
get { return proxyDeclaredMembersOnly; }
|
||||
set { proxyDeclaredMembersOnly = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether interfaces members should be proxied.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if interfaces members should be proxied;
|
||||
/// otherwise, <see langword="false"/>.
|
||||
/// </value>
|
||||
public bool ProxyInterfaces
|
||||
{
|
||||
get { return proxyInterfaces; }
|
||||
set { proxyInterfaces = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback that supplies the owning factory to an object instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Owning <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// (may not be <see langword="null"/>). The object can immediately
|
||||
/// call methods on the factory.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of initialization errors.
|
||||
/// </exception>
|
||||
public IObjectFactory ObjectFactory
|
||||
{
|
||||
set { objectFactory = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows for custom modification of an application context's object definitions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If the object name matches, replaces the type by a AOP proxied type based on inheritance.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory)
|
||||
{
|
||||
var objectDefinitionNames = factory.GetObjectDefinitionNames();
|
||||
for (int i = 0; i < objectDefinitionNames.Count; ++i)
|
||||
string name = objectDefinitionNames[i];
|
||||
if (IsObjectNameMatch(name))
|
||||
{
|
||||
string name = objectDefinitionNames[i];
|
||||
if (IsObjectNameMatch(name))
|
||||
var definition = factory.GetObjectDefinition(name) as IConfigurableObjectDefinition;
|
||||
|
||||
if (definition == null || IsInfrastructureType(definition.ObjectType, name))
|
||||
{
|
||||
var definition = factory.GetObjectDefinition(name) as IConfigurableObjectDefinition;
|
||||
|
||||
if (definition == null || IsInfrastructureType(definition.ObjectType, name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ProxyFactory pf = CreateProxyFactory(definition.ObjectType, name);
|
||||
|
||||
InheritanceAopProxyTypeBuilder iaptb = new InheritanceAopProxyTypeBuilder(pf);
|
||||
iaptb.ProxyDeclaredMembersOnly = this.ProxyDeclaredMembersOnly;
|
||||
Type type = iaptb.BuildProxyType();
|
||||
|
||||
definition.ObjectType = type;
|
||||
definition.ConstructorArgumentValues.AddIndexedArgumentValue(definition.ConstructorArgumentValues.ArgumentCount, pf);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the order value of this object, where a higher value means greater in
|
||||
/// terms of sorting.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ordering which will apply to this class's implementation
|
||||
/// of Ordered, used when applying multiple ObjectPostProcessors.
|
||||
/// Default value is int.MaxValue, meaning that it's non-ordered.
|
||||
/// </remarks>
|
||||
/// <returns>The order value.</returns>
|
||||
public virtual int Order
|
||||
{
|
||||
get { return order; }
|
||||
set { order = value; }
|
||||
}
|
||||
ProxyFactory pf = CreateProxyFactory(definition.ObjectType, name);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the object is an infrastructure type,
|
||||
/// IAdvisor, IAdvice, IAdvisors, AbstractAutoProxyCreator or InheritanceBasedAopConfigurer.
|
||||
/// </summary>
|
||||
/// <param name="type">The object type to compare</param>
|
||||
/// <param name="name">The name of the object</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is infrastructure type] [the specified obj]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected virtual bool IsInfrastructureType(Type type, String name)
|
||||
{
|
||||
return typeof(IAdvisor).IsAssignableFrom(type)
|
||||
|| typeof(IAdvice).IsAssignableFrom(type)
|
||||
|| typeof(IAdvisors).IsAssignableFrom(type)
|
||||
|| typeof(AbstractAutoProxyCreator).IsAssignableFrom(type)
|
||||
|| typeof(InheritanceBasedAopConfigurer).IsAssignableFrom(type);
|
||||
}
|
||||
InheritanceAopProxyTypeBuilder iaptb = new InheritanceAopProxyTypeBuilder(pf);
|
||||
iaptb.ProxyDeclaredMembersOnly = this.ProxyDeclaredMembersOnly;
|
||||
Type type = iaptb.BuildProxyType();
|
||||
|
||||
/// <summary>
|
||||
/// Create an AOP proxy for the given object.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="objectName">The name of the object.</param>
|
||||
/// <returns>The AOP Proxy for the object.</returns>
|
||||
protected virtual ProxyFactory CreateProxyFactory(Type objectType, string objectName)
|
||||
{
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.ProxyTargetAttributes = this.ProxyTargetAttributes;
|
||||
proxyFactory.TargetSource = new InheritanceBasedAopTargetSource(objectType);
|
||||
if (!ProxyInterfaces)
|
||||
{
|
||||
proxyFactory.Interfaces = Type.EmptyTypes;
|
||||
}
|
||||
|
||||
IList<IAdvisor> advisors = ResolveInterceptorNames();
|
||||
foreach (IAdvisor advisor in advisors)
|
||||
{
|
||||
if (advisor is IIntroductionAdvisor)
|
||||
{
|
||||
proxyFactory.AddIntroduction((IIntroductionAdvisor)advisor);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyFactory.AddAdvisor(advisor);
|
||||
}
|
||||
}
|
||||
|
||||
return proxyFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return if the given object name matches one of the object names specified.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
|
||||
/// as well as direct equality. Can be overridden in subclasses.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="objectName">the object name to check</param>
|
||||
/// <returns>if the names match</returns>
|
||||
protected virtual bool IsObjectNameMatch(string objectName)
|
||||
{
|
||||
if (objectNames != null)
|
||||
{
|
||||
for (int i = 0; i < objectNames.Count; i++)
|
||||
{
|
||||
string mappedName = String.Copy((string)objectNames[i]);
|
||||
if (PatternMatchUtils.SimpleMatch(mappedName, objectName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private IList<IAdvisor> ResolveInterceptorNames()
|
||||
{
|
||||
List<IAdvisor> advisors = new List<IAdvisor>();
|
||||
foreach (string name in interceptorNames)
|
||||
{
|
||||
object next = objectFactory.GetObject(name);
|
||||
if (next is IAdvisors)
|
||||
{
|
||||
advisors.AddRange(((IAdvisors)next).Advisors);
|
||||
}
|
||||
else
|
||||
{
|
||||
advisors.Add(advisorAdapterRegistry.Wrap(next));
|
||||
}
|
||||
}
|
||||
return advisors;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class InheritanceBasedAopTargetSource : ITargetSource, ISerializable
|
||||
{
|
||||
private readonly Type _targetType;
|
||||
|
||||
public InheritanceBasedAopTargetSource(Type targetType)
|
||||
{
|
||||
_targetType = targetType;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
private InheritanceBasedAopTargetSource(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
var type = info.GetString("TargetType");
|
||||
_targetType = type != null ? Type.GetType(type) : null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("TargetType", _targetType?.AssemblyQualifiedName);
|
||||
}
|
||||
|
||||
public object GetTarget()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsStatic
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void ReleaseTarget(object target)
|
||||
{
|
||||
}
|
||||
|
||||
public Type TargetType
|
||||
{
|
||||
get { return _targetType; }
|
||||
definition.ObjectType = type;
|
||||
definition.ConstructorArgumentValues.AddIndexedArgumentValue(definition.ConstructorArgumentValues.ArgumentCount, pf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the order value of this object, where a higher value means greater in
|
||||
/// terms of sorting.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ordering which will apply to this class's implementation
|
||||
/// of Ordered, used when applying multiple ObjectPostProcessors.
|
||||
/// Default value is int.MaxValue, meaning that it's non-ordered.
|
||||
/// </remarks>
|
||||
/// <returns>The order value.</returns>
|
||||
public virtual int Order
|
||||
{
|
||||
get { return order; }
|
||||
set { order = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the object is an infrastructure type,
|
||||
/// IAdvisor, IAdvice, IAdvisors, AbstractAutoProxyCreator or InheritanceBasedAopConfigurer.
|
||||
/// </summary>
|
||||
/// <param name="type">The object type to compare</param>
|
||||
/// <param name="name">The name of the object</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is infrastructure type] [the specified obj]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected virtual bool IsInfrastructureType(Type type, String name)
|
||||
{
|
||||
return typeof(IAdvisor).IsAssignableFrom(type)
|
||||
|| typeof(IAdvice).IsAssignableFrom(type)
|
||||
|| typeof(IAdvisors).IsAssignableFrom(type)
|
||||
|| typeof(AbstractAutoProxyCreator).IsAssignableFrom(type)
|
||||
|| typeof(InheritanceBasedAopConfigurer).IsAssignableFrom(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an AOP proxy for the given object.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="objectName">The name of the object.</param>
|
||||
/// <returns>The AOP Proxy for the object.</returns>
|
||||
protected virtual ProxyFactory CreateProxyFactory(Type objectType, string objectName)
|
||||
{
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.ProxyTargetAttributes = this.ProxyTargetAttributes;
|
||||
proxyFactory.TargetSource = new InheritanceBasedAopTargetSource(objectType);
|
||||
if (!ProxyInterfaces)
|
||||
{
|
||||
proxyFactory.Interfaces = Type.EmptyTypes;
|
||||
}
|
||||
|
||||
IList<IAdvisor> advisors = ResolveInterceptorNames();
|
||||
foreach (IAdvisor advisor in advisors)
|
||||
{
|
||||
if (advisor is IIntroductionAdvisor)
|
||||
{
|
||||
proxyFactory.AddIntroduction((IIntroductionAdvisor) advisor);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyFactory.AddAdvisor(advisor);
|
||||
}
|
||||
}
|
||||
|
||||
return proxyFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return if the given object name matches one of the object names specified.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
|
||||
/// as well as direct equality. Can be overridden in subclasses.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="objectName">the object name to check</param>
|
||||
/// <returns>if the names match</returns>
|
||||
protected virtual bool IsObjectNameMatch(string objectName)
|
||||
{
|
||||
if (objectNames != null)
|
||||
{
|
||||
for (int i = 0; i < objectNames.Count; i++)
|
||||
{
|
||||
string mappedName = String.Copy((string) objectNames[i]);
|
||||
if (PatternMatchUtils.SimpleMatch(mappedName, objectName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private IList<IAdvisor> ResolveInterceptorNames()
|
||||
{
|
||||
List<IAdvisor> advisors = new List<IAdvisor>();
|
||||
foreach (string name in interceptorNames)
|
||||
{
|
||||
object next = objectFactory.GetObject(name);
|
||||
if (next is IAdvisors)
|
||||
{
|
||||
advisors.AddRange(((IAdvisors) next).Advisors);
|
||||
}
|
||||
else
|
||||
{
|
||||
advisors.Add(advisorAdapterRegistry.Wrap(next));
|
||||
}
|
||||
}
|
||||
|
||||
return advisors;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class InheritanceBasedAopTargetSource : ITargetSource, ISerializable
|
||||
{
|
||||
private readonly Type _targetType;
|
||||
|
||||
public InheritanceBasedAopTargetSource(Type targetType)
|
||||
{
|
||||
_targetType = targetType;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
private InheritanceBasedAopTargetSource(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
var type = info.GetString("TargetType");
|
||||
_targetType = type != null ? Type.GetType(type) : null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("TargetType", _targetType?.AssemblyQualifiedName);
|
||||
}
|
||||
|
||||
public object GetTarget()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsStatic
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void ReleaseTarget(object target)
|
||||
{
|
||||
}
|
||||
|
||||
public Type TargetType
|
||||
{
|
||||
get { return _targetType; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,152 +23,155 @@ using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Helper for retrieving standard Spring advisors from an <see cref="IObjectFactory"/> for
|
||||
/// use with auto-proxying.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class ObjectFactoryAdvisorRetrievalHelper : IAdvisorRetrievalHelper
|
||||
{
|
||||
private readonly ILogger _log;
|
||||
private readonly IConfigurableListableObjectFactory _objectFactory;
|
||||
private List<string> _cachedObjectNames;
|
||||
|
||||
/// <summary>
|
||||
/// Helper for retrieving standard Spring advisors from an <see cref="IObjectFactory"/> for
|
||||
/// use with auto-proxying.
|
||||
/// The object factory to lookup advisors from
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class ObjectFactoryAdvisorRetrievalHelper : IAdvisorRetrievalHelper
|
||||
public IConfigurableListableObjectFactory ObjectFactory
|
||||
{
|
||||
private readonly ILogger _log;
|
||||
private readonly IConfigurableListableObjectFactory _objectFactory;
|
||||
private List<string> _cachedObjectNames;
|
||||
get { return _objectFactory; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object factory to lookup advisors from
|
||||
/// </summary>
|
||||
public IConfigurableListableObjectFactory ObjectFactory
|
||||
/// <summary>
|
||||
/// Create a new helper for the specified <paramref name="objectFactory"/>.
|
||||
/// </summary>
|
||||
public ObjectFactoryAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(objectFactory, "objectFactory");
|
||||
_log = LogManager.GetLogger(this.GetType());
|
||||
_objectFactory = objectFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all all eligible advisor objects in the current object factory.
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>A list of eligible <see cref="IAdvisor"/> instances</returns>
|
||||
public virtual List<IAdvisor> FindAdvisorObjects(Type targetType, string targetName)
|
||||
{
|
||||
IList<string> advisorNames = GetAdvisorCandidateNames(targetType, targetName);
|
||||
|
||||
List<IAdvisor> advisors = new List<IAdvisor>();
|
||||
|
||||
if (advisorNames.Count == 0)
|
||||
{
|
||||
get { return _objectFactory; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new helper for the specified <paramref name="objectFactory"/>.
|
||||
/// </summary>
|
||||
public ObjectFactoryAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(objectFactory, "objectFactory");
|
||||
_log = LogManager.GetLogger(this.GetType());
|
||||
_objectFactory = objectFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all all eligible advisor objects in the current object factory.
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>A list of eligible <see cref="IAdvisor"/> instances</returns>
|
||||
public virtual List<IAdvisor> FindAdvisorObjects(Type targetType, string targetName)
|
||||
{
|
||||
IList<string> advisorNames = GetAdvisorCandidateNames(targetType, targetName);
|
||||
|
||||
List<IAdvisor> advisors = new List<IAdvisor>();
|
||||
|
||||
if (advisorNames.Count == 0)
|
||||
{
|
||||
return advisors;
|
||||
}
|
||||
|
||||
for (int i = 0; i < advisorNames.Count; i++)
|
||||
{
|
||||
string name = advisorNames[i];
|
||||
if (IsEligibleObject(name, targetType, targetName) && !_objectFactory.IsCurrentlyInCreation(name))
|
||||
{
|
||||
try
|
||||
{
|
||||
AddAdvisorCandidate(advisors, name);
|
||||
}
|
||||
catch (ObjectCreationException ex)
|
||||
{
|
||||
Exception rootEx = ex.GetBaseException();
|
||||
if (rootEx is ObjectCurrentlyInCreationException)
|
||||
{
|
||||
ObjectCurrentlyInCreationException oce = (ObjectCurrentlyInCreationException)rootEx;
|
||||
if (_objectFactory.IsCurrentlyInCreation(oce.ObjectName))
|
||||
{
|
||||
if (_log.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
_log.LogDebug(string.Format("Ignoring currently created advisor '{0}': exception message = {1}",
|
||||
name, ex.Message));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return advisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the named advisor instance to the list of advisors.
|
||||
/// </summary>
|
||||
/// <param name="advisors">the advisor list</param>
|
||||
/// <param name="advisorName">the object name of the advisor to add</param>
|
||||
private void AddAdvisorCandidate(List<IAdvisor> advisors, string advisorName)
|
||||
for (int i = 0; i < advisorNames.Count; i++)
|
||||
{
|
||||
object advisorCandidate = _objectFactory.GetObject(advisorName);
|
||||
if (advisorCandidate is IAdvisor)
|
||||
string name = advisorNames[i];
|
||||
if (IsEligibleObject(name, targetType, targetName) && !_objectFactory.IsCurrentlyInCreation(name))
|
||||
{
|
||||
advisors.Add((IAdvisor) advisorCandidate);
|
||||
}
|
||||
else if (advisorCandidate is IAdvisors)
|
||||
{
|
||||
advisors.AddRange(((IAdvisors)advisorCandidate).Advisors);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("expected type IAdvisor or IAdvisors but was " +
|
||||
advisorCandidate.GetType().FullName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of advisor candidates
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>a non-null string array of advisor candidate names</returns>
|
||||
protected virtual IList<string> GetAdvisorCandidateNames(Type targetType, string targetName)
|
||||
{
|
||||
if (_cachedObjectNames == null)
|
||||
{
|
||||
lock(this)
|
||||
try
|
||||
{
|
||||
if (_cachedObjectNames == null)
|
||||
AddAdvisorCandidate(advisors, name);
|
||||
}
|
||||
catch (ObjectCreationException ex)
|
||||
{
|
||||
Exception rootEx = ex.GetBaseException();
|
||||
if (rootEx is ObjectCurrentlyInCreationException)
|
||||
{
|
||||
List<string> candidateNameList = new List<string>();
|
||||
IList<string> advisorCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors( _objectFactory, typeof(IAdvisor), true, false);
|
||||
candidateNameList.AddRange(advisorCandidateNames);
|
||||
IList<string> advisorsCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_objectFactory, typeof(IAdvisors), true, false);
|
||||
candidateNameList.AddRange(advisorsCandidateNames);
|
||||
_cachedObjectNames = candidateNameList;
|
||||
ObjectCurrentlyInCreationException oce = (ObjectCurrentlyInCreationException) rootEx;
|
||||
if (_objectFactory.IsCurrentlyInCreation(oce.ObjectName))
|
||||
{
|
||||
if (_log.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
_log.LogDebug(string.Format("Ignoring currently created advisor '{0}': exception message = {1}",
|
||||
name, ex.Message));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return _cachedObjectNames;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine, whether the specified aspect object is eligible.
|
||||
/// The default implementation accepts all except for advisors that are
|
||||
/// part of the internal infrastructure.
|
||||
/// </summary>
|
||||
/// <param name="advisorName">the name of the candidate advisor</param>
|
||||
/// <param name="objectType">the type of the object to be advised</param>
|
||||
/// <param name="objectName">the name of the object to be advised</param>
|
||||
protected virtual bool IsEligibleObject(string advisorName, Type objectType, string objectName )
|
||||
return advisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the named advisor instance to the list of advisors.
|
||||
/// </summary>
|
||||
/// <param name="advisors">the advisor list</param>
|
||||
/// <param name="advisorName">the object name of the advisor to add</param>
|
||||
private void AddAdvisorCandidate(List<IAdvisor> advisors, string advisorName)
|
||||
{
|
||||
object advisorCandidate = _objectFactory.GetObject(advisorName);
|
||||
if (advisorCandidate is IAdvisor)
|
||||
{
|
||||
bool containsObjectDefinition = this.ObjectFactory.ContainsObjectDefinition(advisorName);
|
||||
if (containsObjectDefinition)
|
||||
advisors.Add((IAdvisor) advisorCandidate);
|
||||
}
|
||||
else if (advisorCandidate is IAdvisors)
|
||||
{
|
||||
advisors.AddRange(((IAdvisors) advisorCandidate).Advisors);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("expected type IAdvisor or IAdvisors but was " +
|
||||
advisorCandidate.GetType().FullName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of advisor candidates
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>a non-null string array of advisor candidate names</returns>
|
||||
protected virtual IList<string> GetAdvisorCandidateNames(Type targetType, string targetName)
|
||||
{
|
||||
if (_cachedObjectNames == null)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return this.ObjectFactory.GetObjectDefinition(advisorName).Role != ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
if (_cachedObjectNames == null)
|
||||
{
|
||||
List<string> candidateNameList = new List<string>();
|
||||
IList<string> advisorCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_objectFactory, typeof(IAdvisor), true, false);
|
||||
candidateNameList.AddRange(advisorCandidateNames);
|
||||
IList<string> advisorsCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_objectFactory, typeof(IAdvisors), true, false);
|
||||
candidateNameList.AddRange(advisorsCandidateNames);
|
||||
_cachedObjectNames = candidateNameList;
|
||||
}
|
||||
}
|
||||
return this.ObjectFactory.ContainsObject(advisorName);
|
||||
}
|
||||
}
|
||||
|
||||
return _cachedObjectNames;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine, whether the specified aspect object is eligible.
|
||||
/// The default implementation accepts all except for advisors that are
|
||||
/// part of the internal infrastructure.
|
||||
/// </summary>
|
||||
/// <param name="advisorName">the name of the candidate advisor</param>
|
||||
/// <param name="objectType">the type of the object to be advised</param>
|
||||
/// <param name="objectName">the name of the object to be advised</param>
|
||||
protected virtual bool IsEligibleObject(string advisorName, Type objectType, string objectName)
|
||||
{
|
||||
bool containsObjectDefinition = this.ObjectFactory.ContainsObjectDefinition(advisorName);
|
||||
if (containsObjectDefinition)
|
||||
{
|
||||
return this.ObjectFactory.GetObjectDefinition(advisorName).Role != ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
}
|
||||
|
||||
return this.ObjectFactory.ContainsObject(advisorName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,114 +22,117 @@ using System.Collections;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// AutoProxyCreator that identifies objects to proxy via a list of names.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Auto proxy creator that identifies objects to proxy via a list of names.
|
||||
/// Checks for direct, "xxx*", "*xxx" and "*xxx*" matches.
|
||||
/// </para>
|
||||
/// <para>In case of a IFactoryObject, only the objects created by the
|
||||
/// FactoryBean will get proxied. If you intend to proxy a IFactoryObject instance itself
|
||||
/// specify the object name of the IFactoryObject including
|
||||
/// the factory-object prefix "&" e.g. "&MyFactoryObject".
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator.IsMatch"/>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class ObjectNameAutoProxyCreator : AbstractFilteringAutoProxyCreator
|
||||
{
|
||||
private IList objectNames;
|
||||
|
||||
/// <summary>
|
||||
/// AutoProxyCreator that identifies objects to proxy via a list of names.
|
||||
/// Initializes a new instance of <see cref="ObjectNameAutoProxyCreator"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Auto proxy creator that identifies objects to proxy via a list of names.
|
||||
/// Checks for direct, "xxx*", "*xxx" and "*xxx*" matches.
|
||||
/// </para>
|
||||
/// <para>In case of a IFactoryObject, only the objects created by the
|
||||
/// FactoryBean will get proxied. If you intend to proxy a IFactoryObject instance itself
|
||||
/// specify the object name of the IFactoryObject including
|
||||
/// the factory-object prefix "&" e.g. "&MyFactoryObject".
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator.IsMatch"/>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class ObjectNameAutoProxyCreator : AbstractFilteringAutoProxyCreator
|
||||
public ObjectNameAutoProxyCreator()
|
||||
{
|
||||
private IList objectNames;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ObjectNameAutoProxyCreator"/>.
|
||||
/// </summary>
|
||||
public ObjectNameAutoProxyCreator()
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Set the names of the objects in IList fashioned way that should automatically
|
||||
/// get wrapped with proxies.
|
||||
/// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*"
|
||||
/// will match the object named "myObject" and all objects whose name start with "tx".
|
||||
/// </summary>
|
||||
public IList ObjectNames
|
||||
/// <summary>
|
||||
/// Set the names of the objects in IList fashioned way that should automatically
|
||||
/// get wrapped with proxies.
|
||||
/// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*"
|
||||
/// will match the object named "myObject" and all objects whose name start with "tx".
|
||||
/// </summary>
|
||||
public IList ObjectNames
|
||||
{
|
||||
set
|
||||
{
|
||||
set
|
||||
{
|
||||
AssertUtils.ArgumentHasElements(value, "ObjectNames");
|
||||
objectNames = value;
|
||||
}
|
||||
get
|
||||
{
|
||||
return objectNames;
|
||||
}
|
||||
AssertUtils.ArgumentHasElements(value, "ObjectNames");
|
||||
objectNames = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identify as object to proxy if the object name is in the configured list of names.
|
||||
/// </summary>
|
||||
protected override bool IsEligibleForProxying( Type targetType, string targetName )
|
||||
get
|
||||
{
|
||||
bool shallProxy = IsObjectNameMatch(targetType, targetName, this.ObjectNames);
|
||||
return shallProxy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return if the given object name matches the mapped name.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
|
||||
/// as well as direct equality. Can be overridden in subclasses.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="objectName">the object name to check</param>
|
||||
/// <param name="mappedName">the name in the configured list of names</param>
|
||||
/// <returns>if the names match</returns>
|
||||
protected virtual bool IsMatch( string objectName, string mappedName )
|
||||
{
|
||||
return PatternMatchUtils.SimpleMatch( mappedName, objectName );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method that may be used by derived classes. Iterates over the list of <paramref name="objectNamePatterns"/> to match <paramref name="objectName"/> against.
|
||||
/// </summary>
|
||||
/// <param name="objType">the object's type. Must not be <c>null</c>.</param>
|
||||
/// <param name="objectName">the name of the object Must not be <c>null</c>.</param>
|
||||
/// <param name="objectNamePatterns">the list of patterns, that <paramref name="objectName"/> shall be matched against. Must not be <c>null</c>.</param>
|
||||
/// <returns>
|
||||
/// If <paramref name="objectNamePatterns"/> is <c>null</c>, will always return <c>true</c>, otherwise
|
||||
/// if <paramref name="objectName"/> matches any of the patterns specified in <paramref name="objectNamePatterns"/>.
|
||||
/// </returns>
|
||||
protected bool IsObjectNameMatch(Type objType, string objectName, IList objectNamePatterns)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(objType, "objType");
|
||||
AssertUtils.ArgumentNotNull(objectName, "objectName" );
|
||||
AssertUtils.ArgumentNotNull(objectNamePatterns, "objectNamePatterns");
|
||||
|
||||
for (int i = 0; i < objectNamePatterns.Count; i++)
|
||||
{
|
||||
string mappedName = (string)objectNamePatterns[i];
|
||||
if (typeof(IFactoryObject).IsAssignableFrom(objType))
|
||||
{
|
||||
if (!objectName.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
mappedName = mappedName.Substring(ObjectFactoryUtils.FactoryObjectPrefix.Length);
|
||||
}
|
||||
if (IsMatch(objectName, mappedName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return objectNames;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identify as object to proxy if the object name is in the configured list of names.
|
||||
/// </summary>
|
||||
protected override bool IsEligibleForProxying(Type targetType, string targetName)
|
||||
{
|
||||
bool shallProxy = IsObjectNameMatch(targetType, targetName, this.ObjectNames);
|
||||
return shallProxy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return if the given object name matches the mapped name.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
|
||||
/// as well as direct equality. Can be overridden in subclasses.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="objectName">the object name to check</param>
|
||||
/// <param name="mappedName">the name in the configured list of names</param>
|
||||
/// <returns>if the names match</returns>
|
||||
protected virtual bool IsMatch(string objectName, string mappedName)
|
||||
{
|
||||
return PatternMatchUtils.SimpleMatch(mappedName, objectName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method that may be used by derived classes. Iterates over the list of <paramref name="objectNamePatterns"/> to match <paramref name="objectName"/> against.
|
||||
/// </summary>
|
||||
/// <param name="objType">the object's type. Must not be <c>null</c>.</param>
|
||||
/// <param name="objectName">the name of the object Must not be <c>null</c>.</param>
|
||||
/// <param name="objectNamePatterns">the list of patterns, that <paramref name="objectName"/> shall be matched against. Must not be <c>null</c>.</param>
|
||||
/// <returns>
|
||||
/// If <paramref name="objectNamePatterns"/> is <c>null</c>, will always return <c>true</c>, otherwise
|
||||
/// if <paramref name="objectName"/> matches any of the patterns specified in <paramref name="objectNamePatterns"/>.
|
||||
/// </returns>
|
||||
protected bool IsObjectNameMatch(Type objType, string objectName, IList objectNamePatterns)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(objType, "objType");
|
||||
AssertUtils.ArgumentNotNull(objectName, "objectName");
|
||||
AssertUtils.ArgumentNotNull(objectNamePatterns, "objectNamePatterns");
|
||||
|
||||
for (int i = 0; i < objectNamePatterns.Count; i++)
|
||||
{
|
||||
string mappedName = (string) objectNamePatterns[i];
|
||||
if (typeof(IFactoryObject).IsAssignableFrom(objType))
|
||||
{
|
||||
if (!objectName.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
mappedName = mappedName.Substring(ObjectFactoryUtils.FactoryObjectPrefix.Length);
|
||||
}
|
||||
|
||||
if (IsMatch(objectName, mappedName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,34 +24,33 @@ using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// This AutoProxyCreator only proxies objects matching the specified <see cref="IPointcut"/>.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class PointcutFilteringAutoProxyCreator : AbstractFilteringAutoProxyCreator
|
||||
{
|
||||
private IPointcut _pointcut;
|
||||
|
||||
/// <summary>
|
||||
/// This AutoProxyCreator only proxies objects matching the specified <see cref="IPointcut"/>.
|
||||
/// Set the pointcut used to filter objects that should automatically get wrapped with proxies.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class PointcutFilteringAutoProxyCreator : AbstractFilteringAutoProxyCreator
|
||||
public IPointcut Pointcut
|
||||
{
|
||||
private IPointcut _pointcut;
|
||||
set { _pointcut = value; }
|
||||
get { return _pointcut; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the pointcut used to filter objects that should automatically get wrapped with proxies.
|
||||
/// </summary>
|
||||
public IPointcut Pointcut
|
||||
{
|
||||
set { _pointcut = value; }
|
||||
get { return _pointcut; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines, whether the given object shall be proxied.
|
||||
/// </summary>
|
||||
protected override bool IsEligibleForProxying(Type targetType, string targetName)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(_pointcut, "Pointcut");
|
||||
|
||||
/// <summary>
|
||||
/// Determines, whether the given object shall be proxied.
|
||||
/// </summary>
|
||||
protected override bool IsEligibleForProxying( Type targetType, string targetName )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(_pointcut, "Pointcut");
|
||||
|
||||
bool shallProxy = AopUtils.CanApply( _pointcut, targetType, null );
|
||||
return shallProxy;
|
||||
}
|
||||
bool shallProxy = AopUtils.CanApply(_pointcut, targetType, null);
|
||||
return shallProxy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,80 +27,79 @@ using Spring.Objects.Factory.Support;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy.Target
|
||||
namespace Spring.Aop.Framework.AutoProxy.Target;
|
||||
|
||||
/// <summary>
|
||||
/// Summary description for AbstractPrototypeBasedTargetSourceCreator.
|
||||
/// </summary>
|
||||
public abstract class AbstractPrototypeTargetSourceCreator : ITargetSourceCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for AbstractPrototypeBasedTargetSourceCreator.
|
||||
/// The logger
|
||||
/// </summary>
|
||||
public abstract class AbstractPrototypeTargetSourceCreator : ITargetSourceCreator
|
||||
protected readonly ILogger logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
#region ITargetSourceCreator Members
|
||||
|
||||
/// <summary>
|
||||
/// Create a special TargetSource for the given object, if any.
|
||||
/// </summary>
|
||||
/// <param name="objectType">the type of the object to create a TargetSource for</param>
|
||||
/// <param name="name">the name of the object</param>
|
||||
/// <param name="factory">the containing factory</param>
|
||||
/// <returns>
|
||||
/// a special TargetSource or null if this TargetSourceCreator isn't
|
||||
/// interested in the particular object
|
||||
/// </returns>
|
||||
public ITargetSource GetTargetSource(Type objectType, string name, IObjectFactory factory)
|
||||
{
|
||||
/// <summary>
|
||||
/// The logger
|
||||
/// </summary>
|
||||
protected readonly ILogger logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
#region ITargetSourceCreator Members
|
||||
|
||||
/// <summary>
|
||||
/// Create a special TargetSource for the given object, if any.
|
||||
/// </summary>
|
||||
/// <param name="objectType">the type of the object to create a TargetSource for</param>
|
||||
/// <param name="name">the name of the object</param>
|
||||
/// <param name="factory">the containing factory</param>
|
||||
/// <returns>
|
||||
/// a special TargetSource or null if this TargetSourceCreator isn't
|
||||
/// interested in the particular object
|
||||
/// </returns>
|
||||
public ITargetSource GetTargetSource(Type objectType, string name, IObjectFactory factory)
|
||||
AbstractPrototypeTargetSource prototypeTargetSource = CreatePrototypeTargetSource(objectType, name, factory);
|
||||
if (prototypeTargetSource == null)
|
||||
{
|
||||
AbstractPrototypeTargetSource prototypeTargetSource = CreatePrototypeTargetSource(objectType, name, factory);
|
||||
if (prototypeTargetSource == null)
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(factory is IObjectDefinitionRegistry))
|
||||
{
|
||||
if (logger.IsEnabled(LogLevel.Warning))
|
||||
logger.LogWarning("Cannot do autopooling with a IObjectFactory that doesn't implement IObjectDefinitionRegistry");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(factory is IObjectDefinitionRegistry))
|
||||
{
|
||||
if (logger.IsEnabled(LogLevel.Warning))
|
||||
logger.LogWarning("Cannot do autopooling with a IObjectFactory that doesn't implement IObjectDefinitionRegistry");
|
||||
return null;
|
||||
}
|
||||
IObjectDefinitionRegistry definitionRegistry = (IObjectDefinitionRegistry) factory;
|
||||
RootObjectDefinition definition = (RootObjectDefinition) definitionRegistry.GetObjectDefinition(name);
|
||||
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
logger.LogInformation("Configuring AbstractPrototypeBasedTargetSource...");
|
||||
IObjectDefinitionRegistry definitionRegistry = (IObjectDefinitionRegistry) factory;
|
||||
RootObjectDefinition definition = (RootObjectDefinition) definitionRegistry.GetObjectDefinition(name);
|
||||
|
||||
// Infinite cycle will result if we don't use a different factory,
|
||||
// because a GetObject() call with this objectName will go through the autoproxy
|
||||
// infrastructure again.
|
||||
// We to override just this object definition, as it may reference other objects
|
||||
// and we're happy to take the parent's definition for those.
|
||||
DefaultListableObjectFactory objectFactory = new DefaultListableObjectFactory(factory);
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
logger.LogInformation("Configuring AbstractPrototypeBasedTargetSource...");
|
||||
|
||||
// Override the prototype object
|
||||
objectFactory.RegisterObjectDefinition(name, definition);
|
||||
// Infinite cycle will result if we don't use a different factory,
|
||||
// because a GetObject() call with this objectName will go through the autoproxy
|
||||
// infrastructure again.
|
||||
// We to override just this object definition, as it may reference other objects
|
||||
// and we're happy to take the parent's definition for those.
|
||||
DefaultListableObjectFactory objectFactory = new DefaultListableObjectFactory(factory);
|
||||
|
||||
// Complete configuring the PrototypeTargetSource
|
||||
prototypeTargetSource.TargetObjectName = name;
|
||||
prototypeTargetSource.ObjectFactory = objectFactory;
|
||||
// Override the prototype object
|
||||
objectFactory.RegisterObjectDefinition(name, definition);
|
||||
|
||||
return prototypeTargetSource;
|
||||
}
|
||||
// Complete configuring the PrototypeTargetSource
|
||||
prototypeTargetSource.TargetObjectName = name;
|
||||
prototypeTargetSource.ObjectFactory = objectFactory;
|
||||
|
||||
return prototypeTargetSource;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates the prototype target source.
|
||||
/// </summary>
|
||||
/// <param name="objectType">The type of the object to create a target source for.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="factory">The factory.</param>
|
||||
/// <returns></returns>
|
||||
protected abstract AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name,
|
||||
IObjectFactory factory);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates the prototype target source.
|
||||
/// </summary>
|
||||
/// <param name="objectType">The type of the object to create a target source for.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="factory">The factory.</param>
|
||||
/// <returns></returns>
|
||||
protected abstract AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name,
|
||||
IObjectFactory factory);
|
||||
}
|
||||
|
||||
@@ -25,52 +25,52 @@ using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
namespace Spring.Aop.Framework.AutoProxy;
|
||||
|
||||
/// <summary>
|
||||
/// AutoProxyCreator, that identifies objects to proxy by matching their <see cref="Type.FullName"/> against a list of patterns.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class TypeNameAutoProxyCreator : AbstractFilteringAutoProxyCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// AutoProxyCreator, that identifies objects to proxy by matching their <see cref="Type.FullName"/> against a list of patterns.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class TypeNameAutoProxyCreator : AbstractFilteringAutoProxyCreator
|
||||
private TypeNameTypeFilter _typeNameFilter = null;
|
||||
|
||||
///<summary>
|
||||
/// The list of patterns to match <see cref="Type.FullName"/> against. For pattern syntax, see <see cref="TypeNameTypeFilter"/>
|
||||
///</summary>
|
||||
public string[] TypeNames
|
||||
{
|
||||
private TypeNameTypeFilter _typeNameFilter = null;
|
||||
|
||||
///<summary>
|
||||
/// The list of patterns to match <see cref="Type.FullName"/> against. For pattern syntax, see <see cref="TypeNameTypeFilter"/>
|
||||
///</summary>
|
||||
public string[] TypeNames
|
||||
get
|
||||
{
|
||||
get
|
||||
if (_typeNameFilter != null)
|
||||
{
|
||||
if (_typeNameFilter != null)
|
||||
{
|
||||
return _typeNameFilter.TypeNamePatterns;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(value, "TypeNames");
|
||||
_typeNameFilter = new TypeNameTypeFilter(value);
|
||||
return _typeNameFilter.TypeNamePatterns;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decide, whether the given object is eligible for proxying.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Override this method to allow or reject proxying for the given object.
|
||||
/// </remarks>
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.ShouldSkip"/>
|
||||
/// <returns>whether the given object shall be proxied.</returns>
|
||||
protected override bool IsEligibleForProxying(Type targetType, string targetName)
|
||||
set
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(_typeNameFilter, "TypeNames");
|
||||
|
||||
bool shallProxy = _typeNameFilter.Matches(targetType);
|
||||
return shallProxy;
|
||||
AssertUtils.ArgumentNotNull(value, "TypeNames");
|
||||
_typeNameFilter = new TypeNameTypeFilter(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decide, whether the given object is eligible for proxying.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Override this method to allow or reject proxying for the given object.
|
||||
/// </remarks>
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.ShouldSkip"/>
|
||||
/// <returns>whether the given object shall be proxied.</returns>
|
||||
protected override bool IsEligibleForProxying(Type targetType, string targetName)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(_typeNameFilter, "TypeNames");
|
||||
|
||||
bool shallProxy = _typeNameFilter.Matches(targetType);
|
||||
return shallProxy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,115 +22,113 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
|
||||
using Spring.Util;
|
||||
using Spring.Reflection.Dynamic;
|
||||
using AopAlliance.Intercept;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a target method using dynamic reflection.
|
||||
/// </summary>
|
||||
/// <seealso cref="Spring.Reflection.Dynamic.DynamicMethod"/>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
[Serializable]
|
||||
public class DynamicMethodInvocation : AbstractMethodInvocation
|
||||
{
|
||||
/// <summary>
|
||||
/// Invokes a target method using dynamic reflection.
|
||||
/// The method invocation that is to be invoked on the proxy.
|
||||
/// </summary>
|
||||
/// <seealso cref="Spring.Reflection.Dynamic.DynamicMethod"/>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
[Serializable]
|
||||
public class DynamicMethodInvocation : AbstractMethodInvocation
|
||||
private MethodInfo proxyMethod;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.DynamicMethodInvocation"/> class.
|
||||
/// </summary>
|
||||
/// <param name="proxy">The AOP proxy.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="method">The target method proxied.</param>
|
||||
/// <param name="proxyMethod">The method to invoke on proxy.</param>
|
||||
/// <param name="arguments">The target method's arguments.</param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.</param>
|
||||
/// <param name="interceptors">
|
||||
/// The list of interceptors that are to be applied. May be
|
||||
/// <cref lang="null"/>.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If any of the <paramref name="target"/> or <paramref name="method"/>
|
||||
/// parameters is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public DynamicMethodInvocation(
|
||||
object proxy, object target, MethodInfo method, MethodInfo proxyMethod,
|
||||
object[] arguments, Type targetType, IList interceptors)
|
||||
: base(proxy, target, method, arguments, targetType, interceptors)
|
||||
{
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked on the proxy.
|
||||
/// </summary>
|
||||
private MethodInfo proxyMethod;
|
||||
this.proxyMethod = proxyMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.DynamicMethodInvocation"/> class.
|
||||
/// </summary>
|
||||
/// <param name="proxy">The AOP proxy.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="method">The target method proxied.</param>
|
||||
/// <param name="proxyMethod">The method to invoke on proxy.</param>
|
||||
/// <param name="arguments">The target method's arguments.</param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.</param>
|
||||
/// <param name="interceptors">
|
||||
/// The list of interceptors that are to be applied. May be
|
||||
/// <cref lang="null"/>.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If any of the <paramref name="target"/> or <paramref name="method"/>
|
||||
/// parameters is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public DynamicMethodInvocation(
|
||||
object proxy, object target, MethodInfo method, MethodInfo proxyMethod,
|
||||
object[] arguments, Type targetType, IList interceptors)
|
||||
: base(proxy, target, method, arguments, targetType, interceptors)
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked on the proxy.
|
||||
/// </summary>
|
||||
protected MethodInfo ProxyMethod
|
||||
{
|
||||
get { return proxyMethod; }
|
||||
set { proxyMethod = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the joinpoint using dynamic reflection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses can override this to use custom invocation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The return value of the invocation of the joinpoint.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If invoking the joinpoint resulted in an exception.
|
||||
/// </exception>
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation.InvokeJoinpoint"/>
|
||||
protected override object InvokeJoinpoint()
|
||||
{
|
||||
MethodInfo targetMethodInfo = this.proxyMethod ?? Method;
|
||||
|
||||
IDynamicMethod targetMethod = new SafeMethod(targetMethodInfo);
|
||||
|
||||
try
|
||||
{
|
||||
this.proxyMethod = proxyMethod;
|
||||
AssertUtils.Understands(Target, "target", targetMethodInfo);
|
||||
return targetMethod.Invoke(Target, Arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked on the proxy.
|
||||
/// </summary>
|
||||
protected MethodInfo ProxyMethod
|
||||
// Only happens if fallback to standard reflection.
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
get { return proxyMethod; }
|
||||
set { proxyMethod = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the joinpoint using dynamic reflection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses can override this to use custom invocation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The return value of the invocation of the joinpoint.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If invoking the joinpoint resulted in an exception.
|
||||
/// </exception>
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation.InvokeJoinpoint"/>
|
||||
protected override object InvokeJoinpoint()
|
||||
{
|
||||
MethodInfo targetMethodInfo = this.proxyMethod ?? Method;
|
||||
|
||||
IDynamicMethod targetMethod = new SafeMethod(targetMethodInfo);
|
||||
|
||||
try
|
||||
{
|
||||
AssertUtils.Understands(Target, "target", targetMethodInfo);
|
||||
return targetMethod.Invoke(Target, Arguments);
|
||||
}
|
||||
// Only happens if fallback to standard reflection.
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
throw ReflectionUtils.UnwrapTargetInvocationException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Spring.Aop.Framework.DynamicMethodInvocation"/> instance
|
||||
/// from the specified <see cref="AopAlliance.Intercept.IMethodInvocation"/> and
|
||||
/// increments the interceptor index.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The current <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The new <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance to use.
|
||||
/// </returns>
|
||||
protected override IMethodInvocation PrepareMethodInvocationForProceed(IMethodInvocation invocation)
|
||||
{
|
||||
var rmi = new DynamicMethodInvocation(Proxy, Target, Method, ProxyMethod, Arguments, TargetType, Interceptors);
|
||||
rmi.CurrentInterceptorIndex = CurrentInterceptorIndex + 1;
|
||||
|
||||
return rmi;
|
||||
throw ReflectionUtils.UnwrapTargetInvocationException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Spring.Aop.Framework.DynamicMethodInvocation"/> instance
|
||||
/// from the specified <see cref="AopAlliance.Intercept.IMethodInvocation"/> and
|
||||
/// increments the interceptor index.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The current <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The new <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance to use.
|
||||
/// </returns>
|
||||
protected override IMethodInvocation PrepareMethodInvocationForProceed(IMethodInvocation invocation)
|
||||
{
|
||||
var rmi = new DynamicMethodInvocation(Proxy, Target, Method, ProxyMethod, Arguments, TargetType, Interceptors);
|
||||
rmi.CurrentInterceptorIndex = CurrentInterceptorIndex + 1;
|
||||
|
||||
return rmi;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +1,88 @@
|
||||
using Spring.Aop.Support;
|
||||
using Spring.Aop.Target;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// A reusable base implementation of <see cref="IAopProxyFactory"/>, providing
|
||||
/// some useful default implementations
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractAopProxyFactory : IAopProxyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// A reusable base implementation of <see cref="IAopProxyFactory"/>, providing
|
||||
/// some useful default implementations
|
||||
/// Creates an <see cref="Spring.Aop.Framework.IAopProxy"/> for the
|
||||
/// supplied <paramref name="advisedSupport"/> configuration.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractAopProxyFactory : IAopProxyFactory
|
||||
/// <param name="advisedSupport">The AOP configuration.</param>
|
||||
/// <returns>An <see cref="Spring.Aop.Framework.IAopProxy"/>.</returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the supplied <paramref name="advisedSupport"/> configuration is
|
||||
/// invalid.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory.CreateAopProxy"/>
|
||||
public IAopProxy CreateAopProxy(AdvisedSupport advisedSupport)
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="Spring.Aop.Framework.IAopProxy"/> for the
|
||||
/// supplied <paramref name="advisedSupport"/> configuration.
|
||||
/// </summary>
|
||||
/// <param name="advisedSupport">The AOP configuration.</param>
|
||||
/// <returns>An <see cref="Spring.Aop.Framework.IAopProxy"/>.</returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the supplied <paramref name="advisedSupport"/> configuration is
|
||||
/// invalid.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory.CreateAopProxy"/>
|
||||
public IAopProxy CreateAopProxy(AdvisedSupport advisedSupport)
|
||||
if (advisedSupport == null)
|
||||
{
|
||||
if (advisedSupport == null)
|
||||
{
|
||||
throw new AopConfigException("Cannot create IAopProxy with null ProxyConfig");
|
||||
}
|
||||
if (advisedSupport.Advisors.Count == 0 && advisedSupport.TargetSource == EmptyTargetSource.Empty)
|
||||
{
|
||||
throw new AopConfigException("Cannot create IAopProxy with no advisors and no target source");
|
||||
}
|
||||
|
||||
EliminateDuplicateAdvisors(advisedSupport);
|
||||
|
||||
return DoCreateAopProxyInstance(advisedSupport);
|
||||
throw new AopConfigException("Cannot create IAopProxy with null ProxyConfig");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actually creates the proxy instance based on the supplied <see cref="AdvisedSupport"/>.
|
||||
/// </summary>
|
||||
/// <returns>the proxy instance described by <paramref name="advisedSupport"/>. Must not be <c>null</c></returns>
|
||||
protected abstract IAopProxy DoCreateAopProxyInstance(AdvisedSupport advisedSupport);
|
||||
|
||||
/// <summary>
|
||||
/// If possible, checks for advisor duplicates on the supplied <paramref name="advisedSupport"/> and
|
||||
/// eliminates them.
|
||||
/// </summary>
|
||||
protected virtual void EliminateDuplicateAdvisors(AdvisedSupport advisedSupport)
|
||||
if (advisedSupport.Advisors.Count == 0 && advisedSupport.TargetSource == EmptyTargetSource.Empty)
|
||||
{
|
||||
if (advisedSupport.TargetSource is SingletonTargetSource
|
||||
&& IsAopProxyType(advisedSupport.TargetSource))
|
||||
throw new AopConfigException("Cannot create IAopProxy with no advisors and no target source");
|
||||
}
|
||||
|
||||
EliminateDuplicateAdvisors(advisedSupport);
|
||||
|
||||
return DoCreateAopProxyInstance(advisedSupport);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actually creates the proxy instance based on the supplied <see cref="AdvisedSupport"/>.
|
||||
/// </summary>
|
||||
/// <returns>the proxy instance described by <paramref name="advisedSupport"/>. Must not be <c>null</c></returns>
|
||||
protected abstract IAopProxy DoCreateAopProxyInstance(AdvisedSupport advisedSupport);
|
||||
|
||||
/// <summary>
|
||||
/// If possible, checks for advisor duplicates on the supplied <paramref name="advisedSupport"/> and
|
||||
/// eliminates them.
|
||||
/// </summary>
|
||||
protected virtual void EliminateDuplicateAdvisors(AdvisedSupport advisedSupport)
|
||||
{
|
||||
if (advisedSupport.TargetSource is SingletonTargetSource
|
||||
&& IsAopProxyType(advisedSupport.TargetSource))
|
||||
{
|
||||
IAdvised innerProxy = (IAdvised) advisedSupport.TargetSource.GetTarget();
|
||||
// eliminate duplicate advisors
|
||||
List<IAdvisor> thisAdvisors = new List<IAdvisor>(advisedSupport.Advisors);
|
||||
foreach (IAdvisor innerAdvisor in innerProxy.Advisors)
|
||||
{
|
||||
IAdvised innerProxy = (IAdvised)advisedSupport.TargetSource.GetTarget();
|
||||
// eliminate duplicate advisors
|
||||
List<IAdvisor> thisAdvisors = new List<IAdvisor>(advisedSupport.Advisors);
|
||||
foreach (IAdvisor innerAdvisor in innerProxy.Advisors)
|
||||
foreach (IAdvisor thisAdvisor in thisAdvisors)
|
||||
{
|
||||
foreach (IAdvisor thisAdvisor in thisAdvisors)
|
||||
if (ReferenceEquals(thisAdvisor, innerAdvisor)
|
||||
|| (thisAdvisor.GetType() == typeof(DefaultPointcutAdvisor)
|
||||
&& thisAdvisor.Equals(innerAdvisor)
|
||||
)
|
||||
)
|
||||
{
|
||||
if (ReferenceEquals(thisAdvisor, innerAdvisor)
|
||||
|| (thisAdvisor.GetType() == typeof(DefaultPointcutAdvisor)
|
||||
&& thisAdvisor.Equals(innerAdvisor)
|
||||
)
|
||||
)
|
||||
{
|
||||
advisedSupport.RemoveAdvisor(thisAdvisor);
|
||||
}
|
||||
advisedSupport.RemoveAdvisor(thisAdvisor);
|
||||
}
|
||||
}
|
||||
|
||||
// elimination of duplicate introductions is not necessary
|
||||
// since they do not propagate to nested proxy anyway
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if the given <paramref name="targetSource"/> holds a proxy generated by this factory.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual bool IsAopProxyType(ITargetSource targetSource)
|
||||
{
|
||||
return AopUtils.IsAopProxyType(targetSource.TargetType);
|
||||
// elimination of duplicate introductions is not necessary
|
||||
// since they do not propagate to nested proxy anyway
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if the given <paramref name="targetSource"/> holds a proxy generated by this factory.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual bool IsAopProxyType(ITargetSource targetSource)
|
||||
{
|
||||
return AopUtils.IsAopProxyType(targetSource.TargetType);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,73 +22,69 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
using Spring.Proxy;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for proxy builders that can be used
|
||||
/// to create an AOP proxy for any object.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public abstract class AbstractAopProxyTypeBuilder :
|
||||
AbstractProxyTypeBuilder, IAopProxyTypeGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for proxy builders that can be used
|
||||
/// to create an AOP proxy for any object.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public abstract class AbstractAopProxyTypeBuilder :
|
||||
AbstractProxyTypeBuilder, IAopProxyTypeGenerator
|
||||
#region IProxyTypeGenerator Members
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the target instance on which calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushTarget(ILGenerator il)
|
||||
{
|
||||
#region IProxyTypeGenerator Members
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the target instance on which calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushTarget(ILGenerator il)
|
||||
{
|
||||
PushAdvisedProxy(il);
|
||||
il.Emit(OpCodes.Ldfld, References.TargetSourceField);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetTargetMethod, null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAopProxyTypeGenerator Members
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public abstract void PushAdvisedProxy(ILGenerator il);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IList GetTypeAttributes(Type type)
|
||||
{
|
||||
IList attrs = base.GetTypeAttributes(type);
|
||||
int i = 0;
|
||||
while (i < attrs.Count)
|
||||
{
|
||||
if (IsAttributeMatchingType(attrs[i], typeof(SerializableAttribute)))
|
||||
{
|
||||
attrs.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return attrs;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
PushAdvisedProxy(il);
|
||||
il.Emit(OpCodes.Ldfld, References.TargetSourceField);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetTargetMethod, null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAopProxyTypeGenerator Members
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public abstract void PushAdvisedProxy(ILGenerator il);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IList GetTypeAttributes(Type type)
|
||||
{
|
||||
IList attrs = base.GetTypeAttributes(type);
|
||||
int i = 0;
|
||||
while (i < attrs.Count)
|
||||
{
|
||||
if (IsAttributeMatchingType(attrs[i], typeof(SerializableAttribute)))
|
||||
{
|
||||
attrs.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return attrs;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -24,368 +24,369 @@ using AopAlliance.Aop;
|
||||
using AopAlliance.Intercept;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the AOP configuration data built-in with the proxy.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
[Serializable]
|
||||
public class AdvisedProxy : IAdvised, ISerializable
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the AOP configuration data built-in with the proxy.
|
||||
/// Should we use dynamic reflection for method invocation ?
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
[Serializable]
|
||||
public class AdvisedProxy : IAdvised, ISerializable
|
||||
public static bool UseDynamicReflection;
|
||||
|
||||
/// <summary>
|
||||
/// Optimization fields
|
||||
/// </summary>
|
||||
private static IList<object> EmptyList = new ReadOnlyCollection<object>(new object[0]);
|
||||
|
||||
/// <summary>
|
||||
/// IAdvised delegate
|
||||
/// </summary>
|
||||
public IAdvised m_advised;
|
||||
|
||||
/// <summary>
|
||||
/// Array of introduction delegates
|
||||
/// </summary>
|
||||
public IAdvice[] m_introductions;
|
||||
|
||||
/// <summary>
|
||||
/// Target source
|
||||
/// </summary>
|
||||
public ITargetSource m_targetSource;
|
||||
|
||||
/// <summary>
|
||||
/// Type of target object.
|
||||
/// </summary>
|
||||
public Type m_targetType;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="AdvisedProxy"/> class.
|
||||
/// </summary>
|
||||
static AdvisedProxy()
|
||||
{
|
||||
/// <summary>
|
||||
/// Should we use dynamic reflection for method invocation ?
|
||||
/// </summary>
|
||||
public static bool UseDynamicReflection;
|
||||
string appSettingsKey = typeof(AdvisedProxy).FullName + ".UseDynamicReflection";
|
||||
NameValueCollection appSettings =
|
||||
ConfigurationUtils.GetSection("appSettings") as NameValueCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Optimization fields
|
||||
/// </summary>
|
||||
private static IList<object> EmptyList = new ReadOnlyCollection<object>(new object[0]);
|
||||
|
||||
/// <summary>
|
||||
/// IAdvised delegate
|
||||
/// </summary>
|
||||
public IAdvised m_advised;
|
||||
|
||||
/// <summary>
|
||||
/// Array of introduction delegates
|
||||
/// </summary>
|
||||
public IAdvice[] m_introductions;
|
||||
|
||||
/// <summary>
|
||||
/// Target source
|
||||
/// </summary>
|
||||
public ITargetSource m_targetSource;
|
||||
|
||||
/// <summary>
|
||||
/// Type of target object.
|
||||
/// </summary>
|
||||
public Type m_targetType;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="AdvisedProxy"/> class.
|
||||
/// </summary>
|
||||
static AdvisedProxy()
|
||||
if (appSettings != null && StringUtils.HasLength(appSettings[appSettingsKey]))
|
||||
{
|
||||
string appSettingsKey = typeof(AdvisedProxy).FullName + ".UseDynamicReflection";
|
||||
NameValueCollection appSettings =
|
||||
ConfigurationUtils.GetSection("appSettings") as NameValueCollection;
|
||||
|
||||
if (appSettings != null && StringUtils.HasLength(appSettings[appSettingsKey]))
|
||||
{
|
||||
UseDynamicReflection = bool.Parse(appSettings[appSettingsKey]);
|
||||
}
|
||||
else
|
||||
{
|
||||
UseDynamicReflection = true;
|
||||
}
|
||||
UseDynamicReflection = bool.Parse(appSettings[appSettingsKey]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="AdvisedProxy"/> class.
|
||||
/// </summary>
|
||||
public AdvisedProxy()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="AdvisedProxy"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
protected AdvisedProxy(IAdvised advised)
|
||||
else
|
||||
{
|
||||
m_advised = advised;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
/// <param name="proxy">The proxy.</param>
|
||||
public AdvisedProxy(IAdvised advised, IAopProxy proxy)
|
||||
{
|
||||
Initialize(advised, proxy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="info">Serialization data.</param>
|
||||
/// <param name="context">Serialization context.</param>
|
||||
protected AdvisedProxy(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
m_advised = (IAdvised)info.GetValue("advised", typeof(IAdvised));
|
||||
m_introductions = (IAdvice[])info.GetValue("introductions", typeof(IAdvice[]));
|
||||
m_targetSource = (ITargetSource)info.GetValue("targetSource", typeof(ITargetSource));
|
||||
|
||||
var type = info.GetString("targetType");
|
||||
m_targetType = type != null ? Type.GetType(type) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes this instance.
|
||||
/// </summary>
|
||||
/// <param name="info">Serialization data.</param>
|
||||
/// <param name="context">Serialization context.</param>
|
||||
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("advised", m_advised);
|
||||
info.AddValue("introductions", m_introductions);
|
||||
info.AddValue("targetSource", m_targetSource);
|
||||
info.AddValue("targetType", m_targetType?.AssemblyQualifiedName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialization method.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
/// <param name="proxy">
|
||||
/// The current <see cref="Spring.Aop.Framework.IAopProxy"/> implementation.
|
||||
/// </param>
|
||||
protected void Initialize(IAdvised advised, IAopProxy proxy)
|
||||
{
|
||||
this.m_advised = advised;
|
||||
this.m_targetSource = advised.TargetSource;
|
||||
this.m_targetType = advised.TargetSource.TargetType;
|
||||
|
||||
// initialize introduction advice
|
||||
this.m_introductions = new IAdvice[advised.Introductions.Count];
|
||||
for (int i = 0; i < advised.Introductions.Count; i++)
|
||||
{
|
||||
this.m_introductions[i] = advised.Introductions[i].Advice;
|
||||
|
||||
// set target proxy on introduction instance if it implements ITargetAware
|
||||
if (this.m_introductions[i] is ITargetAware)
|
||||
{
|
||||
((ITargetAware)this.m_introductions[i]).TargetProxy = proxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes intercepted methods using reflection
|
||||
/// </summary>
|
||||
/// <param name="proxy">proxy object</param>
|
||||
/// <param name="target">target object to invoke method on</param>
|
||||
/// <param name="targetType">target type</param>
|
||||
/// <param name="targetMethod">taget method to invoke</param>
|
||||
/// <param name="proxyMethod">The method to invoke on proxy.</param>
|
||||
/// <param name="args">method arguments</param>
|
||||
/// <param name="interceptors">interceptor chain</param>
|
||||
/// <returns>value returned by invocation chain</returns>
|
||||
public object Invoke(object proxy, object target, Type targetType,
|
||||
MethodInfo targetMethod, MethodInfo proxyMethod, object[] args, IList interceptors)
|
||||
{
|
||||
IMethodInvocation invocation = null;
|
||||
if (UseDynamicReflection)
|
||||
{
|
||||
invocation = new DynamicMethodInvocation(
|
||||
proxy, target, targetMethod, proxyMethod, args, targetType, interceptors);
|
||||
}
|
||||
else
|
||||
{
|
||||
invocation = new ReflectiveMethodInvocation(
|
||||
proxy, target, targetMethod, proxyMethod, args, targetType, interceptors);
|
||||
}
|
||||
return invocation.Proceed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of method interceptors
|
||||
/// </summary>
|
||||
/// <param name="targetType">target type</param>
|
||||
/// <param name="method">target method</param>
|
||||
/// <returns>list of inteceptors for the specified method</returns>
|
||||
public IList<object> GetInterceptors(Type targetType, MethodInfo method)
|
||||
{
|
||||
if (m_advised.Advisors.Count == 0)
|
||||
{
|
||||
return EmptyList;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_advised.AdvisorChainFactory.GetInterceptors(m_advised, this, method, targetType);
|
||||
}
|
||||
}
|
||||
|
||||
bool IAdvised.ExposeProxy
|
||||
{
|
||||
get { return m_advised.ExposeProxy; }
|
||||
}
|
||||
|
||||
IAdvisorChainFactory IAdvised.AdvisorChainFactory
|
||||
{
|
||||
get { return m_advised.AdvisorChainFactory; }
|
||||
}
|
||||
|
||||
bool IAdvised.ProxyTargetType
|
||||
{
|
||||
get { return m_advised.ProxyTargetType; }
|
||||
}
|
||||
|
||||
bool IAdvised.ProxyTargetAttributes
|
||||
{
|
||||
get { return m_advised.ProxyTargetAttributes; }
|
||||
}
|
||||
|
||||
IList<IAdvisor> IAdvised.Advisors
|
||||
{
|
||||
get { return m_advised.Advisors; }
|
||||
}
|
||||
|
||||
IList<IIntroductionAdvisor> IAdvised.Introductions
|
||||
{
|
||||
get { return m_advised.Introductions; }
|
||||
}
|
||||
|
||||
IList<Type> IAdvised.Interfaces
|
||||
{
|
||||
get { return m_advised.Interfaces; }
|
||||
}
|
||||
|
||||
IDictionary<Type, object> IAdvised.InterfaceMap
|
||||
{
|
||||
get { return m_advised.InterfaceMap; }
|
||||
}
|
||||
|
||||
bool IAdvised.IsFrozen
|
||||
{
|
||||
get { return m_advised.IsFrozen; }
|
||||
}
|
||||
|
||||
ITargetSource IAdvised.TargetSource
|
||||
{
|
||||
get { return m_advised.TargetSource; }
|
||||
}
|
||||
|
||||
bool IAdvised.IsSerializable
|
||||
{
|
||||
get { return m_advised.IsSerializable; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advice"/> to the end (or tail)
|
||||
/// of the advice (interceptor) chain.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to be added.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAdvised.AddAdvice(int,IAdvice)"/>
|
||||
public void AddAdvice(IAdvice advice)
|
||||
{
|
||||
this.m_advised.AddAdvice(advice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advice"/> to the supplied
|
||||
/// <paramref name="position"/> in the advice (interceptor) chain.
|
||||
/// </summary>
|
||||
/// <param name="position">
|
||||
/// The zero (0) indexed position (from the head) at which the
|
||||
/// supplied <paramref name="advice"/> is to be inserted into the
|
||||
/// advice (interceptor) chain.
|
||||
/// </param>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to be added.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAdvised.AddAdvice(IAdvice)"/>
|
||||
public void AddAdvice(int position, IAdvice advice)
|
||||
{
|
||||
this.m_advised.AddAdvice(position, advice);
|
||||
}
|
||||
|
||||
bool IAdvised.IsInterfaceProxied(Type intf)
|
||||
{
|
||||
return m_advised.IsInterfaceProxied(intf);
|
||||
}
|
||||
|
||||
void IAdvised.AddAdvisors(IAdvisors advisors)
|
||||
{
|
||||
m_advised.AddAdvisors(advisors);
|
||||
}
|
||||
|
||||
void IAdvised.AddAdvisor(IAdvisor advisor)
|
||||
{
|
||||
m_advised.AddAdvisor(advisor);
|
||||
}
|
||||
|
||||
void IAdvised.AddAdvisor(int pos, IAdvisor advisor)
|
||||
{
|
||||
m_advised.AddAdvisor(pos, advisor);
|
||||
}
|
||||
|
||||
void IAdvised.AddIntroduction(IIntroductionAdvisor advisor)
|
||||
{
|
||||
m_advised.AddIntroduction(advisor);
|
||||
}
|
||||
|
||||
void IAdvised.AddIntroduction(int pos, IIntroductionAdvisor advisor)
|
||||
{
|
||||
m_advised.AddIntroduction(pos, advisor);
|
||||
}
|
||||
|
||||
int IAdvised.IndexOf(IAdvisor advisor)
|
||||
{
|
||||
return m_advised.IndexOf(advisor);
|
||||
}
|
||||
|
||||
int IAdvised.IndexOf(IIntroductionAdvisor advisor)
|
||||
{
|
||||
return m_advised.IndexOf(advisor);
|
||||
}
|
||||
|
||||
bool IAdvised.RemoveAdvisor(IAdvisor advisor)
|
||||
{
|
||||
return m_advised.RemoveAdvisor(advisor);
|
||||
}
|
||||
|
||||
void IAdvised.RemoveAdvisor(int index)
|
||||
{
|
||||
m_advised.RemoveAdvisor(index);
|
||||
}
|
||||
|
||||
bool IAdvised.RemoveAdvice(IAdvice advice)
|
||||
{
|
||||
return m_advised.RemoveAdvice(advice);
|
||||
}
|
||||
|
||||
bool IAdvised.RemoveIntroduction(IIntroductionAdvisor advisor)
|
||||
{
|
||||
return m_advised.RemoveIntroduction(advisor);
|
||||
}
|
||||
|
||||
void IAdvised.RemoveIntroduction(int index)
|
||||
{
|
||||
m_advised.RemoveIntroduction(index);
|
||||
}
|
||||
|
||||
void IAdvised.ReplaceIntroduction(int index, IIntroductionAdvisor advisor)
|
||||
{
|
||||
m_advised.ReplaceIntroduction(index, advisor);
|
||||
}
|
||||
|
||||
bool IAdvised.ReplaceAdvisor(IAdvisor a, IAdvisor b)
|
||||
{
|
||||
return m_advised.ReplaceAdvisor(a, b);
|
||||
}
|
||||
|
||||
string IAdvised.ToProxyConfigString()
|
||||
{
|
||||
return m_advised.ToProxyConfigString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target type behind the implementing object.
|
||||
/// Ttypically a proxy configuration or an actual proxy.
|
||||
/// </summary>
|
||||
/// <value>The type of the target or null if not known.</value>
|
||||
public Type TargetType
|
||||
{
|
||||
get { return m_targetType; }
|
||||
UseDynamicReflection = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="AdvisedProxy"/> class.
|
||||
/// </summary>
|
||||
public AdvisedProxy()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="AdvisedProxy"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
protected AdvisedProxy(IAdvised advised)
|
||||
{
|
||||
m_advised = advised;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
/// <param name="proxy">The proxy.</param>
|
||||
public AdvisedProxy(IAdvised advised, IAopProxy proxy)
|
||||
{
|
||||
Initialize(advised, proxy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="info">Serialization data.</param>
|
||||
/// <param name="context">Serialization context.</param>
|
||||
protected AdvisedProxy(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
m_advised = (IAdvised) info.GetValue("advised", typeof(IAdvised));
|
||||
m_introductions = (IAdvice[]) info.GetValue("introductions", typeof(IAdvice[]));
|
||||
m_targetSource = (ITargetSource) info.GetValue("targetSource", typeof(ITargetSource));
|
||||
|
||||
var type = info.GetString("targetType");
|
||||
m_targetType = type != null ? Type.GetType(type) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes this instance.
|
||||
/// </summary>
|
||||
/// <param name="info">Serialization data.</param>
|
||||
/// <param name="context">Serialization context.</param>
|
||||
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("advised", m_advised);
|
||||
info.AddValue("introductions", m_introductions);
|
||||
info.AddValue("targetSource", m_targetSource);
|
||||
info.AddValue("targetType", m_targetType?.AssemblyQualifiedName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialization method.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
/// <param name="proxy">
|
||||
/// The current <see cref="Spring.Aop.Framework.IAopProxy"/> implementation.
|
||||
/// </param>
|
||||
protected void Initialize(IAdvised advised, IAopProxy proxy)
|
||||
{
|
||||
this.m_advised = advised;
|
||||
this.m_targetSource = advised.TargetSource;
|
||||
this.m_targetType = advised.TargetSource.TargetType;
|
||||
|
||||
// initialize introduction advice
|
||||
this.m_introductions = new IAdvice[advised.Introductions.Count];
|
||||
for (int i = 0; i < advised.Introductions.Count; i++)
|
||||
{
|
||||
this.m_introductions[i] = advised.Introductions[i].Advice;
|
||||
|
||||
// set target proxy on introduction instance if it implements ITargetAware
|
||||
if (this.m_introductions[i] is ITargetAware)
|
||||
{
|
||||
((ITargetAware) this.m_introductions[i]).TargetProxy = proxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes intercepted methods using reflection
|
||||
/// </summary>
|
||||
/// <param name="proxy">proxy object</param>
|
||||
/// <param name="target">target object to invoke method on</param>
|
||||
/// <param name="targetType">target type</param>
|
||||
/// <param name="targetMethod">taget method to invoke</param>
|
||||
/// <param name="proxyMethod">The method to invoke on proxy.</param>
|
||||
/// <param name="args">method arguments</param>
|
||||
/// <param name="interceptors">interceptor chain</param>
|
||||
/// <returns>value returned by invocation chain</returns>
|
||||
public object Invoke(object proxy, object target, Type targetType,
|
||||
MethodInfo targetMethod, MethodInfo proxyMethod, object[] args, IList interceptors)
|
||||
{
|
||||
IMethodInvocation invocation = null;
|
||||
if (UseDynamicReflection)
|
||||
{
|
||||
invocation = new DynamicMethodInvocation(
|
||||
proxy, target, targetMethod, proxyMethod, args, targetType, interceptors);
|
||||
}
|
||||
else
|
||||
{
|
||||
invocation = new ReflectiveMethodInvocation(
|
||||
proxy, target, targetMethod, proxyMethod, args, targetType, interceptors);
|
||||
}
|
||||
|
||||
return invocation.Proceed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of method interceptors
|
||||
/// </summary>
|
||||
/// <param name="targetType">target type</param>
|
||||
/// <param name="method">target method</param>
|
||||
/// <returns>list of inteceptors for the specified method</returns>
|
||||
public IList<object> GetInterceptors(Type targetType, MethodInfo method)
|
||||
{
|
||||
if (m_advised.Advisors.Count == 0)
|
||||
{
|
||||
return EmptyList;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_advised.AdvisorChainFactory.GetInterceptors(m_advised, this, method, targetType);
|
||||
}
|
||||
}
|
||||
|
||||
bool IAdvised.ExposeProxy
|
||||
{
|
||||
get { return m_advised.ExposeProxy; }
|
||||
}
|
||||
|
||||
IAdvisorChainFactory IAdvised.AdvisorChainFactory
|
||||
{
|
||||
get { return m_advised.AdvisorChainFactory; }
|
||||
}
|
||||
|
||||
bool IAdvised.ProxyTargetType
|
||||
{
|
||||
get { return m_advised.ProxyTargetType; }
|
||||
}
|
||||
|
||||
bool IAdvised.ProxyTargetAttributes
|
||||
{
|
||||
get { return m_advised.ProxyTargetAttributes; }
|
||||
}
|
||||
|
||||
IList<IAdvisor> IAdvised.Advisors
|
||||
{
|
||||
get { return m_advised.Advisors; }
|
||||
}
|
||||
|
||||
IList<IIntroductionAdvisor> IAdvised.Introductions
|
||||
{
|
||||
get { return m_advised.Introductions; }
|
||||
}
|
||||
|
||||
IList<Type> IAdvised.Interfaces
|
||||
{
|
||||
get { return m_advised.Interfaces; }
|
||||
}
|
||||
|
||||
IDictionary<Type, object> IAdvised.InterfaceMap
|
||||
{
|
||||
get { return m_advised.InterfaceMap; }
|
||||
}
|
||||
|
||||
bool IAdvised.IsFrozen
|
||||
{
|
||||
get { return m_advised.IsFrozen; }
|
||||
}
|
||||
|
||||
ITargetSource IAdvised.TargetSource
|
||||
{
|
||||
get { return m_advised.TargetSource; }
|
||||
}
|
||||
|
||||
bool IAdvised.IsSerializable
|
||||
{
|
||||
get { return m_advised.IsSerializable; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advice"/> to the end (or tail)
|
||||
/// of the advice (interceptor) chain.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to be added.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAdvised.AddAdvice(int,IAdvice)"/>
|
||||
public void AddAdvice(IAdvice advice)
|
||||
{
|
||||
this.m_advised.AddAdvice(advice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advice"/> to the supplied
|
||||
/// <paramref name="position"/> in the advice (interceptor) chain.
|
||||
/// </summary>
|
||||
/// <param name="position">
|
||||
/// The zero (0) indexed position (from the head) at which the
|
||||
/// supplied <paramref name="advice"/> is to be inserted into the
|
||||
/// advice (interceptor) chain.
|
||||
/// </param>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to be added.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAdvised.AddAdvice(IAdvice)"/>
|
||||
public void AddAdvice(int position, IAdvice advice)
|
||||
{
|
||||
this.m_advised.AddAdvice(position, advice);
|
||||
}
|
||||
|
||||
bool IAdvised.IsInterfaceProxied(Type intf)
|
||||
{
|
||||
return m_advised.IsInterfaceProxied(intf);
|
||||
}
|
||||
|
||||
void IAdvised.AddAdvisors(IAdvisors advisors)
|
||||
{
|
||||
m_advised.AddAdvisors(advisors);
|
||||
}
|
||||
|
||||
void IAdvised.AddAdvisor(IAdvisor advisor)
|
||||
{
|
||||
m_advised.AddAdvisor(advisor);
|
||||
}
|
||||
|
||||
void IAdvised.AddAdvisor(int pos, IAdvisor advisor)
|
||||
{
|
||||
m_advised.AddAdvisor(pos, advisor);
|
||||
}
|
||||
|
||||
void IAdvised.AddIntroduction(IIntroductionAdvisor advisor)
|
||||
{
|
||||
m_advised.AddIntroduction(advisor);
|
||||
}
|
||||
|
||||
void IAdvised.AddIntroduction(int pos, IIntroductionAdvisor advisor)
|
||||
{
|
||||
m_advised.AddIntroduction(pos, advisor);
|
||||
}
|
||||
|
||||
int IAdvised.IndexOf(IAdvisor advisor)
|
||||
{
|
||||
return m_advised.IndexOf(advisor);
|
||||
}
|
||||
|
||||
int IAdvised.IndexOf(IIntroductionAdvisor advisor)
|
||||
{
|
||||
return m_advised.IndexOf(advisor);
|
||||
}
|
||||
|
||||
bool IAdvised.RemoveAdvisor(IAdvisor advisor)
|
||||
{
|
||||
return m_advised.RemoveAdvisor(advisor);
|
||||
}
|
||||
|
||||
void IAdvised.RemoveAdvisor(int index)
|
||||
{
|
||||
m_advised.RemoveAdvisor(index);
|
||||
}
|
||||
|
||||
bool IAdvised.RemoveAdvice(IAdvice advice)
|
||||
{
|
||||
return m_advised.RemoveAdvice(advice);
|
||||
}
|
||||
|
||||
bool IAdvised.RemoveIntroduction(IIntroductionAdvisor advisor)
|
||||
{
|
||||
return m_advised.RemoveIntroduction(advisor);
|
||||
}
|
||||
|
||||
void IAdvised.RemoveIntroduction(int index)
|
||||
{
|
||||
m_advised.RemoveIntroduction(index);
|
||||
}
|
||||
|
||||
void IAdvised.ReplaceIntroduction(int index, IIntroductionAdvisor advisor)
|
||||
{
|
||||
m_advised.ReplaceIntroduction(index, advisor);
|
||||
}
|
||||
|
||||
bool IAdvised.ReplaceAdvisor(IAdvisor a, IAdvisor b)
|
||||
{
|
||||
return m_advised.ReplaceAdvisor(a, b);
|
||||
}
|
||||
|
||||
string IAdvised.ToProxyConfigString()
|
||||
{
|
||||
return m_advised.ToProxyConfigString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target type behind the implementing object.
|
||||
/// Ttypically a proxy configuration or an actual proxy.
|
||||
/// </summary>
|
||||
/// <value>The type of the target or null if not known.</value>
|
||||
public Type TargetType
|
||||
{
|
||||
get { return m_targetType; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,94 +20,93 @@
|
||||
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Proxy.IProxyMethodBuilder"/> implementation
|
||||
/// that delegates method calls to the base method.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class BaseAopProxyMethodBuilder : AbstractAopProxyMethodBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Proxy.IProxyMethodBuilder"/> implementation
|
||||
/// that delegates method calls to the base method.
|
||||
/// Creates a new instance of the method builder.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class BaseAopProxyMethodBuilder : AbstractAopProxyMethodBuilder
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
/// <param name="aopProxyGenerator">
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </param>
|
||||
/// <param name="targetMethods">
|
||||
/// The dictionary to cache the list of target
|
||||
/// <see cref="System.Reflection.MethodInfo"/>s.
|
||||
/// </param>
|
||||
/// <param name="onProxyTargetMethods">
|
||||
/// The dictionary to cache the list of target
|
||||
/// <see cref="System.Reflection.MethodInfo"/>s defined on the proxy.
|
||||
/// </param>
|
||||
public BaseAopProxyMethodBuilder(
|
||||
TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator,
|
||||
IDictionary<string, MethodInfo> targetMethods, IDictionary<string, MethodInfo> onProxyTargetMethods)
|
||||
: base(typeBuilder, aopProxyGenerator, false, targetMethods, onProxyTargetMethods)
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the method builder.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
/// <param name="aopProxyGenerator">
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </param>
|
||||
/// <param name="targetMethods">
|
||||
/// The dictionary to cache the list of target
|
||||
/// <see cref="System.Reflection.MethodInfo"/>s.
|
||||
/// </param>
|
||||
/// <param name="onProxyTargetMethods">
|
||||
/// The dictionary to cache the list of target
|
||||
/// <see cref="System.Reflection.MethodInfo"/>s defined on the proxy.
|
||||
/// </param>
|
||||
public BaseAopProxyMethodBuilder(
|
||||
TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator,
|
||||
IDictionary<string, MethodInfo> targetMethods, IDictionary<string, MethodInfo> onProxyTargetMethods)
|
||||
: base(typeBuilder, aopProxyGenerator, false, targetMethods, onProxyTargetMethods)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create static field that will cache target method when defined on the proxy.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The target method.</param>
|
||||
protected override void GenerateOnProxyTargetMethodCacheField(
|
||||
ILGenerator il, MethodInfo method)
|
||||
/// <summary>
|
||||
/// Create static field that will cache target method when defined on the proxy.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The target method.</param>
|
||||
protected override void GenerateOnProxyTargetMethodCacheField(
|
||||
ILGenerator il, MethodInfo method)
|
||||
{
|
||||
if (method.IsVirtual && !method.IsFinal)
|
||||
{
|
||||
if (method.IsVirtual && !method.IsFinal)
|
||||
string methodId = GenerateMethodCacheFieldId(method);
|
||||
|
||||
// generate proxy method
|
||||
MethodBuilder baseMethod = typeBuilder.DefineMethod("proxy_" + methodId,
|
||||
MethodAttributes.Public | MethodAttributes.HideBySig,
|
||||
CallingConventions.Standard,
|
||||
method.ReturnType, ReflectionUtils.GetParameterTypes(method));
|
||||
|
||||
DefineGenericParameters(baseMethod, method);
|
||||
//DefineParameters(baseMethod, method);
|
||||
|
||||
ILGenerator localIL = baseMethod.GetILGenerator();
|
||||
|
||||
localIL.Emit(OpCodes.Ldarg_0);
|
||||
// setup parameters for call
|
||||
for (int i = 0; i < method.GetParameters().Length; i++)
|
||||
{
|
||||
string methodId = GenerateMethodCacheFieldId(method);
|
||||
|
||||
// generate proxy method
|
||||
MethodBuilder baseMethod = typeBuilder.DefineMethod("proxy_" + methodId,
|
||||
MethodAttributes.Public | MethodAttributes.HideBySig,
|
||||
CallingConventions.Standard,
|
||||
method.ReturnType, ReflectionUtils.GetParameterTypes(method));
|
||||
|
||||
DefineGenericParameters(baseMethod, method);
|
||||
//DefineParameters(baseMethod, method);
|
||||
|
||||
ILGenerator localIL = baseMethod.GetILGenerator();
|
||||
|
||||
localIL.Emit(OpCodes.Ldarg_0);
|
||||
// setup parameters for call
|
||||
for (int i = 0; i < method.GetParameters().Length; i++)
|
||||
{
|
||||
localIL.Emit(OpCodes.Ldarg_S, i + 1);
|
||||
}
|
||||
localIL.EmitCall(OpCodes.Call, method, null);
|
||||
localIL.Emit(OpCodes.Ret);
|
||||
|
||||
// create static field that will cache proxy method
|
||||
onProxyTargetMethods.Add(methodId, method);
|
||||
|
||||
onProxyTargetMethodCacheField = typeBuilder.DefineField(
|
||||
methodId, typeof(MethodInfo), FieldAttributes.Private | FieldAttributes.Static);
|
||||
|
||||
MakeGenericMethod(il, method, onProxyTargetMethodCacheField, genericOnProxyTargetMethod);
|
||||
localIL.Emit(OpCodes.Ldarg_S, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls target method directly.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
protected override void CallDirectProxiedMethod(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
CallDirectBaseMethod(il, method);
|
||||
localIL.EmitCall(OpCodes.Call, method, null);
|
||||
localIL.Emit(OpCodes.Ret);
|
||||
|
||||
// create static field that will cache proxy method
|
||||
onProxyTargetMethods.Add(methodId, method);
|
||||
|
||||
onProxyTargetMethodCacheField = typeBuilder.DefineField(
|
||||
methodId, typeof(MethodInfo), FieldAttributes.Private | FieldAttributes.Static);
|
||||
|
||||
MakeGenericMethod(il, method, onProxyTargetMethodCacheField, genericOnProxyTargetMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls target method directly.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
protected override void CallDirectProxiedMethod(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
CallDirectBaseMethod(il, method);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,142 +24,147 @@ using System.Runtime.Serialization;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Base class that each dynamic composition proxy has to extend.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
[Serializable]
|
||||
public abstract class BaseCompositionAopProxy : AdvisedProxy, IAopProxy, ISerializable
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class that each dynamic composition proxy has to extend.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
[Serializable]
|
||||
public abstract class BaseCompositionAopProxy : AdvisedProxy, IAopProxy, ISerializable
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
public BaseCompositionAopProxy()
|
||||
{
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
public BaseCompositionAopProxy()
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.DynamicProxy.BaseCompositionAopProxy"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
public BaseCompositionAopProxy(IAdvised advised) : base(advised)
|
||||
{
|
||||
base.Initialize(advised, this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="info">Serialization data.</param>
|
||||
/// <param name="context">Serialization context.</param>
|
||||
protected BaseCompositionAopProxy(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{}
|
||||
|
||||
///<summary>
|
||||
///Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> with the data needed to serialize the target object.
|
||||
///</summary>
|
||||
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAopProxy Members
|
||||
|
||||
/// <summary>
|
||||
/// Returns this proxy instance
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
object IAopProxy.GetProxy()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Equal, HashCode and ToString overrides
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to target object handling of equals method.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare with the current target object</param>
|
||||
/// <returns>true if the specified Object is equal to the current target object; otherwise, false</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
bool equals = false;
|
||||
object target = m_targetSource.GetTarget();
|
||||
AdvisedProxy otherProxy = obj as AdvisedProxy;
|
||||
object otherTarget = null;
|
||||
if (otherProxy != null)
|
||||
{
|
||||
otherTarget = otherProxy.m_targetSource.GetTarget();
|
||||
if (target == null)
|
||||
{
|
||||
equals = (otherTarget == null);
|
||||
}
|
||||
else
|
||||
{
|
||||
equals = target.Equals(otherTarget);
|
||||
}
|
||||
}
|
||||
else if (target == null)
|
||||
{
|
||||
equals = (obj == null);
|
||||
}
|
||||
else
|
||||
{
|
||||
equals = target.Equals(obj);
|
||||
}
|
||||
m_targetSource.ReleaseTarget(target);
|
||||
if (otherProxy != null)
|
||||
{
|
||||
otherProxy.m_targetSource.ReleaseTarget(otherTarget);
|
||||
}
|
||||
return equals;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delgate to the target object generation of the hash code.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for the target object.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = 0;
|
||||
object target = m_targetSource.GetTarget();
|
||||
if (target != null)
|
||||
{
|
||||
hashCode = target.GetHashCode();
|
||||
}
|
||||
m_targetSource.ReleaseTarget(target);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a String the represents the target object.
|
||||
/// </summary>
|
||||
/// <returns>A String that represents the target object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string str;
|
||||
object target = m_targetSource.GetTarget();
|
||||
if (target != null)
|
||||
{
|
||||
str = target.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
str = base.ToString();
|
||||
}
|
||||
m_targetSource.ReleaseTarget(target);
|
||||
return str;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.DynamicProxy.BaseCompositionAopProxy"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
public BaseCompositionAopProxy(IAdvised advised) : base(advised)
|
||||
{
|
||||
base.Initialize(advised, this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="info">Serialization data.</param>
|
||||
/// <param name="context">Serialization context.</param>
|
||||
protected BaseCompositionAopProxy(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> with the data needed to serialize the target object.
|
||||
///</summary>
|
||||
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAopProxy Members
|
||||
|
||||
/// <summary>
|
||||
/// Returns this proxy instance
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
object IAopProxy.GetProxy()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Equal, HashCode and ToString overrides
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to target object handling of equals method.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare with the current target object</param>
|
||||
/// <returns>true if the specified Object is equal to the current target object; otherwise, false</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
bool equals = false;
|
||||
object target = m_targetSource.GetTarget();
|
||||
AdvisedProxy otherProxy = obj as AdvisedProxy;
|
||||
object otherTarget = null;
|
||||
if (otherProxy != null)
|
||||
{
|
||||
otherTarget = otherProxy.m_targetSource.GetTarget();
|
||||
if (target == null)
|
||||
{
|
||||
equals = (otherTarget == null);
|
||||
}
|
||||
else
|
||||
{
|
||||
equals = target.Equals(otherTarget);
|
||||
}
|
||||
}
|
||||
else if (target == null)
|
||||
{
|
||||
equals = (obj == null);
|
||||
}
|
||||
else
|
||||
{
|
||||
equals = target.Equals(obj);
|
||||
}
|
||||
|
||||
m_targetSource.ReleaseTarget(target);
|
||||
if (otherProxy != null)
|
||||
{
|
||||
otherProxy.m_targetSource.ReleaseTarget(otherTarget);
|
||||
}
|
||||
|
||||
return equals;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delgate to the target object generation of the hash code.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for the target object.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = 0;
|
||||
object target = m_targetSource.GetTarget();
|
||||
if (target != null)
|
||||
{
|
||||
hashCode = target.GetHashCode();
|
||||
}
|
||||
|
||||
m_targetSource.ReleaseTarget(target);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a String the represents the target object.
|
||||
/// </summary>
|
||||
/// <returns>A String that represents the target object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string str;
|
||||
object target = m_targetSource.GetTarget();
|
||||
if (target != null)
|
||||
{
|
||||
str = target.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
str = base.ToString();
|
||||
}
|
||||
|
||||
m_targetSource.ReleaseTarget(target);
|
||||
return str;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -27,184 +27,193 @@ using Spring.Proxy;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of the <see cref="Spring.Aop.Framework.IAopProxyFactory"/>
|
||||
/// interface that caches the AOP proxy <see cref="System.Type"/> instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Caches against a key based on :
|
||||
/// - the base type
|
||||
/// - the target type
|
||||
/// - the interfaces to proxy
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Bruno Baia</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <seealso cref="Spring.Aop.Framework.DynamicProxy.DefaultAopProxyFactory"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory"/>
|
||||
[Serializable]
|
||||
public class CachedAopProxyFactory : DefaultAopProxyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of the <see cref="Spring.Aop.Framework.IAopProxyFactory"/>
|
||||
/// interface that caches the AOP proxy <see cref="System.Type"/> instance.
|
||||
/// The shared <see cref="ILogger"/> instance for this class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Caches against a key based on :
|
||||
/// - the base type
|
||||
/// - the target type
|
||||
/// - the interfaces to proxy
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Bruno Baia</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <seealso cref="Spring.Aop.Framework.DynamicProxy.DefaultAopProxyFactory"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory"/>
|
||||
[Serializable]
|
||||
public class CachedAopProxyFactory : DefaultAopProxyFactory
|
||||
private static readonly ILogger<CachedAopProxyFactory> logger = LogManager.GetLogger<CachedAopProxyFactory>();
|
||||
|
||||
private static readonly Hashtable typeCache = new Hashtable();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of proxy types in the cache
|
||||
/// </summary>
|
||||
public static int CountCachedTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// The shared <see cref="ILogger"/> instance for this class.
|
||||
/// </summary>
|
||||
private static readonly ILogger<CachedAopProxyFactory> logger = LogManager.GetLogger<CachedAopProxyFactory>();
|
||||
get { return typeCache.Count; }
|
||||
}
|
||||
|
||||
private static readonly Hashtable typeCache = new Hashtable();
|
||||
/// <summary>
|
||||
/// Clears the type cache
|
||||
/// </summary>
|
||||
public static void ClearCache()
|
||||
{
|
||||
typeCache.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of proxy types in the cache
|
||||
/// </summary>
|
||||
public static int CountCachedTypes
|
||||
/// <summary>
|
||||
/// Creates a new instance
|
||||
/// </summary>
|
||||
public CachedAopProxyFactory()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the proxy type and caches the <see cref="System.Type"/>
|
||||
/// instance against the base type and the interfaces to proxy.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">
|
||||
/// The <see cref="Spring.Proxy.IProxyTypeBuilder"/> to use
|
||||
/// </param>
|
||||
/// <returns>The generated or cached proxy class.</returns>
|
||||
protected override Type BuildProxyType(IProxyTypeBuilder typeBuilder)
|
||||
{
|
||||
ProxyTypeCacheKey cacheKey = new ProxyTypeCacheKey(
|
||||
typeBuilder.BaseType, typeBuilder.TargetType, typeBuilder.Interfaces, typeBuilder.ProxyTargetAttributes);
|
||||
Type proxyType = null;
|
||||
lock (typeCache)
|
||||
{
|
||||
get { return typeCache.Count; }
|
||||
proxyType = typeCache[cacheKey] as Type;
|
||||
if (proxyType == null)
|
||||
{
|
||||
proxyType = typeBuilder.BuildProxyType();
|
||||
typeCache[cacheKey] = proxyType;
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.LogDebug("AOP proxy type found in cache for {CacheKey}", cacheKey);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the type cache
|
||||
/// </summary>
|
||||
public static void ClearCache()
|
||||
return proxyType;
|
||||
}
|
||||
|
||||
#region ProxyTypeCacheKey inner class implementation
|
||||
|
||||
/// <summary>
|
||||
/// Uniquely identifies a proxytype in the cache
|
||||
/// </summary>
|
||||
private sealed class ProxyTypeCacheKey
|
||||
{
|
||||
private sealed class HashCodeComparer : IComparer<Type>
|
||||
{
|
||||
typeCache.Clear();
|
||||
public int Compare(Type x, Type y)
|
||||
{
|
||||
return x.GetHashCode().CompareTo(y.GetHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance
|
||||
/// </summary>
|
||||
public CachedAopProxyFactory()
|
||||
{}
|
||||
private static HashCodeComparer interfaceComparer = new HashCodeComparer();
|
||||
|
||||
/// <summary>
|
||||
/// Generates the proxy type and caches the <see cref="System.Type"/>
|
||||
/// instance against the base type and the interfaces to proxy.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">
|
||||
/// The <see cref="Spring.Proxy.IProxyTypeBuilder"/> to use
|
||||
/// </param>
|
||||
/// <returns>The generated or cached proxy class.</returns>
|
||||
protected override Type BuildProxyType(IProxyTypeBuilder typeBuilder)
|
||||
private Type baseType;
|
||||
private Type targetType;
|
||||
private List<Type> interfaceTypes;
|
||||
private bool proxyTargetAttributes;
|
||||
|
||||
public ProxyTypeCacheKey(Type baseType, Type targetType, IList<Type> interfaceTypes, bool proxyTargetAttributes)
|
||||
{
|
||||
ProxyTypeCacheKey cacheKey = new ProxyTypeCacheKey(
|
||||
typeBuilder.BaseType, typeBuilder.TargetType, typeBuilder.Interfaces, typeBuilder.ProxyTargetAttributes);
|
||||
Type proxyType = null;
|
||||
lock (typeCache)
|
||||
{
|
||||
proxyType = typeCache[cacheKey] as Type;
|
||||
if (proxyType == null)
|
||||
{
|
||||
proxyType = typeBuilder.BuildProxyType();
|
||||
typeCache[cacheKey] = proxyType;
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.LogDebug("AOP proxy type found in cache for {CacheKey}", cacheKey);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
return proxyType;
|
||||
this.baseType = baseType;
|
||||
this.targetType = targetType;
|
||||
this.interfaceTypes = new List<Type>(interfaceTypes);
|
||||
this.interfaceTypes.Sort(interfaceComparer); // sort by GetHashcode()? to have a defined order
|
||||
this.proxyTargetAttributes = proxyTargetAttributes;
|
||||
}
|
||||
|
||||
#region ProxyTypeCacheKey inner class implementation
|
||||
|
||||
/// <summary>
|
||||
/// Uniquely identifies a proxytype in the cache
|
||||
/// </summary>
|
||||
private sealed class ProxyTypeCacheKey
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
private sealed class HashCodeComparer : IComparer<Type>
|
||||
if (this == obj)
|
||||
{
|
||||
public int Compare(Type x, Type y)
|
||||
{
|
||||
return x.GetHashCode().CompareTo(y.GetHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private static HashCodeComparer interfaceComparer = new HashCodeComparer();
|
||||
|
||||
private Type baseType;
|
||||
private Type targetType;
|
||||
private List<Type> interfaceTypes;
|
||||
private bool proxyTargetAttributes;
|
||||
|
||||
public ProxyTypeCacheKey(Type baseType, Type targetType, IList<Type> interfaceTypes, bool proxyTargetAttributes)
|
||||
{
|
||||
this.baseType = baseType;
|
||||
this.targetType = targetType;
|
||||
this.interfaceTypes = new List<Type>(interfaceTypes);
|
||||
this.interfaceTypes.Sort(interfaceComparer); // sort by GetHashcode()? to have a defined order
|
||||
this.proxyTargetAttributes = proxyTargetAttributes;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
ProxyTypeCacheKey proxyTypeCacheKey = obj as ProxyTypeCacheKey;
|
||||
if (proxyTypeCacheKey == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!Equals(targetType, proxyTypeCacheKey.targetType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!Equals(baseType, proxyTypeCacheKey.baseType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < interfaceTypes.Count; i++)
|
||||
{
|
||||
if (!Equals(interfaceTypes[i], proxyTypeCacheKey.interfaceTypes[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (proxyTargetAttributes != proxyTypeCacheKey.proxyTargetAttributes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
ProxyTypeCacheKey proxyTypeCacheKey = obj as ProxyTypeCacheKey;
|
||||
if (proxyTypeCacheKey == null)
|
||||
{
|
||||
int result = baseType.GetHashCode();
|
||||
result = 29*result + targetType.GetHashCode();
|
||||
for (int i = 0; i < interfaceTypes.Count; i++)
|
||||
{
|
||||
result = 29 * result + interfaceTypes[i].GetHashCode();
|
||||
}
|
||||
result = 29 * result + proxyTargetAttributes.GetHashCode();
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
if (!Equals(targetType, proxyTypeCacheKey.targetType))
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("baseType=" + baseType + "; ");
|
||||
buffer.Append("targetType=" + targetType + "; ");
|
||||
buffer.Append("interfaceTypes=[");
|
||||
foreach (Type intf in interfaceTypes)
|
||||
{
|
||||
buffer.Append(intf + ";");
|
||||
}
|
||||
buffer.Append("]; ");
|
||||
buffer.Append("proxyTargetAttributes=" + proxyTargetAttributes + "; ");
|
||||
return buffer.ToString();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Equals(baseType, proxyTypeCacheKey.baseType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < interfaceTypes.Count; i++)
|
||||
{
|
||||
if (!Equals(interfaceTypes[i], proxyTypeCacheKey.interfaceTypes[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (proxyTargetAttributes != proxyTypeCacheKey.proxyTargetAttributes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int result = baseType.GetHashCode();
|
||||
result = 29 * result + targetType.GetHashCode();
|
||||
for (int i = 0; i < interfaceTypes.Count; i++)
|
||||
{
|
||||
result = 29 * result + interfaceTypes[i].GetHashCode();
|
||||
}
|
||||
|
||||
result = 29 * result + proxyTargetAttributes.GetHashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("baseType=" + baseType + "; ");
|
||||
buffer.Append("targetType=" + targetType + "; ");
|
||||
buffer.Append("interfaceTypes=[");
|
||||
foreach (Type intf in interfaceTypes)
|
||||
{
|
||||
buffer.Append(intf + ";");
|
||||
}
|
||||
|
||||
buffer.Append("]; ");
|
||||
buffer.Append("proxyTargetAttributes=" + proxyTargetAttributes + "; ");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -21,161 +21,159 @@
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Builds an AOP proxy type using composition.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class CompositionAopProxyTypeBuilder : AbstractAopProxyTypeBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds an AOP proxy type using composition.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class CompositionAopProxyTypeBuilder : AbstractAopProxyTypeBuilder
|
||||
private const string PROXY_TYPE_NAME = "CompositionAopProxy";
|
||||
|
||||
private readonly IAdvised advised;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="CompositionAopProxyTypeBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
public CompositionAopProxyTypeBuilder(IAdvised advised)
|
||||
{
|
||||
private const string PROXY_TYPE_NAME = "CompositionAopProxy";
|
||||
this.advised = advised;
|
||||
|
||||
private readonly IAdvised advised;
|
||||
Name = PROXY_TYPE_NAME;
|
||||
BaseType = typeof(BaseCompositionAopProxy);
|
||||
TargetType = advised.TargetSource.TargetType.IsInterface ? typeof(object) : advised.TargetSource.TargetType;
|
||||
Interfaces = GetProxiableInterfaces(advised.Interfaces);
|
||||
ProxyTargetAttributes = advised.ProxyTargetAttributes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="CompositionAopProxyTypeBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
public CompositionAopProxyTypeBuilder(IAdvised advised)
|
||||
/// <summary>
|
||||
/// Creates the proxy type.
|
||||
/// </summary>
|
||||
/// <returns>The generated proxy type.</returns>
|
||||
public override Type BuildProxyType()
|
||||
{
|
||||
Dictionary<string, MethodInfo> targetMethods = new Dictionary<string, MethodInfo>();
|
||||
|
||||
TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType);
|
||||
|
||||
// apply custom attributes to the proxy type.
|
||||
ApplyTypeAttributes(typeBuilder, TargetType);
|
||||
|
||||
if (advised.IsSerializable)
|
||||
{
|
||||
this.advised = advised;
|
||||
|
||||
Name = PROXY_TYPE_NAME;
|
||||
BaseType = typeof(BaseCompositionAopProxy);
|
||||
TargetType = advised.TargetSource.TargetType.IsInterface ? typeof(object) : advised.TargetSource.TargetType;
|
||||
Interfaces = GetProxiableInterfaces(advised.Interfaces);
|
||||
ProxyTargetAttributes = advised.ProxyTargetAttributes;
|
||||
typeBuilder.SetCustomAttribute(
|
||||
ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute)));
|
||||
ImplementSerializationConstructor(typeBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the proxy type.
|
||||
/// </summary>
|
||||
/// <returns>The generated proxy type.</returns>
|
||||
public override Type BuildProxyType()
|
||||
{
|
||||
Dictionary<string, MethodInfo> targetMethods = new Dictionary<string, MethodInfo>();
|
||||
// create constructors
|
||||
ImplementConstructors(typeBuilder);
|
||||
|
||||
TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType);
|
||||
|
||||
// apply custom attributes to the proxy type.
|
||||
ApplyTypeAttributes(typeBuilder, TargetType);
|
||||
|
||||
if (advised.IsSerializable)
|
||||
// implement interfaces
|
||||
IDictionary<Type, object> interfaceMap = advised.InterfaceMap;
|
||||
foreach (Type intf in Interfaces)
|
||||
{
|
||||
interfaceMap.TryGetValue(intf, out var target);
|
||||
if (target is null)
|
||||
{
|
||||
typeBuilder.SetCustomAttribute(
|
||||
ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute)));
|
||||
ImplementSerializationConstructor(typeBuilder);
|
||||
// implement interface
|
||||
ImplementInterface(typeBuilder,
|
||||
new TargetAopProxyMethodBuilder(typeBuilder, this, false, targetMethods),
|
||||
intf, TargetType);
|
||||
}
|
||||
else if (target is IIntroductionAdvisor)
|
||||
{
|
||||
// implement introduction
|
||||
ImplementInterface(typeBuilder,
|
||||
new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor) target)),
|
||||
intf, TargetType);
|
||||
}
|
||||
|
||||
// create constructors
|
||||
ImplementConstructors(typeBuilder);
|
||||
|
||||
// implement interfaces
|
||||
IDictionary<Type, object> interfaceMap = advised.InterfaceMap;
|
||||
foreach (Type intf in Interfaces)
|
||||
{
|
||||
interfaceMap.TryGetValue(intf, out var target);
|
||||
if (target is null)
|
||||
{
|
||||
// implement interface
|
||||
ImplementInterface(typeBuilder,
|
||||
new TargetAopProxyMethodBuilder(typeBuilder, this, false, targetMethods),
|
||||
intf, TargetType);
|
||||
}
|
||||
else if (target is IIntroductionAdvisor)
|
||||
{
|
||||
// implement introduction
|
||||
ImplementInterface(typeBuilder,
|
||||
new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor) target)),
|
||||
intf, TargetType);
|
||||
}
|
||||
}
|
||||
|
||||
Type proxyType = typeBuilder.CreateTypeInfo();
|
||||
|
||||
// set target method references
|
||||
foreach (KeyValuePair<string, MethodInfo> entry in targetMethods)
|
||||
{
|
||||
FieldInfo field = proxyType.GetField(entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
field.SetValue(proxyType, entry.Value);
|
||||
}
|
||||
|
||||
return proxyType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushAdvisedProxy(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements serialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">Type builder to use.</param>
|
||||
private void ImplementSerializationConstructor(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(MethodAttributes.Family,
|
||||
CallingConventions.Standard,
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
Type proxyType = typeBuilder.CreateTypeInfo();
|
||||
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldarg_2);
|
||||
il.Emit(OpCodes.Call, References.BaseCompositionAopProxySerializationConstructor);
|
||||
il.Emit(OpCodes.Ret);
|
||||
// set target method references
|
||||
foreach (KeyValuePair<string, MethodInfo> entry in targetMethods)
|
||||
{
|
||||
FieldInfo field = proxyType.GetField(entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
field.SetValue(proxyType, entry.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements constructors for the proxy class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation calls the base constructor.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="typeBuilder">
|
||||
/// The <see cref="System.Type"/> builder to use.
|
||||
/// </param>
|
||||
protected override void ImplementConstructors(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(References.BaseCompositionAopProxyConstructor.Attributes,
|
||||
References.BaseCompositionAopProxyConstructor.CallingConvention,
|
||||
new Type[] { typeof(IAdvised) });
|
||||
return proxyType;
|
||||
}
|
||||
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Call, References.BaseCompositionAopProxyConstructor);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushAdvisedProxy(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the specified <paramref name="type"/>
|
||||
/// is one of those generated by this builder.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the type is a composition-based proxy;
|
||||
/// otherwise <see langword="false"/>.
|
||||
/// </returns>
|
||||
public static bool IsCompositionProxy(Type type)
|
||||
{
|
||||
return type.FullName.StartsWith(PROXY_TYPE_NAME);
|
||||
}
|
||||
/// <summary>
|
||||
/// Implements serialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">Type builder to use.</param>
|
||||
private void ImplementSerializationConstructor(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(MethodAttributes.Family,
|
||||
CallingConventions.Standard,
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldarg_2);
|
||||
il.Emit(OpCodes.Call, References.BaseCompositionAopProxySerializationConstructor);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements constructors for the proxy class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation calls the base constructor.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="typeBuilder">
|
||||
/// The <see cref="System.Type"/> builder to use.
|
||||
/// </param>
|
||||
protected override void ImplementConstructors(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(References.BaseCompositionAopProxyConstructor.Attributes,
|
||||
References.BaseCompositionAopProxyConstructor.CallingConvention,
|
||||
new Type[] { typeof(IAdvised) });
|
||||
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Call, References.BaseCompositionAopProxyConstructor);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the specified <paramref name="type"/>
|
||||
/// is one of those generated by this builder.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the type is a composition-based proxy;
|
||||
/// otherwise <see langword="false"/>.
|
||||
/// </returns>
|
||||
public static bool IsCompositionProxy(Type type)
|
||||
{
|
||||
return type.FullName.StartsWith(PROXY_TYPE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,265 +21,264 @@
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using Spring.Util;
|
||||
using Spring.Proxy;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Builds an AOP proxy type using the decorator pattern.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class DecoratorAopProxyTypeBuilder : AbstractAopProxyTypeBuilder
|
||||
{
|
||||
private const string PROXY_TYPE_NAME = "DecoratorAopProxy";
|
||||
|
||||
private IAdvised advised;
|
||||
|
||||
/// <summary>
|
||||
/// Builds an AOP proxy type using the decorator pattern.
|
||||
/// AdvisedProxy instance calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class DecoratorAopProxyTypeBuilder : AbstractAopProxyTypeBuilder
|
||||
protected FieldBuilder advisedProxyField;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="DecoratorAopProxyTypeBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
public DecoratorAopProxyTypeBuilder(IAdvised advised)
|
||||
{
|
||||
private const string PROXY_TYPE_NAME = "DecoratorAopProxy";
|
||||
|
||||
private IAdvised advised;
|
||||
|
||||
/// <summary>
|
||||
/// AdvisedProxy instance calls should be delegated to.
|
||||
/// </summary>
|
||||
protected FieldBuilder advisedProxyField;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="DecoratorAopProxyTypeBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
public DecoratorAopProxyTypeBuilder(IAdvised advised)
|
||||
if (!ReflectionUtils.IsTypeVisible(advised.TargetSource.TargetType, DynamicProxyManager.ASSEMBLY_NAME))
|
||||
{
|
||||
if (!ReflectionUtils.IsTypeVisible(advised.TargetSource.TargetType, DynamicProxyManager.ASSEMBLY_NAME))
|
||||
throw new AopConfigException(String.Format(
|
||||
"Cannot create decorator-based IAopProxy for a non visible class [{0}]",
|
||||
advised.TargetSource.TargetType.FullName));
|
||||
}
|
||||
|
||||
if (advised.TargetSource.TargetType.IsSealed)
|
||||
{
|
||||
throw new AopConfigException(String.Format(
|
||||
"Cannot create decorator-based IAopProxy for a sealed class [{0}]",
|
||||
advised.TargetSource.TargetType.FullName));
|
||||
}
|
||||
|
||||
this.advised = advised;
|
||||
|
||||
Name = PROXY_TYPE_NAME;
|
||||
TargetType = advised.TargetSource.TargetType.IsInterface ? typeof(object) : advised.TargetSource.TargetType;
|
||||
BaseType = TargetType;
|
||||
Interfaces = GetProxiableInterfaces(advised.Interfaces);
|
||||
ProxyTargetAttributes = advised.ProxyTargetAttributes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the proxy type.
|
||||
/// </summary>
|
||||
/// <returns>The generated proxy class.</returns>
|
||||
public override Type BuildProxyType()
|
||||
{
|
||||
var targetMethods = new Dictionary<string, MethodInfo>();
|
||||
|
||||
TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType);
|
||||
|
||||
// apply custom attributes to the proxy type.
|
||||
ApplyTypeAttributes(typeBuilder, TargetType);
|
||||
|
||||
// declare fields
|
||||
DeclareAdvisedProxyInstanceField(typeBuilder);
|
||||
|
||||
// implement ISerializable if possible
|
||||
if (advised.IsSerializable)
|
||||
{
|
||||
typeBuilder.SetCustomAttribute(
|
||||
ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute)));
|
||||
ImplementSerializationConstructor(typeBuilder);
|
||||
ImplementGetObjectDataMethod(typeBuilder);
|
||||
}
|
||||
|
||||
// create constructors
|
||||
ImplementConstructors(typeBuilder);
|
||||
|
||||
// implement interfaces
|
||||
var interfaceMap = advised.InterfaceMap;
|
||||
foreach (Type intf in Interfaces)
|
||||
{
|
||||
interfaceMap.TryGetValue(intf, out var target);
|
||||
if (target is null)
|
||||
{
|
||||
throw new AopConfigException(String.Format(
|
||||
"Cannot create decorator-based IAopProxy for a non visible class [{0}]",
|
||||
advised.TargetSource.TargetType.FullName));
|
||||
// implement interface (proxy only final methods)
|
||||
ImplementInterface(typeBuilder,
|
||||
new TargetAopProxyMethodBuilder(typeBuilder, this, true, targetMethods),
|
||||
intf, TargetType, false);
|
||||
}
|
||||
if (advised.TargetSource.TargetType.IsSealed)
|
||||
else if (target is IIntroductionAdvisor)
|
||||
{
|
||||
throw new AopConfigException(String.Format(
|
||||
"Cannot create decorator-based IAopProxy for a sealed class [{0}]",
|
||||
advised.TargetSource.TargetType.FullName));
|
||||
// implement introduction
|
||||
ImplementInterface(typeBuilder,
|
||||
new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor) target)),
|
||||
intf, TargetType);
|
||||
}
|
||||
this.advised = advised;
|
||||
|
||||
Name = PROXY_TYPE_NAME;
|
||||
TargetType = advised.TargetSource.TargetType.IsInterface ? typeof(object) : advised.TargetSource.TargetType;
|
||||
BaseType = TargetType;
|
||||
Interfaces = GetProxiableInterfaces(advised.Interfaces);
|
||||
ProxyTargetAttributes = advised.ProxyTargetAttributes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the proxy type.
|
||||
/// </summary>
|
||||
/// <returns>The generated proxy class.</returns>
|
||||
public override Type BuildProxyType()
|
||||
// inherit from target type
|
||||
InheritType(typeBuilder,
|
||||
new TargetAopProxyMethodBuilder(typeBuilder, this, false, targetMethods),
|
||||
TargetType);
|
||||
|
||||
// implement IAdvised interface
|
||||
ImplementInterface(typeBuilder,
|
||||
new IAdvisedProxyMethodBuilder(typeBuilder, this),
|
||||
typeof(IAdvised), TargetType);
|
||||
|
||||
// implement IAopProxy interface
|
||||
ImplementIAopProxy(typeBuilder);
|
||||
|
||||
Type proxyType = typeBuilder.CreateTypeInfo();
|
||||
|
||||
// set target method references
|
||||
foreach (var entry in targetMethods)
|
||||
{
|
||||
var targetMethods = new Dictionary<string, MethodInfo>();
|
||||
|
||||
TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType);
|
||||
|
||||
// apply custom attributes to the proxy type.
|
||||
ApplyTypeAttributes(typeBuilder, TargetType);
|
||||
|
||||
// declare fields
|
||||
DeclareAdvisedProxyInstanceField(typeBuilder);
|
||||
|
||||
// implement ISerializable if possible
|
||||
if (advised.IsSerializable)
|
||||
{
|
||||
typeBuilder.SetCustomAttribute(
|
||||
ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute)));
|
||||
ImplementSerializationConstructor(typeBuilder);
|
||||
ImplementGetObjectDataMethod(typeBuilder);
|
||||
}
|
||||
|
||||
// create constructors
|
||||
ImplementConstructors(typeBuilder);
|
||||
|
||||
// implement interfaces
|
||||
var interfaceMap = advised.InterfaceMap;
|
||||
foreach (Type intf in Interfaces)
|
||||
{
|
||||
interfaceMap.TryGetValue(intf, out var target);
|
||||
if (target is null)
|
||||
{
|
||||
// implement interface (proxy only final methods)
|
||||
ImplementInterface(typeBuilder,
|
||||
new TargetAopProxyMethodBuilder(typeBuilder, this, true, targetMethods),
|
||||
intf, TargetType, false);
|
||||
}
|
||||
else if (target is IIntroductionAdvisor)
|
||||
{
|
||||
// implement introduction
|
||||
ImplementInterface(typeBuilder,
|
||||
new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor)target)),
|
||||
intf, TargetType);
|
||||
}
|
||||
}
|
||||
|
||||
// inherit from target type
|
||||
InheritType(typeBuilder,
|
||||
new TargetAopProxyMethodBuilder(typeBuilder, this, false, targetMethods),
|
||||
TargetType);
|
||||
|
||||
// implement IAdvised interface
|
||||
ImplementInterface(typeBuilder,
|
||||
new IAdvisedProxyMethodBuilder(typeBuilder, this),
|
||||
typeof(IAdvised), TargetType);
|
||||
|
||||
// implement IAopProxy interface
|
||||
ImplementIAopProxy(typeBuilder);
|
||||
|
||||
Type proxyType = typeBuilder.CreateTypeInfo();
|
||||
|
||||
// set target method references
|
||||
foreach (var entry in targetMethods)
|
||||
{
|
||||
FieldInfo field = proxyType.GetField(entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
field.SetValue(proxyType, entry.Value);
|
||||
}
|
||||
|
||||
return proxyType;
|
||||
FieldInfo field = proxyType.GetField(entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
field.SetValue(proxyType, entry.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushAdvisedProxy(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, advisedProxyField);
|
||||
}
|
||||
return proxyType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Declares field that holds the <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance used by the proxy.
|
||||
/// </summary>
|
||||
/// <param name="builder">
|
||||
/// The <see cref="System.Type"/> builder to use for code generation.
|
||||
/// </param>
|
||||
protected virtual void DeclareAdvisedProxyInstanceField(TypeBuilder builder)
|
||||
{
|
||||
advisedProxyField = builder.DefineField("__advisedProxy", typeof(AdvisedProxy), FieldAttributes.Private);
|
||||
}
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushAdvisedProxy(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, advisedProxyField);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements serialization method.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder"></param>
|
||||
private void ImplementGetObjectDataMethod(TypeBuilder typeBuilder)
|
||||
{
|
||||
typeBuilder.AddInterfaceImplementation(typeof(ISerializable));
|
||||
/// <summary>
|
||||
/// Declares field that holds the <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance used by the proxy.
|
||||
/// </summary>
|
||||
/// <param name="builder">
|
||||
/// The <see cref="System.Type"/> builder to use for code generation.
|
||||
/// </param>
|
||||
protected virtual void DeclareAdvisedProxyInstanceField(TypeBuilder builder)
|
||||
{
|
||||
advisedProxyField = builder.DefineField("__advisedProxy", typeof(AdvisedProxy), FieldAttributes.Private);
|
||||
}
|
||||
|
||||
MethodBuilder mb =
|
||||
typeBuilder.DefineMethod("GetObjectData",
|
||||
MethodAttributes.Public | MethodAttributes.HideBySig |
|
||||
MethodAttributes.NewSlot | MethodAttributes.Virtual,
|
||||
typeof (void),
|
||||
new Type[] {typeof (SerializationInfo), typeof (StreamingContext)});
|
||||
/// <summary>
|
||||
/// Implements serialization method.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder"></param>
|
||||
private void ImplementGetObjectDataMethod(TypeBuilder typeBuilder)
|
||||
{
|
||||
typeBuilder.AddInterfaceImplementation(typeof(ISerializable));
|
||||
|
||||
ILGenerator il = mb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldstr, "advisedProxy");
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, advisedProxyField);
|
||||
il.EmitCall(OpCodes.Callvirt, References.AddSerializationValue, null);
|
||||
il.Emit(OpCodes.Ret);
|
||||
MethodBuilder mb =
|
||||
typeBuilder.DefineMethod("GetObjectData",
|
||||
MethodAttributes.Public | MethodAttributes.HideBySig |
|
||||
MethodAttributes.NewSlot | MethodAttributes.Virtual,
|
||||
typeof(void),
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
|
||||
//typeBuilder.DefineMethodOverride(mb, typeof(ISerializable).GetMethod("GetObjectData"));
|
||||
}
|
||||
ILGenerator il = mb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldstr, "advisedProxy");
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, advisedProxyField);
|
||||
il.EmitCall(OpCodes.Callvirt, References.AddSerializationValue, null);
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
//typeBuilder.DefineMethodOverride(mb, typeof(ISerializable).GetMethod("GetObjectData"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements serialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">Type builder to use.</param>
|
||||
private void ImplementSerializationConstructor(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(MethodAttributes.Family,
|
||||
CallingConventions.Standard,
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
/// <summary>
|
||||
/// Implements serialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">Type builder to use.</param>
|
||||
private void ImplementSerializationConstructor(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(MethodAttributes.Family,
|
||||
CallingConventions.Standard,
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldstr, "advisedProxy");
|
||||
il.Emit(OpCodes.Ldtoken, typeof(AdvisedProxy));
|
||||
il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetSerializationValue, null);
|
||||
il.Emit(OpCodes.Castclass, typeof(AdvisedProxy));
|
||||
il.Emit(OpCodes.Stfld, advisedProxyField);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldstr, "advisedProxy");
|
||||
il.Emit(OpCodes.Ldtoken, typeof(AdvisedProxy));
|
||||
il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetSerializationValue, null);
|
||||
il.Emit(OpCodes.Castclass, typeof(AdvisedProxy));
|
||||
il.Emit(OpCodes.Stfld, advisedProxyField);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements constructors for the proxy class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation creates a new instance
|
||||
/// of the <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/> class.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="typeBuilder">
|
||||
/// The <see cref="System.Type"/> builder to use.
|
||||
/// </param>
|
||||
protected override void ImplementConstructors(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(References.ObjectConstructor.Attributes,
|
||||
References.ObjectConstructor.CallingConvention,
|
||||
new Type[] { typeof(IAdvised) });
|
||||
/// <summary>
|
||||
/// Implements constructors for the proxy class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation creates a new instance
|
||||
/// of the <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/> class.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="typeBuilder">
|
||||
/// The <see cref="System.Type"/> builder to use.
|
||||
/// </param>
|
||||
protected override void ImplementConstructors(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(References.ObjectConstructor.Attributes,
|
||||
References.ObjectConstructor.CallingConvention,
|
||||
new Type[] { typeof(IAdvised) });
|
||||
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Newobj, References.AdvisedProxyConstructor);
|
||||
il.Emit(OpCodes.Stfld, advisedProxyField);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Newobj, References.AdvisedProxyConstructor);
|
||||
il.Emit(OpCodes.Stfld, advisedProxyField);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements <see cref="Spring.Aop.Framework.IAopProxy"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
protected virtual void ImplementIAopProxy(TypeBuilder typeBuilder)
|
||||
{
|
||||
Type intf = typeof(IAopProxy);
|
||||
MethodInfo getProxyMethod = intf.GetMethod("GetProxy", Type.EmptyTypes);
|
||||
/// <summary>
|
||||
/// Implements <see cref="Spring.Aop.Framework.IAopProxy"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
protected virtual void ImplementIAopProxy(TypeBuilder typeBuilder)
|
||||
{
|
||||
Type intf = typeof(IAopProxy);
|
||||
MethodInfo getProxyMethod = intf.GetMethod("GetProxy", Type.EmptyTypes);
|
||||
|
||||
typeBuilder.AddInterfaceImplementation(intf);
|
||||
typeBuilder.AddInterfaceImplementation(intf);
|
||||
|
||||
MethodBuilder mb = typeBuilder.DefineMethod(typeof(IAdvised).FullName + "." + getProxyMethod.Name,
|
||||
MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
|
||||
getProxyMethod.CallingConvention, getProxyMethod.ReturnType, Type.EmptyTypes);
|
||||
MethodBuilder mb = typeBuilder.DefineMethod(typeof(IAdvised).FullName + "." + getProxyMethod.Name,
|
||||
MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
|
||||
getProxyMethod.CallingConvention, getProxyMethod.ReturnType, Type.EmptyTypes);
|
||||
|
||||
ILGenerator il = mb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ret);
|
||||
ILGenerator il = mb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
typeBuilder.DefineMethodOverride(mb, getProxyMethod);
|
||||
}
|
||||
typeBuilder.DefineMethodOverride(mb, getProxyMethod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the specified <paramref name="type"/>
|
||||
/// is one of those generated by this builder.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the type is a decorator-based proxy;
|
||||
/// otherwise <see langword="false"/>.
|
||||
/// </returns>
|
||||
public static bool IsDecoratorProxy(Type type)
|
||||
{
|
||||
return type.FullName.StartsWith(PROXY_TYPE_NAME);
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines if the specified <paramref name="type"/>
|
||||
/// is one of those generated by this builder.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the type is a decorator-based proxy;
|
||||
/// otherwise <see langword="false"/>.
|
||||
/// </returns>
|
||||
public static bool IsDecoratorProxy(Type type)
|
||||
{
|
||||
return type.FullName.StartsWith(PROXY_TYPE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,76 +22,77 @@ using System.Reflection;
|
||||
using Spring.Proxy;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Default implementation of the
|
||||
/// <see cref="Spring.Aop.Framework.IAopProxyFactory"/> interface,
|
||||
/// either creating a decorator-based dynamic proxy or
|
||||
/// a composition-based dynamic proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Creates a decorator-base proxy if one the following is true :
|
||||
/// - the "ProxyTargetType" property is set
|
||||
/// - no interfaces have been specified
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// In general, specify "ProxyTargetType" to enforce a decorator-based proxy,
|
||||
/// or specify one or more interfaces to use a composition-based proxy.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <author>Bruno Baia (.NET)</author>
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory"/>
|
||||
[Serializable]
|
||||
public class DefaultAopProxyFactory : AbstractAopProxyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of the
|
||||
/// <see cref="Spring.Aop.Framework.IAopProxyFactory"/> interface,
|
||||
/// either creating a decorator-based dynamic proxy or
|
||||
/// a composition-based dynamic proxy.
|
||||
/// Force transient assemblies to be resolvable by <see cref="Assembly.Load(string)"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Creates a decorator-base proxy if one the following is true :
|
||||
/// - the "ProxyTargetType" property is set
|
||||
/// - no interfaces have been specified
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// In general, specify "ProxyTargetType" to enforce a decorator-based proxy,
|
||||
/// or specify one or more interfaces to use a composition-based proxy.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <author>Bruno Baia (.NET)</author>
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory"/>
|
||||
[Serializable]
|
||||
public class DefaultAopProxyFactory : AbstractAopProxyFactory
|
||||
static DefaultAopProxyFactory()
|
||||
{
|
||||
/// <summary>
|
||||
/// Force transient assemblies to be resolvable by <see cref="Assembly.Load(string)"/>.
|
||||
/// </summary>
|
||||
static DefaultAopProxyFactory()
|
||||
{
|
||||
SystemUtils.RegisterLoadedAssemblyResolver();
|
||||
}
|
||||
SystemUtils.RegisterLoadedAssemblyResolver();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an actual proxy instance based on the supplied <paramref name="advisedSupport"/>
|
||||
/// </summary>
|
||||
/// <param name="advisedSupport"></param>
|
||||
/// <returns></returns>
|
||||
protected override IAopProxy DoCreateAopProxyInstance(AdvisedSupport advisedSupport)
|
||||
/// <summary>
|
||||
/// Creates an actual proxy instance based on the supplied <paramref name="advisedSupport"/>
|
||||
/// </summary>
|
||||
/// <param name="advisedSupport"></param>
|
||||
/// <returns></returns>
|
||||
protected override IAopProxy DoCreateAopProxyInstance(AdvisedSupport advisedSupport)
|
||||
{
|
||||
if (advisedSupport.ProxyType == null)
|
||||
{
|
||||
if (advisedSupport.ProxyType == null)
|
||||
IProxyTypeBuilder typeBuilder;
|
||||
if ((advisedSupport.ProxyTargetType) ||
|
||||
(advisedSupport.Interfaces.Count == 0))
|
||||
{
|
||||
IProxyTypeBuilder typeBuilder;
|
||||
if ((advisedSupport.ProxyTargetType) ||
|
||||
(advisedSupport.Interfaces.Count == 0))
|
||||
{
|
||||
typeBuilder = new DecoratorAopProxyTypeBuilder(advisedSupport);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeBuilder = new CompositionAopProxyTypeBuilder(advisedSupport);
|
||||
}
|
||||
advisedSupport.ProxyType = BuildProxyType(typeBuilder);
|
||||
advisedSupport.ProxyConstructor = advisedSupport.ProxyType.GetConstructor(new Type[] { typeof(IAdvised) });
|
||||
typeBuilder = new DecoratorAopProxyTypeBuilder(advisedSupport);
|
||||
}
|
||||
return (IAopProxy)advisedSupport.ProxyConstructor.Invoke(new object[] { advisedSupport });
|
||||
else
|
||||
{
|
||||
typeBuilder = new CompositionAopProxyTypeBuilder(advisedSupport);
|
||||
}
|
||||
|
||||
advisedSupport.ProxyType = BuildProxyType(typeBuilder);
|
||||
advisedSupport.ProxyConstructor = advisedSupport.ProxyType.GetConstructor(new Type[] { typeof(IAdvised) });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the proxy type.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">
|
||||
/// The <see cref="Spring.Proxy.IProxyTypeBuilder"/> to use
|
||||
/// </param>
|
||||
/// <returns>The generated proxy class.</returns>
|
||||
protected virtual Type BuildProxyType(IProxyTypeBuilder typeBuilder)
|
||||
{
|
||||
return typeBuilder.BuildProxyType();
|
||||
}
|
||||
return (IAopProxy) advisedSupport.ProxyConstructor.Invoke(new object[] { advisedSupport });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the proxy type.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">
|
||||
/// The <see cref="Spring.Proxy.IProxyTypeBuilder"/> to use
|
||||
/// </param>
|
||||
/// <returns>The generated proxy class.</returns>
|
||||
protected virtual Type BuildProxyType(IProxyTypeBuilder typeBuilder)
|
||||
{
|
||||
return typeBuilder.BuildProxyType();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -21,59 +21,57 @@
|
||||
#region Imports
|
||||
|
||||
using System.Reflection.Emit;
|
||||
|
||||
using Spring.Proxy;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Proxy.IProxyMethodBuilder"/> implementation that delegates
|
||||
/// method calls to an <see cref="Spring.Aop.Framework.IAdvised"/> instance.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class IAdvisedProxyMethodBuilder : TargetProxyMethodBuilder
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Proxy.IProxyMethodBuilder"/> implementation that delegates
|
||||
/// method calls to an <see cref="Spring.Aop.Framework.IAdvised"/> instance.
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class IAdvisedProxyMethodBuilder : TargetProxyMethodBuilder
|
||||
private IAopProxyTypeGenerator _aopProxyGenerator;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor(s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the method builder.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
/// <param name="aopProxyGenerator">
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </param>
|
||||
public IAdvisedProxyMethodBuilder(
|
||||
TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator)
|
||||
: base(typeBuilder, aopProxyGenerator, true)
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </summary>
|
||||
private IAopProxyTypeGenerator _aopProxyGenerator;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor(s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the method builder.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
/// <param name="aopProxyGenerator">
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </param>
|
||||
public IAdvisedProxyMethodBuilder(
|
||||
TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator)
|
||||
: base(typeBuilder, aopProxyGenerator, true)
|
||||
{
|
||||
this._aopProxyGenerator = aopProxyGenerator;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the target instance on which calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
protected override void PushTarget(ILGenerator il)
|
||||
{
|
||||
_aopProxyGenerator.PushAdvisedProxy(il);
|
||||
}
|
||||
|
||||
#endregion
|
||||
this._aopProxyGenerator = aopProxyGenerator;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the target instance on which calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
protected override void PushTarget(ILGenerator il)
|
||||
{
|
||||
_aopProxyGenerator.PushAdvisedProxy(il);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -21,26 +21,24 @@
|
||||
#region Imports
|
||||
|
||||
using System.Reflection.Emit;
|
||||
|
||||
using Spring.Proxy;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Describes the operations that generates IL instructions
|
||||
/// used to build the Aop proxy type.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public interface IAopProxyTypeGenerator : IProxyTypeGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the operations that generates IL instructions
|
||||
/// used to build the Aop proxy type.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public interface IAopProxyTypeGenerator : IProxyTypeGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
void PushAdvisedProxy(ILGenerator il);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
void PushAdvisedProxy(ILGenerator il);
|
||||
}
|
||||
|
||||
@@ -21,315 +21,316 @@
|
||||
using System.Runtime.Serialization;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
using Spring.Proxy;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Builds an AOP proxy type using inheritance.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class InheritanceAopProxyTypeBuilder : AbstractAopProxyTypeBuilder
|
||||
{
|
||||
private const string PROXY_TYPE_NAME = "InheritanceAopProxy";
|
||||
|
||||
private IAdvised advised;
|
||||
private bool proxyDeclaredMembersOnly = true;
|
||||
|
||||
/// <summary>
|
||||
/// Builds an AOP proxy type using inheritance.
|
||||
/// AdvisedProxy instance calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class InheritanceAopProxyTypeBuilder : AbstractAopProxyTypeBuilder
|
||||
protected FieldBuilder advisedProxyField;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether inherited members should be proxied.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if inherited members should be proxied;
|
||||
/// otherwise, <see langword="false"/>.
|
||||
/// </value>
|
||||
public bool ProxyDeclaredMembersOnly
|
||||
{
|
||||
private const string PROXY_TYPE_NAME = "InheritanceAopProxy";
|
||||
get { return proxyDeclaredMembersOnly; }
|
||||
set { proxyDeclaredMembersOnly = value; }
|
||||
}
|
||||
|
||||
private IAdvised advised;
|
||||
private bool proxyDeclaredMembersOnly = true;
|
||||
|
||||
/// <summary>
|
||||
/// AdvisedProxy instance calls should be delegated to.
|
||||
/// </summary>
|
||||
protected FieldBuilder advisedProxyField;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether inherited members should be proxied.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if inherited members should be proxied;
|
||||
/// otherwise, <see langword="false"/>.
|
||||
/// </value>
|
||||
public bool ProxyDeclaredMembersOnly
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="CompositionAopProxyTypeBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
public InheritanceAopProxyTypeBuilder(IAdvised advised)
|
||||
{
|
||||
if (!ReflectionUtils.IsTypeVisible(advised.TargetSource.TargetType, DynamicProxyManager.ASSEMBLY_NAME))
|
||||
{
|
||||
get { return proxyDeclaredMembersOnly; }
|
||||
set { proxyDeclaredMembersOnly = value; }
|
||||
throw new AopConfigException(String.Format(
|
||||
"Cannot create inheritance-based IAopProxy for a non visible class [{0}]",
|
||||
advised.TargetSource.TargetType.FullName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="CompositionAopProxyTypeBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration.</param>
|
||||
public InheritanceAopProxyTypeBuilder(IAdvised advised)
|
||||
if (advised.TargetSource.TargetType.IsSealed)
|
||||
{
|
||||
if (!ReflectionUtils.IsTypeVisible(advised.TargetSource.TargetType, DynamicProxyManager.ASSEMBLY_NAME))
|
||||
throw new AopConfigException(String.Format(
|
||||
"Cannot create inheritance-based IAopProxy for a sealed class [{0}]",
|
||||
advised.TargetSource.TargetType.FullName));
|
||||
}
|
||||
|
||||
this.advised = advised;
|
||||
|
||||
Name = PROXY_TYPE_NAME;
|
||||
TargetType = advised.TargetSource.TargetType;
|
||||
BaseType = TargetType;
|
||||
Interfaces = GetProxiableInterfaces(advised.Interfaces);
|
||||
ProxyTargetAttributes = advised.ProxyTargetAttributes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the proxy type.
|
||||
/// </summary>
|
||||
/// <returns>The generated proxy class.</returns>
|
||||
public override Type BuildProxyType()
|
||||
{
|
||||
var targetMethods = new Dictionary<string, MethodInfo>();
|
||||
var proxyMethods = new Dictionary<string, MethodInfo>();
|
||||
|
||||
TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType);
|
||||
|
||||
// apply custom attributes to the proxy type.
|
||||
ApplyTypeAttributes(typeBuilder, TargetType);
|
||||
|
||||
// declare fields
|
||||
DeclareAdvisedProxyInstanceField(typeBuilder);
|
||||
|
||||
// implement ISerializable if possible
|
||||
if (advised.IsSerializable)
|
||||
{
|
||||
typeBuilder.SetCustomAttribute(
|
||||
ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute)));
|
||||
ImplementSerializationConstructor(typeBuilder);
|
||||
ImplementGetObjectDataMethod(typeBuilder);
|
||||
}
|
||||
|
||||
// create constructors
|
||||
ImplementConstructors(typeBuilder);
|
||||
|
||||
// implement interfaces
|
||||
var interfaceMap = advised.InterfaceMap;
|
||||
foreach (Type intf in Interfaces)
|
||||
{
|
||||
object target = interfaceMap[intf];
|
||||
if (target == null)
|
||||
{
|
||||
throw new AopConfigException(String.Format(
|
||||
"Cannot create inheritance-based IAopProxy for a non visible class [{0}]",
|
||||
advised.TargetSource.TargetType.FullName));
|
||||
// implement interface (proxy only final methods)
|
||||
ImplementInterface(typeBuilder,
|
||||
new BaseAopProxyMethodBuilder(typeBuilder, this, targetMethods, proxyMethods),
|
||||
intf, TargetType, false);
|
||||
}
|
||||
if (advised.TargetSource.TargetType.IsSealed)
|
||||
else if (target is IIntroductionAdvisor)
|
||||
{
|
||||
throw new AopConfigException(String.Format(
|
||||
"Cannot create inheritance-based IAopProxy for a sealed class [{0}]",
|
||||
advised.TargetSource.TargetType.FullName));
|
||||
// implement introduction
|
||||
ImplementInterface(typeBuilder,
|
||||
new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor) target)),
|
||||
intf, TargetType);
|
||||
}
|
||||
this.advised = advised;
|
||||
|
||||
Name = PROXY_TYPE_NAME;
|
||||
TargetType = advised.TargetSource.TargetType;
|
||||
BaseType = TargetType;
|
||||
Interfaces = GetProxiableInterfaces(advised.Interfaces);
|
||||
ProxyTargetAttributes = advised.ProxyTargetAttributes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the proxy type.
|
||||
/// </summary>
|
||||
/// <returns>The generated proxy class.</returns>
|
||||
public override Type BuildProxyType()
|
||||
// inherit from target type
|
||||
InheritType(typeBuilder,
|
||||
new BaseAopProxyMethodBuilder(typeBuilder, this, targetMethods, proxyMethods),
|
||||
TargetType, ProxyDeclaredMembersOnly);
|
||||
|
||||
// implement IAdvised interface
|
||||
ImplementInterface(typeBuilder,
|
||||
new IAdvisedProxyMethodBuilder(typeBuilder, this),
|
||||
typeof(IAdvised), TargetType);
|
||||
|
||||
// implement IAopProxy interface
|
||||
ImplementIAopProxy(typeBuilder);
|
||||
|
||||
Type proxyType;
|
||||
proxyType = typeBuilder.CreateTypeInfo();
|
||||
|
||||
// set target method references
|
||||
foreach (var entry in targetMethods)
|
||||
{
|
||||
var targetMethods = new Dictionary<string, MethodInfo>();
|
||||
var proxyMethods = new Dictionary<string, MethodInfo>();
|
||||
|
||||
TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType);
|
||||
|
||||
// apply custom attributes to the proxy type.
|
||||
ApplyTypeAttributes(typeBuilder, TargetType);
|
||||
|
||||
// declare fields
|
||||
DeclareAdvisedProxyInstanceField(typeBuilder);
|
||||
|
||||
// implement ISerializable if possible
|
||||
if (advised.IsSerializable)
|
||||
{
|
||||
typeBuilder.SetCustomAttribute(
|
||||
ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute)));
|
||||
ImplementSerializationConstructor(typeBuilder);
|
||||
ImplementGetObjectDataMethod(typeBuilder);
|
||||
}
|
||||
|
||||
// create constructors
|
||||
ImplementConstructors(typeBuilder);
|
||||
|
||||
// implement interfaces
|
||||
var interfaceMap = advised.InterfaceMap;
|
||||
foreach (Type intf in Interfaces)
|
||||
{
|
||||
object target = interfaceMap[intf];
|
||||
if (target == null)
|
||||
{
|
||||
// implement interface (proxy only final methods)
|
||||
ImplementInterface(typeBuilder,
|
||||
new BaseAopProxyMethodBuilder(typeBuilder, this, targetMethods, proxyMethods),
|
||||
intf, TargetType, false);
|
||||
}
|
||||
else if (target is IIntroductionAdvisor)
|
||||
{
|
||||
// implement introduction
|
||||
ImplementInterface(typeBuilder,
|
||||
new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor)target)),
|
||||
intf, TargetType);
|
||||
}
|
||||
}
|
||||
|
||||
// inherit from target type
|
||||
InheritType(typeBuilder,
|
||||
new BaseAopProxyMethodBuilder(typeBuilder, this, targetMethods, proxyMethods),
|
||||
TargetType, ProxyDeclaredMembersOnly);
|
||||
|
||||
// implement IAdvised interface
|
||||
ImplementInterface(typeBuilder,
|
||||
new IAdvisedProxyMethodBuilder(typeBuilder, this),
|
||||
typeof(IAdvised), TargetType);
|
||||
|
||||
// implement IAopProxy interface
|
||||
ImplementIAopProxy(typeBuilder);
|
||||
|
||||
Type proxyType;
|
||||
proxyType = typeBuilder.CreateTypeInfo();
|
||||
|
||||
// set target method references
|
||||
foreach (var entry in targetMethods)
|
||||
{
|
||||
FieldInfo field = proxyType.GetField(entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
field.SetValue(proxyType, entry.Value);
|
||||
}
|
||||
|
||||
// set proxy method references
|
||||
foreach (var entry in proxyMethods)
|
||||
{
|
||||
FieldInfo field = proxyType.GetField(entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
MethodInfo proxyMethod = proxyType.GetMethod("proxy_" + entry.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
field.SetValue(proxyType, proxyMethod);
|
||||
}
|
||||
|
||||
return proxyType;
|
||||
FieldInfo field = proxyType.GetField(entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
field.SetValue(proxyType, entry.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the target instance on which calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushTarget(ILGenerator il)
|
||||
// set proxy method references
|
||||
foreach (var entry in proxyMethods)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
FieldInfo field = proxyType.GetField(entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
MethodInfo proxyMethod = proxyType.GetMethod("proxy_" + entry.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
field.SetValue(proxyType, proxyMethod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushAdvisedProxy(ILGenerator il)
|
||||
return proxyType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the target instance on which calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushTarget(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the current <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
public override void PushAdvisedProxy(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, advisedProxyField);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Declares field that holds the <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance used by the proxy.
|
||||
/// </summary>
|
||||
/// <param name="builder">
|
||||
/// The <see cref="System.Type"/> builder to use for code generation.
|
||||
/// </param>
|
||||
protected virtual void DeclareAdvisedProxyInstanceField(TypeBuilder builder)
|
||||
{
|
||||
advisedProxyField = builder.DefineField("__advisedProxy", typeof(AdvisedProxy), FieldAttributes.Private);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements serialization method.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder"></param>
|
||||
private void ImplementGetObjectDataMethod(TypeBuilder typeBuilder)
|
||||
{
|
||||
typeBuilder.AddInterfaceImplementation(typeof(ISerializable));
|
||||
|
||||
MethodBuilder mb =
|
||||
typeBuilder.DefineMethod("GetObjectData",
|
||||
MethodAttributes.Public | MethodAttributes.HideBySig |
|
||||
MethodAttributes.NewSlot | MethodAttributes.Virtual,
|
||||
typeof(void),
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
|
||||
ILGenerator il = mb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldstr, "advisedProxy");
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, advisedProxyField);
|
||||
il.EmitCall(OpCodes.Callvirt, References.AddSerializationValue, null);
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
//typeBuilder.DefineMethodOverride(mb, typeof(ISerializable).GetMethod("GetObjectData"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements serialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">Type builder to use.</param>
|
||||
private void ImplementSerializationConstructor(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(MethodAttributes.Family,
|
||||
CallingConventions.Standard,
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldstr, "advisedProxy");
|
||||
il.Emit(OpCodes.Ldtoken, typeof(AdvisedProxy));
|
||||
il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetSerializationValue, null);
|
||||
il.Emit(OpCodes.Castclass, typeof(AdvisedProxy));
|
||||
il.Emit(OpCodes.Stfld, advisedProxyField);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the types of the parameters for the specified constructor.
|
||||
/// </summary>
|
||||
/// <param name="constructor">The constructor to use.</param>
|
||||
/// <returns>The types for constructor's parameters.</returns>
|
||||
protected override Type[] DefineConstructorParameters(ConstructorInfo constructor)
|
||||
{
|
||||
Type[] currentParams = ReflectionUtils.GetParameterTypes(constructor.GetParameters());
|
||||
Type[] newParams = new Type[currentParams.Length + 1];
|
||||
|
||||
newParams[currentParams.Length] = typeof(IAdvised);
|
||||
currentParams.CopyTo(newParams, 0);
|
||||
|
||||
return newParams;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the proxy constructor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation creates instance of the AdvisedProxy object.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="builder">The constructor builder to use.</param>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="constructor">The constructor to delegate the creation to.</param>
|
||||
protected override void GenerateConstructor(
|
||||
ConstructorBuilder builder, ILGenerator il, ConstructorInfo constructor)
|
||||
{
|
||||
int paramCount = constructor.GetParameters().Length;
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
for (int i = 0; i < paramCount; i++)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, advisedProxyField);
|
||||
il.Emit(OpCodes.Ldarg_S, i + 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Declares field that holds the <see cref="Spring.Aop.Framework.DynamicProxy.AdvisedProxy"/>
|
||||
/// instance used by the proxy.
|
||||
/// </summary>
|
||||
/// <param name="builder">
|
||||
/// The <see cref="System.Type"/> builder to use for code generation.
|
||||
/// </param>
|
||||
protected virtual void DeclareAdvisedProxyInstanceField(TypeBuilder builder)
|
||||
{
|
||||
advisedProxyField = builder.DefineField("__advisedProxy", typeof(AdvisedProxy), FieldAttributes.Private);
|
||||
}
|
||||
il.Emit(OpCodes.Call, constructor);
|
||||
|
||||
/// <summary>
|
||||
/// Implements serialization method.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder"></param>
|
||||
private void ImplementGetObjectDataMethod(TypeBuilder typeBuilder)
|
||||
{
|
||||
typeBuilder.AddInterfaceImplementation(typeof(ISerializable));
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_S, paramCount + 1);
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Newobj, References.AdvisedProxyConstructor);
|
||||
il.Emit(OpCodes.Stfld, advisedProxyField);
|
||||
}
|
||||
|
||||
MethodBuilder mb =
|
||||
typeBuilder.DefineMethod("GetObjectData",
|
||||
MethodAttributes.Public | MethodAttributes.HideBySig |
|
||||
MethodAttributes.NewSlot | MethodAttributes.Virtual,
|
||||
typeof(void),
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
/// <summary>
|
||||
/// Implements <see cref="Spring.Aop.Framework.IAopProxy"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
protected virtual void ImplementIAopProxy(TypeBuilder typeBuilder)
|
||||
{
|
||||
Type intf = typeof(IAopProxy);
|
||||
MethodInfo getProxyMethod = intf.GetMethod("GetProxy", Type.EmptyTypes);
|
||||
|
||||
ILGenerator il = mb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldstr, "advisedProxy");
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, advisedProxyField);
|
||||
il.EmitCall(OpCodes.Callvirt, References.AddSerializationValue, null);
|
||||
il.Emit(OpCodes.Ret);
|
||||
typeBuilder.AddInterfaceImplementation(intf);
|
||||
|
||||
//typeBuilder.DefineMethodOverride(mb, typeof(ISerializable).GetMethod("GetObjectData"));
|
||||
}
|
||||
MethodBuilder mb = typeBuilder.DefineMethod(typeof(IAdvised).FullName + "." + getProxyMethod.Name,
|
||||
MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
|
||||
getProxyMethod.CallingConvention, getProxyMethod.ReturnType, Type.EmptyTypes);
|
||||
|
||||
/// <summary>
|
||||
/// Implements serialization constructor.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">Type builder to use.</param>
|
||||
private void ImplementSerializationConstructor(TypeBuilder typeBuilder)
|
||||
{
|
||||
ConstructorBuilder cb =
|
||||
typeBuilder.DefineConstructor(MethodAttributes.Family,
|
||||
CallingConventions.Standard,
|
||||
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
|
||||
ILGenerator il = mb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
ILGenerator il = cb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
il.Emit(OpCodes.Ldstr, "advisedProxy");
|
||||
il.Emit(OpCodes.Ldtoken, typeof(AdvisedProxy));
|
||||
il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetSerializationValue, null);
|
||||
il.Emit(OpCodes.Castclass, typeof(AdvisedProxy));
|
||||
il.Emit(OpCodes.Stfld, advisedProxyField);
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
typeBuilder.DefineMethodOverride(mb, getProxyMethod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the types of the parameters for the specified constructor.
|
||||
/// </summary>
|
||||
/// <param name="constructor">The constructor to use.</param>
|
||||
/// <returns>The types for constructor's parameters.</returns>
|
||||
protected override Type[] DefineConstructorParameters(ConstructorInfo constructor)
|
||||
{
|
||||
Type[] currentParams = ReflectionUtils.GetParameterTypes(constructor.GetParameters());
|
||||
Type[] newParams = new Type[currentParams.Length + 1];
|
||||
|
||||
newParams[currentParams.Length] = typeof(IAdvised);
|
||||
currentParams.CopyTo(newParams, 0);
|
||||
|
||||
return newParams;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the proxy constructor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation creates instance of the AdvisedProxy object.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="builder">The constructor builder to use.</param>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="constructor">The constructor to delegate the creation to.</param>
|
||||
protected override void GenerateConstructor(
|
||||
ConstructorBuilder builder, ILGenerator il, ConstructorInfo constructor)
|
||||
{
|
||||
int paramCount = constructor.GetParameters().Length;
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
for (int i = 0; i < paramCount; i++)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_S, i + 1);
|
||||
}
|
||||
il.Emit(OpCodes.Call, constructor);
|
||||
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldarg_S, paramCount + 1);
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Newobj, References.AdvisedProxyConstructor);
|
||||
il.Emit(OpCodes.Stfld, advisedProxyField);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements <see cref="Spring.Aop.Framework.IAopProxy"/> interface.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
protected virtual void ImplementIAopProxy(TypeBuilder typeBuilder)
|
||||
{
|
||||
Type intf = typeof(IAopProxy);
|
||||
MethodInfo getProxyMethod = intf.GetMethod("GetProxy", Type.EmptyTypes);
|
||||
|
||||
typeBuilder.AddInterfaceImplementation(intf);
|
||||
|
||||
MethodBuilder mb = typeBuilder.DefineMethod(typeof(IAdvised).FullName + "." + getProxyMethod.Name,
|
||||
MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
|
||||
getProxyMethod.CallingConvention, getProxyMethod.ReturnType, Type.EmptyTypes);
|
||||
|
||||
ILGenerator il = mb.GetILGenerator();
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
typeBuilder.DefineMethodOverride(mb, getProxyMethod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the specified <paramref name="type"/>
|
||||
/// is one of those generated by this builder.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the type is a inheritance-based proxy;
|
||||
/// otherwise <see langword="false"/>.
|
||||
/// </returns>
|
||||
public static bool IsInheritanceProxy(Type type)
|
||||
{
|
||||
return type.FullName.StartsWith(PROXY_TYPE_NAME);
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines if the specified <paramref name="type"/>
|
||||
/// is one of those generated by this builder.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the type is a inheritance-based proxy;
|
||||
/// otherwise <see langword="false"/>.
|
||||
/// </returns>
|
||||
public static bool IsInheritanceProxy(Type type)
|
||||
{
|
||||
return type.FullName.StartsWith(PROXY_TYPE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,76 +21,75 @@
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Proxy.IProxyMethodBuilder"/> implementation
|
||||
/// that delegates method calls to introduction object.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class IntroductionProxyMethodBuilder : AbstractAopProxyMethodBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Proxy.IProxyMethodBuilder"/> implementation
|
||||
/// that delegates method calls to introduction object.
|
||||
/// The index of the introduction to delegate call to.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class IntroductionProxyMethodBuilder : AbstractAopProxyMethodBuilder
|
||||
protected int index;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the method builder.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
/// <param name="aopProxyGenerator">
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </param>
|
||||
/// <param name="targetMethods">
|
||||
///
|
||||
/// </param>
|
||||
/// <param name="index">index of the introduction to delegate call to</param>
|
||||
public IntroductionProxyMethodBuilder(
|
||||
TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator,
|
||||
IDictionary<string, MethodInfo> targetMethods, int index)
|
||||
: base(typeBuilder, aopProxyGenerator, true, targetMethods)
|
||||
{
|
||||
/// <summary>
|
||||
/// The index of the introduction to delegate call to.
|
||||
/// </summary>
|
||||
protected int index;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the method builder.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
/// <param name="aopProxyGenerator">
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </param>
|
||||
/// <param name="targetMethods">
|
||||
///
|
||||
/// </param>
|
||||
/// <param name="index">index of the introduction to delegate call to</param>
|
||||
public IntroductionProxyMethodBuilder(
|
||||
TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator,
|
||||
IDictionary<string, MethodInfo> targetMethods, int index)
|
||||
: base(typeBuilder, aopProxyGenerator, true, targetMethods)
|
||||
{
|
||||
this.index = index;
|
||||
}
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the introduction type on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
protected override void PushTargetType(ILGenerator il)
|
||||
{
|
||||
PushTarget(il);
|
||||
il.EmitCall(OpCodes.Call, References.GetTypeMethod, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the introduction type on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
protected override void PushTargetType(ILGenerator il)
|
||||
{
|
||||
PushTarget(il);
|
||||
il.EmitCall(OpCodes.Call, References.GetTypeMethod, null);
|
||||
}
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the introduction instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
protected override void PushTarget(ILGenerator il)
|
||||
{
|
||||
PushAdvisedProxy(il);
|
||||
il.Emit(OpCodes.Ldfld, References.IntroductionsField);
|
||||
il.Emit(OpCodes.Ldc_I4, index);
|
||||
il.Emit(OpCodes.Ldelem_Ref);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the introduction instance on stack.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
protected override void PushTarget(ILGenerator il)
|
||||
{
|
||||
PushAdvisedProxy(il);
|
||||
il.Emit(OpCodes.Ldfld, References.IntroductionsField);
|
||||
il.Emit(OpCodes.Ldc_I4, index);
|
||||
il.Emit(OpCodes.Ldelem_Ref);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls proxied method directly.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
protected override void CallDirectProxiedMethod(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
CallDirectTargetMethod(il, interfaceMethod);
|
||||
}
|
||||
/// <summary>
|
||||
/// Calls proxied method directly.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
protected override void CallDirectProxiedMethod(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
CallDirectTargetMethod(il, interfaceMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,106 +21,105 @@
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
namespace Spring.Aop.Framework.DynamicProxy;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Proxy.IProxyMethodBuilder"/> implementation
|
||||
/// that delegates method calls to target object.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class TargetAopProxyMethodBuilder : AbstractAopProxyMethodBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Proxy.IProxyMethodBuilder"/> implementation
|
||||
/// that delegates method calls to target object.
|
||||
/// The local variable to store the target instance.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Bruno Baia</author>
|
||||
public class TargetAopProxyMethodBuilder : AbstractAopProxyMethodBuilder
|
||||
protected LocalBuilder target;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the method builder.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
/// <param name="aopProxyGenerator">
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </param>
|
||||
/// <param name="explicitImplementation">
|
||||
/// <see langword="true"/> if the interface is to be
|
||||
/// implemented explicitly; otherwise <see langword="false"/>.
|
||||
/// </param>
|
||||
/// <param name="targetMethods">
|
||||
/// The dictionary to cache the list of target
|
||||
/// <see cref="System.Reflection.MethodInfo"/>s.
|
||||
/// </param>
|
||||
public TargetAopProxyMethodBuilder(TypeBuilder typeBuilder,
|
||||
IAopProxyTypeGenerator aopProxyGenerator, bool explicitImplementation, IDictionary<string, MethodInfo> targetMethods)
|
||||
: base(typeBuilder, aopProxyGenerator, explicitImplementation, targetMethods)
|
||||
{
|
||||
/// <summary>
|
||||
/// The local variable to store the target instance.
|
||||
/// </summary>
|
||||
protected LocalBuilder target;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the method builder.
|
||||
/// </summary>
|
||||
/// <param name="typeBuilder">The type builder to use.</param>
|
||||
/// <param name="aopProxyGenerator">
|
||||
/// The <see cref="IAopProxyTypeGenerator"/> implementation to use.
|
||||
/// </param>
|
||||
/// <param name="explicitImplementation">
|
||||
/// <see langword="true"/> if the interface is to be
|
||||
/// implemented explicitly; otherwise <see langword="false"/>.
|
||||
/// </param>
|
||||
/// <param name="targetMethods">
|
||||
/// The dictionary to cache the list of target
|
||||
/// <see cref="System.Reflection.MethodInfo"/>s.
|
||||
/// </param>
|
||||
public TargetAopProxyMethodBuilder(TypeBuilder typeBuilder,
|
||||
IAopProxyTypeGenerator aopProxyGenerator, bool explicitImplementation, IDictionary<string, MethodInfo> targetMethods)
|
||||
: base(typeBuilder, aopProxyGenerator, explicitImplementation, targetMethods)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates local variable declarations.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
protected override void DeclareLocals(ILGenerator il, MethodInfo method)
|
||||
{
|
||||
base.DeclareLocals(il, method);
|
||||
target = il.DeclareLocal(typeof(object));
|
||||
/// <summary>
|
||||
/// Creates local variable declarations.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
protected override void DeclareLocals(ILGenerator il, MethodInfo method)
|
||||
{
|
||||
base.DeclareLocals(il, method);
|
||||
target = il.DeclareLocal(typeof(object));
|
||||
|
||||
#if DEBUG && !NETSTANDARD
|
||||
target.SetLocalSymInfo("target");
|
||||
target.SetLocalSymInfo("target");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the target instance on which calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
protected override void PushTarget(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldloc, target);
|
||||
}
|
||||
/// <summary>
|
||||
/// Generates the IL instructions that pushes
|
||||
/// the target instance on which calls should be delegated to.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
protected override void PushTarget(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldloc, target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates method logic.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
protected override void GenerateMethodLogic(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
PushAdvisedProxy(il);
|
||||
il.Emit(OpCodes.Ldfld, References.TargetSourceField);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetTargetMethod, null);
|
||||
il.Emit(OpCodes.Stloc, target);
|
||||
/// <summary>
|
||||
/// Generates method logic.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
protected override void GenerateMethodLogic(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
PushAdvisedProxy(il);
|
||||
il.Emit(OpCodes.Ldfld, References.TargetSourceField);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetTargetMethod, null);
|
||||
il.Emit(OpCodes.Stloc, target);
|
||||
|
||||
base.GenerateMethodLogic(il, method, interfaceMethod);
|
||||
base.GenerateMethodLogic(il, method, interfaceMethod);
|
||||
|
||||
PushAdvisedProxy(il);
|
||||
il.Emit(OpCodes.Ldfld, References.TargetSourceField);
|
||||
PushTarget(il);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetReleaseTargetMethod, null);
|
||||
}
|
||||
PushAdvisedProxy(il);
|
||||
il.Emit(OpCodes.Ldfld, References.TargetSourceField);
|
||||
PushTarget(il);
|
||||
il.EmitCall(OpCodes.Callvirt, References.GetReleaseTargetMethod, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls proxied method directly.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
protected override void CallDirectProxiedMethod(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
if (interfaceMethod != null)
|
||||
CallDirectTargetMethod(il, interfaceMethod);
|
||||
else
|
||||
CallDirectTargetMethod(il, method);
|
||||
}
|
||||
/// <summary>
|
||||
/// Calls proxied method directly.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="method">The method to proxy.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
protected override void CallDirectProxiedMethod(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
if (interfaceMethod != null)
|
||||
CallDirectTargetMethod(il, interfaceMethod);
|
||||
else
|
||||
CallDirectTargetMethod(il, method);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,89 +21,88 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.Framework.IAdvisorChainFactory"/> implementation
|
||||
/// that caches advisor chains on a per-advised-method basis.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public sealed class HashtableCachingAdvisorChainFactory : IAdvisorChainFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.Framework.IAdvisorChainFactory"/> implementation
|
||||
/// that caches advisor chains on a per-advised-method basis.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public sealed class HashtableCachingAdvisorChainFactory : IAdvisorChainFactory
|
||||
[NonSerialized] private Dictionary<MethodInfo, IList<object>> methodCache = new Dictionary<MethodInfo, IList<object>>();
|
||||
|
||||
[OnDeserializing]
|
||||
private void OnDeserializing(StreamingContext c)
|
||||
{
|
||||
[NonSerialized]
|
||||
private Dictionary<MethodInfo, IList<object>> methodCache = new Dictionary<MethodInfo, IList<object>>();
|
||||
methodCache = new Dictionary<MethodInfo, IList<object>>();
|
||||
}
|
||||
|
||||
[OnDeserializing]
|
||||
private void OnDeserializing(StreamingContext c)
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="AopAlliance.Intercept.IInterceptor"/> and
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// instances for the supplied <paramref name="proxy"/>.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration object.</param>
|
||||
/// <param name="proxy">The object proxy.</param>
|
||||
/// <param name="method">
|
||||
/// The method for which the interceptors are to be evaluated.
|
||||
/// </param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The list of <see cref="AopAlliance.Intercept.IInterceptor"/> and
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// instances for the supplied <paramref name="proxy"/>.
|
||||
/// </returns>
|
||||
public IList<object> GetInterceptors(IAdvised advised, object proxy, MethodInfo method, Type targetType)
|
||||
{
|
||||
if (!methodCache.TryGetValue(method, out var interceptors))
|
||||
{
|
||||
methodCache = new Dictionary<MethodInfo, IList<object>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="AopAlliance.Intercept.IInterceptor"/> and
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// instances for the supplied <paramref name="proxy"/>.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration object.</param>
|
||||
/// <param name="proxy">The object proxy.</param>
|
||||
/// <param name="method">
|
||||
/// The method for which the interceptors are to be evaluated.
|
||||
/// </param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The list of <see cref="AopAlliance.Intercept.IInterceptor"/> and
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// instances for the supplied <paramref name="proxy"/>.
|
||||
/// </returns>
|
||||
public IList<object> GetInterceptors(IAdvised advised, object proxy, MethodInfo method, Type targetType)
|
||||
{
|
||||
if (!methodCache.TryGetValue(method, out var interceptors))
|
||||
lock (methodCache)
|
||||
{
|
||||
lock (methodCache)
|
||||
if (!methodCache.TryGetValue(method, out interceptors))
|
||||
{
|
||||
if (!methodCache.TryGetValue(method, out interceptors))
|
||||
{
|
||||
interceptors = AdvisorChainFactoryUtils.CalculateInterceptors(advised, proxy, method, targetType);
|
||||
methodCache[method] = interceptors;
|
||||
}
|
||||
interceptors = AdvisorChainFactoryUtils.CalculateInterceptors(advised, proxy, method, targetType);
|
||||
methodCache[method] = interceptors;
|
||||
}
|
||||
}
|
||||
return interceptors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the first proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
public void Activated(AdvisedSupport source)
|
||||
{
|
||||
}
|
||||
return interceptors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when advice is changed after a proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
public void AdviceChanged(AdvisedSupport source)
|
||||
{
|
||||
methodCache.Clear();
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when the first proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
public void Activated(AdvisedSupport source)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when interfaces are changed after a proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
public void InterfacesChanged(AdvisedSupport source)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when advice is changed after a proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
public void AdviceChanged(AdvisedSupport source)
|
||||
{
|
||||
methodCache.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when interfaces are changed after a proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
public void InterfacesChanged(AdvisedSupport source)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,474 +19,472 @@
|
||||
#endregion
|
||||
|
||||
using AopAlliance.Aop;
|
||||
|
||||
using Spring.Proxy;
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration data for an AOP proxy factory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This configuration includes the
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/>s,
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>s, and (any) proxied interfaces.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Any AOP proxy obtained from Spring.NET can be cast to this interface to
|
||||
/// allow the manipulation of said proxy's AOP advice.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.Framework.AdvisedSupport"/>
|
||||
[ProxyIgnore]
|
||||
public interface IAdvised
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration data for an AOP proxy factory.
|
||||
/// Should proxies obtained from this configuration expose
|
||||
/// the AOP proxy to the
|
||||
/// <see cref="Spring.Aop.Framework.AopContext"/> class?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This configuration includes the
|
||||
/// <see cref="AopAlliance.Intercept.IInterceptor"/>s,
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>s, and (any) proxied interfaces.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Any AOP proxy obtained from Spring.NET can be cast to this interface to
|
||||
/// allow the manipulation of said proxy's AOP advice.
|
||||
/// This is useful if an advised object needs to call another advised
|
||||
/// method on itself. (If it uses the <c>this</c> reference (<c>Me</c>
|
||||
/// in Visual Basic.NET), the invocation will <b>not</b> be advised).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.Framework.AdvisedSupport"/>
|
||||
[ProxyIgnore]
|
||||
public interface IAdvised
|
||||
{
|
||||
/// <summary>
|
||||
/// Should proxies obtained from this configuration expose
|
||||
/// the AOP proxy to the
|
||||
/// <see cref="Spring.Aop.Framework.AopContext"/> class?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is useful if an advised object needs to call another advised
|
||||
/// method on itself. (If it uses the <c>this</c> reference (<c>Me</c>
|
||||
/// in Visual Basic.NET), the invocation will <b>not</b> be advised).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
bool ExposeProxy { get; }
|
||||
bool ExposeProxy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the
|
||||
/// <see cref="Spring.Aop.Framework.IAdvisorChainFactory"/>
|
||||
/// implementation that will be used to get the interceptor
|
||||
/// chains for the advised
|
||||
/// <see cref="Spring.Aop.Framework.AdvisedSupport.Target"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="Spring.Aop.Framework.IAdvisorChainFactory"/>
|
||||
/// implementation that will be used to get the interceptor
|
||||
/// chains for the advised
|
||||
/// <see cref="Spring.Aop.Framework.AdvisedSupport.Target"/>.
|
||||
/// </value>
|
||||
IAdvisorChainFactory AdvisorChainFactory { get; }
|
||||
/// <summary>
|
||||
/// Gets the
|
||||
/// <see cref="Spring.Aop.Framework.IAdvisorChainFactory"/>
|
||||
/// implementation that will be used to get the interceptor
|
||||
/// chains for the advised
|
||||
/// <see cref="Spring.Aop.Framework.AdvisedSupport.Target"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="Spring.Aop.Framework.IAdvisorChainFactory"/>
|
||||
/// implementation that will be used to get the interceptor
|
||||
/// chains for the advised
|
||||
/// <see cref="Spring.Aop.Framework.AdvisedSupport.Target"/>.
|
||||
/// </value>
|
||||
IAdvisorChainFactory AdvisorChainFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the target <see cref="System.Type"/> to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
bool ProxyTargetType { get; }
|
||||
/// <summary>
|
||||
/// Is the target <see cref="System.Type"/> to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
bool ProxyTargetType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is target type attributes, method attributes, method's return type attributes
|
||||
/// and method's parameter attributes to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
bool ProxyTargetAttributes { get; }
|
||||
/// <summary>
|
||||
/// Is target type attributes, method attributes, method's return type attributes
|
||||
/// and method's parameter attributes to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
bool ProxyTargetAttributes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the collection of <see cref="Spring.Aop.IAdvisor"/>
|
||||
/// instances that have been applied to this proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Will never return <cref lang="null"/>, but may return an
|
||||
/// empty array (in the case where no
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> instances have been applied to
|
||||
/// this proxy).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The collection of <see cref="Spring.Aop.IAdvisor"/>
|
||||
/// instances that have been applied to this proxy.
|
||||
/// </value>
|
||||
IList<IAdvisor> Advisors { get; }
|
||||
/// <summary>
|
||||
/// Returns the collection of <see cref="Spring.Aop.IAdvisor"/>
|
||||
/// instances that have been applied to this proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Will never return <cref lang="null"/>, but may return an
|
||||
/// empty array (in the case where no
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> instances have been applied to
|
||||
/// this proxy).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The collection of <see cref="Spring.Aop.IAdvisor"/>
|
||||
/// instances that have been applied to this proxy.
|
||||
/// </value>
|
||||
IList<IAdvisor> Advisors { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the collection of <see cref="Spring.Aop.IIntroductionAdvisor"/>
|
||||
/// instances that have been applied to this proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Will never return <cref lang="null"/>, but may return an
|
||||
/// empty array (in the case where no
|
||||
/// <see cref="Spring.Aop.IIntroductionAdvisor"/> instances have been
|
||||
/// applied to this proxy).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The collection of <see cref="Spring.Aop.IIntroductionAdvisor"/>
|
||||
/// instances that have been applied to this proxy.
|
||||
/// </value>
|
||||
IList<IIntroductionAdvisor> Introductions { get; }
|
||||
/// <summary>
|
||||
/// Returns the collection of <see cref="Spring.Aop.IIntroductionAdvisor"/>
|
||||
/// instances that have been applied to this proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Will never return <cref lang="null"/>, but may return an
|
||||
/// empty array (in the case where no
|
||||
/// <see cref="Spring.Aop.IIntroductionAdvisor"/> instances have been
|
||||
/// applied to this proxy).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The collection of <see cref="Spring.Aop.IIntroductionAdvisor"/>
|
||||
/// instances that have been applied to this proxy.
|
||||
/// </value>
|
||||
IList<IIntroductionAdvisor> Introductions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the collection of interface <see cref="System.Type"/>s
|
||||
/// to be (or that are being) proxied by this proxy.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The collection of interface <see cref="System.Type"/>s
|
||||
/// to be (or that are being) proxied by this proxy.
|
||||
/// </value>
|
||||
IList<Type> Interfaces { get; }
|
||||
/// <summary>
|
||||
/// Returns the collection of interface <see cref="System.Type"/>s
|
||||
/// to be (or that are being) proxied by this proxy.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The collection of interface <see cref="System.Type"/>s
|
||||
/// to be (or that are being) proxied by this proxy.
|
||||
/// </value>
|
||||
IList<Type> Interfaces { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the mapping of the proxied interface
|
||||
/// <see cref="System.Type"/>s to their delegates.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The mapping of the proxied interface
|
||||
/// <see cref="System.Type"/>s to their delegates.
|
||||
/// </value>
|
||||
IDictionary<Type, object> InterfaceMap { get; }
|
||||
/// <summary>
|
||||
/// Returns the mapping of the proxied interface
|
||||
/// <see cref="System.Type"/>s to their delegates.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The mapping of the proxied interface
|
||||
/// <see cref="System.Type"/>s to their delegates.
|
||||
/// </value>
|
||||
IDictionary<Type, object> InterfaceMap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this configuration frozen?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// When a config is frozen, no advice changes can be made. This is
|
||||
/// useful for optimization, and useful when we don't want callers
|
||||
/// to be able to manipulate configuration after casting to
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
bool IsFrozen { get; }
|
||||
/// <summary>
|
||||
/// Is this configuration frozen?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// When a config is frozen, no advice changes can be made. This is
|
||||
/// useful for optimization, and useful when we don't want callers
|
||||
/// to be able to manipulate configuration after casting to
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
bool IsFrozen { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Spring.Aop.ITargetSource"/> used by this
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised"/> object.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="Spring.Aop.ITargetSource"/> used by this
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised"/> object.
|
||||
/// </value>
|
||||
ITargetSource TargetSource { get; }
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Spring.Aop.ITargetSource"/> used by this
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised"/> object.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="Spring.Aop.ITargetSource"/> used by this
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised"/> object.
|
||||
/// </value>
|
||||
ITargetSource TargetSource { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a boolean specifying if this <see cref="IAdvised"/>
|
||||
/// instance can be serialized.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance can be serialized, <c>false</c> otherwise.
|
||||
/// </value>
|
||||
bool IsSerializable { get; }
|
||||
/// <summary>
|
||||
/// Returns a boolean specifying if this <see cref="IAdvised"/>
|
||||
/// instance can be serialized.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance can be serialized, <c>false</c> otherwise.
|
||||
/// </value>
|
||||
bool IsSerializable { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advice"/> to the end (or tail)
|
||||
/// of the advice (interceptor) chain.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Please be aware that Spring.NET's AOP implementation only supports
|
||||
/// method advice (as encapsulated by the
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInterceptor"/> interface).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to be added.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAdvised.AddAdvice(int,IAdvice)"/>
|
||||
void AddAdvice(IAdvice advice);
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advice"/> to the end (or tail)
|
||||
/// of the advice (interceptor) chain.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Please be aware that Spring.NET's AOP implementation only supports
|
||||
/// method advice (as encapsulated by the
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInterceptor"/> interface).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to be added.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAdvised.AddAdvice(int,IAdvice)"/>
|
||||
void AddAdvice(IAdvice advice);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advice"/> to the supplied
|
||||
/// <paramref name="position"/> in the advice (interceptor) chain.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Please be aware that Spring.NET's AOP implementation only supports
|
||||
/// method advice (as encapsulated by the
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInterceptor"/> interface).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="position">
|
||||
/// The zero (0) indexed position (from the head) at which the
|
||||
/// supplied <paramref name="advice"/> is to be inserted into the
|
||||
/// advice (interceptor) chain.
|
||||
/// </param>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to be added.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAdvised.AddAdvice(IAdvice)"/>
|
||||
void AddAdvice(int position, IAdvice advice);
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advice"/> to the supplied
|
||||
/// <paramref name="position"/> in the advice (interceptor) chain.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Please be aware that Spring.NET's AOP implementation only supports
|
||||
/// method advice (as encapsulated by the
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInterceptor"/> interface).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="position">
|
||||
/// The zero (0) indexed position (from the head) at which the
|
||||
/// supplied <paramref name="advice"/> is to be inserted into the
|
||||
/// advice (interceptor) chain.
|
||||
/// </param>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to be added.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAdvised.AddAdvice(IAdvice)"/>
|
||||
void AddAdvice(int position, IAdvice advice);
|
||||
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="intf"/> (interface)
|
||||
/// <see cref="System.Type"/> proxied?
|
||||
/// </summary>
|
||||
/// <param name="intf">
|
||||
/// The interface <see cref="System.Type"/> to test.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="intf"/>
|
||||
/// (interface) <see cref="System.Type"/> is proxied;
|
||||
/// <see langword="false"/> if not or the supplied
|
||||
/// <paramref name="intf"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
bool IsInterfaceProxied(Type intf);
|
||||
/// <summary>
|
||||
/// Is the supplied <paramref name="intf"/> (interface)
|
||||
/// <see cref="System.Type"/> proxied?
|
||||
/// </summary>
|
||||
/// <param name="intf">
|
||||
/// The interface <see cref="System.Type"/> to test.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="intf"/>
|
||||
/// (interface) <see cref="System.Type"/> is proxied;
|
||||
/// <see langword="false"/> if not or the supplied
|
||||
/// <paramref name="intf"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
bool IsInterfaceProxied(Type intf);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the advisors from the supplied <paramref name="advisors"/>
|
||||
/// to the list of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>.
|
||||
/// </summary>
|
||||
/// <param name="advisors">
|
||||
/// The <see cref="IAdvisors"/> to add advisors from.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="advisors"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddAdvisors(IAdvisors advisors);
|
||||
/// <summary>
|
||||
/// Adds the advisors from the supplied <paramref name="advisors"/>
|
||||
/// to the list of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>.
|
||||
/// </summary>
|
||||
/// <param name="advisors">
|
||||
/// The <see cref="IAdvisors"/> to add advisors from.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="advisors"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddAdvisors(IAdvisors advisors);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advisor"/> to the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>.
|
||||
/// </summary>
|
||||
/// <param name="advisor">
|
||||
/// The <see cref="Spring.Aop.IAdvisor"/> to add.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="advisor"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddAdvisor(IAdvisor advisor);
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advisor"/> to the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>.
|
||||
/// </summary>
|
||||
/// <param name="advisor">
|
||||
/// The <see cref="Spring.Aop.IAdvisor"/> to add.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="advisor"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddAdvisor(IAdvisor advisor);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advisor"/> to the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The index in the <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>
|
||||
/// list at which the supplied <paramref name="advisor"/>
|
||||
/// is to be inserted.
|
||||
/// </param>
|
||||
/// <param name="advisor">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to add.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="advisor"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddAdvisor(int index, IAdvisor advisor);
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="advisor"/> to the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The index in the <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>
|
||||
/// list at which the supplied <paramref name="advisor"/>
|
||||
/// is to be inserted.
|
||||
/// </param>
|
||||
/// <param name="advisor">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to add.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="advisor"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddAdvisor(int index, IAdvisor advisor);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="introductionAdvisor"/> to the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>.
|
||||
/// </summary>
|
||||
/// <param name="introductionAdvisor">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to add.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="introductionAdvisor"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddIntroduction(IIntroductionAdvisor introductionAdvisor);
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="introductionAdvisor"/> to the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>.
|
||||
/// </summary>
|
||||
/// <param name="introductionAdvisor">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to add.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="introductionAdvisor"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddIntroduction(IIntroductionAdvisor introductionAdvisor);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="introductionAdvisor"/> to the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The index in the <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// list at which the supplied <paramref name="introductionAdvisor"/>
|
||||
/// is to be inserted.
|
||||
/// </param>
|
||||
/// <param name="introductionAdvisor">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to add.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="introductionAdvisor"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddIntroduction(int index, IIntroductionAdvisor introductionAdvisor);
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="introductionAdvisor"/> to the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The index in the <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// list at which the supplied <paramref name="introductionAdvisor"/>
|
||||
/// is to be inserted.
|
||||
/// </param>
|
||||
/// <param name="introductionAdvisor">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to add.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="introductionAdvisor"/> cannot be added.
|
||||
/// </exception>
|
||||
void AddIntroduction(int index, IIntroductionAdvisor introductionAdvisor);
|
||||
|
||||
/// <summary>
|
||||
/// Return the index (0 based) of the supplied
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> in the interceptor
|
||||
/// (advice) chain for this proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The return value of this method can be used to index into
|
||||
/// the <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>
|
||||
/// list.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">
|
||||
/// The <see cref="Spring.Aop.IAdvisor"/> to search for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The zero (0) based index of this advisor, or -1 if the
|
||||
/// supplied <paramref name="advisor"/> is not an advisor for this
|
||||
/// proxy.
|
||||
/// </returns>
|
||||
int IndexOf(IAdvisor advisor);
|
||||
/// <summary>
|
||||
/// Return the index (0 based) of the supplied
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> in the interceptor
|
||||
/// (advice) chain for this proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The return value of this method can be used to index into
|
||||
/// the <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>
|
||||
/// list.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">
|
||||
/// The <see cref="Spring.Aop.IAdvisor"/> to search for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The zero (0) based index of this advisor, or -1 if the
|
||||
/// supplied <paramref name="advisor"/> is not an advisor for this
|
||||
/// proxy.
|
||||
/// </returns>
|
||||
int IndexOf(IAdvisor advisor);
|
||||
|
||||
/// <summary>
|
||||
/// Return the index (0 based) of the supplied
|
||||
/// <see cref="Spring.Aop.IIntroductionAdvisor"/> in the introductions
|
||||
/// for this proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The return value of this method can be used to index into
|
||||
/// the <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// list.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to search for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The zero (0) based index of this advisor, or -1 if the
|
||||
/// supplied <paramref name="advisor"/> is not an introduction advisor
|
||||
/// for this proxy.
|
||||
/// </returns>
|
||||
int IndexOf(IIntroductionAdvisor advisor);
|
||||
/// <summary>
|
||||
/// Return the index (0 based) of the supplied
|
||||
/// <see cref="Spring.Aop.IIntroductionAdvisor"/> in the introductions
|
||||
/// for this proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The return value of this method can be used to index into
|
||||
/// the <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// list.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to search for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The zero (0) based index of this advisor, or -1 if the
|
||||
/// supplied <paramref name="advisor"/> is not an introduction advisor
|
||||
/// for this proxy.
|
||||
/// </returns>
|
||||
int IndexOf(IIntroductionAdvisor advisor);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the supplied <paramref name="advisor"/> the list of advisors
|
||||
/// for this proxy.
|
||||
/// </summary>
|
||||
/// <param name="advisor">The advisor to remove.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if advisor was found in the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Advisors"/> for this
|
||||
/// proxy and was successfully removed; <see langword="false"/> if not
|
||||
/// or if the supplied <paramref name="advisor"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="advisor"/> cannot be removed.
|
||||
/// </exception>
|
||||
bool RemoveAdvisor(IAdvisor advisor);
|
||||
/// <summary>
|
||||
/// Removes the supplied <paramref name="advisor"/> the list of advisors
|
||||
/// for this proxy.
|
||||
/// </summary>
|
||||
/// <param name="advisor">The advisor to remove.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if advisor was found in the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Advisors"/> for this
|
||||
/// proxy and was successfully removed; <see langword="false"/> if not
|
||||
/// or if the supplied <paramref name="advisor"/> is <cref lang="null"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="advisor"/> cannot be removed.
|
||||
/// </exception>
|
||||
bool RemoveAdvisor(IAdvisor advisor);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="Spring.Aop.IAdvisor"/> at the supplied
|
||||
/// <paramref name="index"/> in the
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Advisors"/> list
|
||||
/// from the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Advisors"/> for this proxy.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The index of the <see cref="Spring.Aop.IAdvisor"/> to remove.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> at the supplied <paramref name="index"/>
|
||||
/// cannot be removed; or if the supplied <paramref name="index"/> is out of
|
||||
/// range.
|
||||
/// </exception>
|
||||
void RemoveAdvisor(int index);
|
||||
/// <summary>
|
||||
/// Removes the <see cref="Spring.Aop.IAdvisor"/> at the supplied
|
||||
/// <paramref name="index"/> in the
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Advisors"/> list
|
||||
/// from the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Advisors"/> for this proxy.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The index of the <see cref="Spring.Aop.IAdvisor"/> to remove.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <see cref="Spring.Aop.IAdvisor"/> at the supplied <paramref name="index"/>
|
||||
/// cannot be removed; or if the supplied <paramref name="index"/> is out of
|
||||
/// range.
|
||||
/// </exception>
|
||||
void RemoveAdvisor(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the supplied <paramref name="advice"/> from the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to remove.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="advice"/> was
|
||||
/// found in the list of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>
|
||||
/// and successfully removed.
|
||||
/// </returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <see cref="AopAlliance.Aop.IAdvice"/> cannot be removed.
|
||||
/// </exception>
|
||||
bool RemoveAdvice(IAdvice advice);
|
||||
/// <summary>
|
||||
/// Removes the supplied <paramref name="advice"/> from the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The <see cref="AopAlliance.Aop.IAdvice"/> to remove.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="advice"/> was
|
||||
/// found in the list of <see cref="Spring.Aop.Framework.IAdvised.Advisors"/>
|
||||
/// and successfully removed.
|
||||
/// </returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <see cref="AopAlliance.Aop.IAdvice"/> cannot be removed.
|
||||
/// </exception>
|
||||
bool RemoveAdvice(IAdvice advice);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the supplied <paramref name="introduction"/> from the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>.
|
||||
/// </summary>
|
||||
/// <param name="introduction">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to remove.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="introduction"/> was
|
||||
/// found in the list of <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// and successfully removed.
|
||||
/// </returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <see cref="Spring.Aop.IIntroductionAdvisor"/> cannot be removed.
|
||||
/// </exception>
|
||||
bool RemoveIntroduction(IIntroductionAdvisor introduction);
|
||||
/// <summary>
|
||||
/// Removes the supplied <paramref name="introduction"/> from the list
|
||||
/// of <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>.
|
||||
/// </summary>
|
||||
/// <param name="introduction">
|
||||
/// The <see cref="Spring.Aop.IIntroductionAdvisor"/> to remove.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the supplied <paramref name="introduction"/> was
|
||||
/// found in the list of <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// and successfully removed.
|
||||
/// </returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <see cref="Spring.Aop.IIntroductionAdvisor"/> cannot be removed.
|
||||
/// </exception>
|
||||
bool RemoveIntroduction(IIntroductionAdvisor introduction);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the <see cref="Spring.Aop.IIntroductionAdvisor"/> at the supplied
|
||||
/// <paramref name="index"/> in the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Introductions"/> for this proxy.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the advisor to remove.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <see cref="Spring.Aop.IIntroductionAdvisor"/> at the supplied
|
||||
/// <paramref name="index"/> cannot be removed; or if the supplied
|
||||
/// <paramref name="index"/> is out of range.
|
||||
/// </exception>
|
||||
void RemoveIntroduction(int index);
|
||||
/// <summary>
|
||||
/// Removes the <see cref="Spring.Aop.IIntroductionAdvisor"/> at the supplied
|
||||
/// <paramref name="index"/> in the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Introductions"/> for this proxy.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the advisor to remove.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <see cref="Spring.Aop.IIntroductionAdvisor"/> at the supplied
|
||||
/// <paramref name="index"/> cannot be removed; or if the supplied
|
||||
/// <paramref name="index"/> is out of range.
|
||||
/// </exception>
|
||||
void RemoveIntroduction(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the <see cref="Spring.Aop.IIntroductionAdvisor"/> that
|
||||
/// exists at the supplied <paramref name="index"/> in the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// with the supplied <paramref name="introduction"/>.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The index of the <see cref="Spring.Aop.IIntroductionAdvisor"/>
|
||||
/// in the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// that is to be replaced.
|
||||
/// </param>
|
||||
/// <param name="introduction">
|
||||
/// The new (replacement) <see cref="Spring.Aop.IIntroductionAdvisor"/>.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the supplied <paramref name="index"/> is out of range.
|
||||
/// </exception>
|
||||
void ReplaceIntroduction(int index, IIntroductionAdvisor introduction);
|
||||
/// <summary>
|
||||
/// Replaces the <see cref="Spring.Aop.IIntroductionAdvisor"/> that
|
||||
/// exists at the supplied <paramref name="index"/> in the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// with the supplied <paramref name="introduction"/>.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The index of the <see cref="Spring.Aop.IIntroductionAdvisor"/>
|
||||
/// in the list of
|
||||
/// <see cref="Spring.Aop.Framework.IAdvised.Introductions"/>
|
||||
/// that is to be replaced.
|
||||
/// </param>
|
||||
/// <param name="introduction">
|
||||
/// The new (replacement) <see cref="Spring.Aop.IIntroductionAdvisor"/>.
|
||||
/// </param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the supplied <paramref name="index"/> is out of range.
|
||||
/// </exception>
|
||||
void ReplaceIntroduction(int index, IIntroductionAdvisor introduction);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the <paramref name="oldAdvisor"/> with the
|
||||
/// <paramref name="newAdvisor"/>.
|
||||
/// </summary>
|
||||
/// <param name="oldAdvisor">
|
||||
/// The original (old) advisor to be replaced.
|
||||
/// </param>
|
||||
/// <param name="newAdvisor">
|
||||
/// The new advisor to replace the <paramref name="oldAdvisor"/> with.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the <paramref name="oldAdvisor"/> was
|
||||
/// replaced; if the <paramref name="oldAdvisor"/> was not found in the
|
||||
/// advisors collection, this method returns <see langword="false"/>
|
||||
/// and (effectively) does nothing.
|
||||
/// </returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="oldAdvisor"/> cannot be replaced.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.Framework.ProxyConfig.IsFrozen"/>
|
||||
bool ReplaceAdvisor(IAdvisor oldAdvisor, IAdvisor newAdvisor);
|
||||
/// <summary>
|
||||
/// Replaces the <paramref name="oldAdvisor"/> with the
|
||||
/// <paramref name="newAdvisor"/>.
|
||||
/// </summary>
|
||||
/// <param name="oldAdvisor">
|
||||
/// The original (old) advisor to be replaced.
|
||||
/// </param>
|
||||
/// <param name="newAdvisor">
|
||||
/// The new advisor to replace the <paramref name="oldAdvisor"/> with.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the <paramref name="oldAdvisor"/> was
|
||||
/// replaced; if the <paramref name="oldAdvisor"/> was not found in the
|
||||
/// advisors collection, this method returns <see langword="false"/>
|
||||
/// and (effectively) does nothing.
|
||||
/// </returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If this proxy configuration is frozen and the
|
||||
/// <paramref name="oldAdvisor"/> cannot be replaced.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.Framework.ProxyConfig.IsFrozen"/>
|
||||
bool ReplaceAdvisor(IAdvisor oldAdvisor, IAdvisor newAdvisor);
|
||||
|
||||
/// <summary>
|
||||
/// As <see cref="System.Object.ToString()"/> will normally be passed
|
||||
/// straight through to the advised target, this method returns the
|
||||
/// <see cref="System.Object.ToString()"/> equivalent for the AOP
|
||||
/// proxy itself.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> description of the proxy configuration.
|
||||
/// </returns>
|
||||
string ToProxyConfigString();
|
||||
}
|
||||
/// <summary>
|
||||
/// As <see cref="System.Object.ToString()"/> will normally be passed
|
||||
/// straight through to the advised target, this method returns the
|
||||
/// <see cref="System.Object.ToString()"/> equivalent for the AOP
|
||||
/// proxy itself.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> description of the proxy configuration.
|
||||
/// </returns>
|
||||
string ToProxyConfigString();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -18,46 +18,45 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Callback interface for
|
||||
/// <see cref="Spring.Aop.Framework.AdvisedSupport"/> listeners.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Allows <see cref="Spring.Aop.Framework.IAdvisedSupportListener"/>
|
||||
/// implementations to be notified of notable lifecycle events relating
|
||||
/// to the creation of a proxy, and changes to the configuration data of a
|
||||
/// proxy.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisedSupportListener
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback interface for
|
||||
/// <see cref="Spring.Aop.Framework.AdvisedSupport"/> listeners.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Allows <see cref="Spring.Aop.Framework.IAdvisedSupportListener"/>
|
||||
/// implementations to be notified of notable lifecycle events relating
|
||||
/// to the creation of a proxy, and changes to the configuration data of a
|
||||
/// proxy.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisedSupportListener
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when the first proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
void Activated(AdvisedSupport source);
|
||||
/// <summary>
|
||||
/// Invoked when the first proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
void Activated(AdvisedSupport source);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when advice is changed after a proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
void AdviceChanged(AdvisedSupport source);
|
||||
/// <summary>
|
||||
/// Invoked when advice is changed after a proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
void AdviceChanged(AdvisedSupport source);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when interfaces are changed after a proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
void InterfacesChanged(AdvisedSupport source);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when interfaces are changed after a proxy is created.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The relevant <see cref="Spring.Aop.Framework.AdvisedSupport"/> source.
|
||||
/// </param>
|
||||
void InterfacesChanged(AdvisedSupport source);
|
||||
}
|
||||
|
||||
@@ -24,33 +24,32 @@ using System.Reflection;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Factory interface for advisor chains.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisorChainFactory : IAdvisedSupportListener
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory interface for advisor chains.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisorChainFactory : IAdvisedSupportListener
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="AopAlliance.Intercept.IInterceptor"/> and
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// instances for the supplied <paramref name="proxy"/>.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration object.</param>
|
||||
/// <param name="proxy">The object proxy.</param>
|
||||
/// <param name="method">
|
||||
/// The method for which the interceptors are to be evaluated.
|
||||
/// </param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The list of <see cref="AopAlliance.Intercept.IInterceptor"/> and
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// instances for the supplied <paramref name="proxy"/>.
|
||||
/// </returns>
|
||||
IList<object> GetInterceptors(IAdvised advised, object proxy, MethodInfo method, Type targetType);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="AopAlliance.Intercept.IInterceptor"/> and
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// instances for the supplied <paramref name="proxy"/>.
|
||||
/// </summary>
|
||||
/// <param name="advised">The proxy configuration object.</param>
|
||||
/// <param name="proxy">The object proxy.</param>
|
||||
/// <param name="method">
|
||||
/// The method for which the interceptors are to be evaluated.
|
||||
/// </param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The list of <see cref="AopAlliance.Intercept.IInterceptor"/> and
|
||||
/// <see cref="Spring.Aop.Framework.InterceptorAndDynamicMethodMatcher"/>
|
||||
/// instances for the supplied <paramref name="proxy"/>.
|
||||
/// </returns>
|
||||
IList<object> GetInterceptors(IAdvised advised, object proxy, MethodInfo method, Type targetType);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -24,19 +24,18 @@ using Spring.Proxy;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// The central interface for Spring.NET based AOP proxies.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[ProxyIgnore]
|
||||
public interface IAopProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// The central interface for Spring.NET based AOP proxies.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[ProxyIgnore]
|
||||
public interface IAopProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new proxy object.
|
||||
/// </summary>
|
||||
object GetProxy();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new proxy object.
|
||||
/// </summary>
|
||||
object GetProxy();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -18,27 +18,26 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Factory interface for the creation of AOP proxies based on
|
||||
/// <see cref="Spring.Aop.Framework.AdvisedSupport"/> configuration
|
||||
/// objects.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAopProxyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory interface for the creation of AOP proxies based on
|
||||
/// <see cref="Spring.Aop.Framework.AdvisedSupport"/> configuration
|
||||
/// objects.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAopProxyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="Spring.Aop.Framework.IAopProxy"/> for the
|
||||
/// supplied <paramref name="advisedSupport"/> configuration.
|
||||
/// </summary>
|
||||
/// <param name="advisedSupport">The AOP configuration.</param>
|
||||
/// <returns>An <see cref="Spring.Aop.Framework.IAopProxy"/>.</returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the supplied <paramref name="advisedSupport"/> configuration is
|
||||
/// invalid.
|
||||
/// </exception>
|
||||
IAopProxy CreateAopProxy(AdvisedSupport advisedSupport);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates an <see cref="Spring.Aop.Framework.IAopProxy"/> for the
|
||||
/// supplied <paramref name="advisedSupport"/> configuration.
|
||||
/// </summary>
|
||||
/// <param name="advisedSupport">The AOP configuration.</param>
|
||||
/// <returns>An <see cref="Spring.Aop.Framework.IAopProxy"/>.</returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the supplied <paramref name="advisedSupport"/> configuration is
|
||||
/// invalid.
|
||||
/// </exception>
|
||||
IAopProxy CreateAopProxy(AdvisedSupport advisedSupport);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -18,26 +18,25 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to the target object of an AOP proxy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// To be implemented by introduction aspects in order to obtain access to
|
||||
/// the target object.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
public interface ITargetAware
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to the target object of an AOP proxy.
|
||||
/// Sets the <see cref="Spring.Aop.Framework.IAopProxy"/> target object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// To be implemented by introduction aspects in order to obtain access to
|
||||
/// the target object.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
public interface ITargetAware
|
||||
IAopProxy TargetProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the <see cref="Spring.Aop.Framework.IAopProxy"/> target object.
|
||||
/// </summary>
|
||||
IAopProxy TargetProxy
|
||||
{
|
||||
set;
|
||||
}
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,26 +20,24 @@
|
||||
|
||||
using AopAlliance.Intercept;
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary> Internal framework class.
|
||||
/// This class is required because if we put an interceptor that implements IInterceptionAdvice
|
||||
/// in the interceptor list passed to MethodInvocation, it may be mistaken for an
|
||||
/// advice that requires dynamic method matching.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.Net)</author>
|
||||
[Serializable]
|
||||
internal class InterceptorAndDynamicMethodMatcher
|
||||
{
|
||||
|
||||
/// <summary> Internal framework class.
|
||||
/// This class is required because if we put an interceptor that implements IInterceptionAdvice
|
||||
/// in the interceptor list passed to MethodInvocation, it may be mistaken for an
|
||||
/// advice that requires dynamic method matching.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.Net)</author>
|
||||
[Serializable]
|
||||
internal class InterceptorAndDynamicMethodMatcher
|
||||
{
|
||||
internal IMethodMatcher MethodMatcher;
|
||||
internal IMethodInterceptor Interceptor;
|
||||
|
||||
public InterceptorAndDynamicMethodMatcher(IMethodInterceptor interceptor, IMethodMatcher methodMatcher)
|
||||
{
|
||||
this.Interceptor = interceptor;
|
||||
this.MethodMatcher = methodMatcher;
|
||||
}
|
||||
}
|
||||
internal IMethodMatcher MethodMatcher;
|
||||
internal IMethodInterceptor Interceptor;
|
||||
|
||||
public InterceptorAndDynamicMethodMatcher(IMethodInterceptor interceptor, IMethodMatcher methodMatcher)
|
||||
{
|
||||
this.Interceptor = interceptor;
|
||||
this.MethodMatcher = methodMatcher;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,222 +16,220 @@
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
using Spring.Util;
|
||||
using Spring.Reflection.Dynamic;
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Convenience superclass for configuration used in creating proxies,
|
||||
/// to ensure that all proxy creators have consistent properties.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Note that it is no longer possible to configure subclasses to
|
||||
/// expose the <see cref="AopAlliance.Intercept.IMethodInvocation"/>.
|
||||
/// Interceptors should normally manage their own thread locals if they
|
||||
/// need to make resources available to advised objects. If it is
|
||||
/// absolutely necessary to expose the
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInvocation"/>, use an
|
||||
/// interceptor to do so.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class ProxyConfig : ISerializable
|
||||
{
|
||||
/// <summary>
|
||||
/// Convenience superclass for configuration used in creating proxies,
|
||||
/// to ensure that all proxy creators have consistent properties.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Note that it is no longer possible to configure subclasses to
|
||||
/// expose the <see cref="AopAlliance.Intercept.IMethodInvocation"/>.
|
||||
/// Interceptors should normally manage their own thread locals if they
|
||||
/// need to make resources available to advised objects. If it is
|
||||
/// absolutely necessary to expose the
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInvocation"/>, use an
|
||||
/// interceptor to do so.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class ProxyConfig : ISerializable
|
||||
private static readonly IDynamicConstructor cachedAopProxyFactoryDynCtor =
|
||||
new SafeConstructor(typeof(ProxyConfig).Assembly.GetType("Spring.Aop.Framework.DynamicProxy.CachedAopProxyFactory", false, false).GetConstructor(Type.EmptyTypes));
|
||||
|
||||
private bool proxyTargetType;
|
||||
private bool proxyTargetAttributes = true;
|
||||
private bool optimize;
|
||||
private bool frozen;
|
||||
|
||||
private IAopProxyFactory aopProxyFactory = cachedAopProxyFactoryDynCtor.Invoke(ObjectUtils.EmptyObjects) as IAopProxyFactory;
|
||||
|
||||
private bool exposeProxy;
|
||||
private readonly object syncRoot = new object();
|
||||
|
||||
/// <inheritdoc />
|
||||
public ProxyConfig()
|
||||
{
|
||||
private static readonly IDynamicConstructor cachedAopProxyFactoryDynCtor =
|
||||
new SafeConstructor(typeof(ProxyConfig).Assembly.GetType("Spring.Aop.Framework.DynamicProxy.CachedAopProxyFactory", false, false).GetConstructor(Type.EmptyTypes));
|
||||
}
|
||||
|
||||
private bool proxyTargetType;
|
||||
private bool proxyTargetAttributes = true;
|
||||
private bool optimize;
|
||||
private bool frozen;
|
||||
/// <inheritdoc />
|
||||
protected ProxyConfig(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
proxyTargetType = info.GetBoolean("proxyTargetType");
|
||||
proxyTargetAttributes = info.GetBoolean("proxyTargetAttributes");
|
||||
optimize = info.GetBoolean("optimize");
|
||||
frozen = info.GetBoolean("frozen");
|
||||
exposeProxy = info.GetBoolean("exposeProxy");
|
||||
syncRoot = info.GetValue("syncRoot", typeof(object));
|
||||
}
|
||||
|
||||
private IAopProxyFactory aopProxyFactory = cachedAopProxyFactoryDynCtor.Invoke(ObjectUtils.EmptyObjects) as IAopProxyFactory;
|
||||
/// <inheritdoc />
|
||||
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("proxyTargetType", proxyTargetType);
|
||||
info.AddValue("proxyTargetAttributes", proxyTargetAttributes);
|
||||
info.AddValue("optimize", optimize);
|
||||
info.AddValue("frozen", frozen);
|
||||
info.AddValue("exposeProxy", exposeProxy);
|
||||
info.AddValue("syncRoot", syncRoot);
|
||||
}
|
||||
|
||||
private bool exposeProxy;
|
||||
private readonly object syncRoot = new object();
|
||||
/// <summary>
|
||||
/// Use to synchronize access to this ProxyConfig instance
|
||||
/// </summary>
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return syncRoot; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ProxyConfig()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Is the target <see cref="System.Type"/> to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
public virtual bool ProxyTargetType
|
||||
{
|
||||
get { return this.proxyTargetType; }
|
||||
set { this.proxyTargetType = value; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected ProxyConfig(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
proxyTargetType = info.GetBoolean("proxyTargetType");
|
||||
proxyTargetAttributes = info.GetBoolean("proxyTargetAttributes");
|
||||
optimize = info.GetBoolean("optimize");
|
||||
frozen = info.GetBoolean("frozen");
|
||||
exposeProxy = info.GetBoolean("exposeProxy");
|
||||
syncRoot = info.GetValue("syncRoot", typeof(object));
|
||||
}
|
||||
/// <summary>
|
||||
/// Is target type attributes, method attributes, method's return type attributes
|
||||
/// and method's parameter attributes to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
public virtual bool ProxyTargetAttributes
|
||||
{
|
||||
get { return this.proxyTargetAttributes; }
|
||||
set { this.proxyTargetAttributes = value; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("proxyTargetType", proxyTargetType);
|
||||
info.AddValue("proxyTargetAttributes", proxyTargetAttributes);
|
||||
info.AddValue("optimize", optimize);
|
||||
info.AddValue("frozen", frozen);
|
||||
info.AddValue("exposeProxy", exposeProxy);
|
||||
info.AddValue("syncRoot", syncRoot);
|
||||
}
|
||||
/// <summary>
|
||||
/// Are any <i>agressive optimizations</i> to be performed?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The exact meaning of <i>agressive optimizations</i> will differ
|
||||
/// between proxies, but there is usually some tradeoff.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// For example, optimization will usually mean that advice changes
|
||||
/// won't take effect after a proxy has been created. For this reason,
|
||||
/// optimization is disabled by default. An optimize value of
|
||||
/// <see langword="true"/> may be ignored if other settings preclude
|
||||
/// optimization: for example, if the
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/> property
|
||||
/// is set to <see langword="true"/> and such a value is not compatible
|
||||
/// with the optimization.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// The default is <see langword="false"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual bool Optimize
|
||||
{
|
||||
get { return this.optimize; }
|
||||
set { this.optimize = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use to synchronize access to this ProxyConfig instance
|
||||
/// </summary>
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return syncRoot; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Should proxies obtained from this configuration expose
|
||||
/// the AOP proxy to the
|
||||
/// <see cref="Spring.Aop.Framework.AopContext"/> class?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default is <see langword="false"/>, as enabling this property
|
||||
/// may impair performance.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public bool ExposeProxy
|
||||
{
|
||||
get { return this.exposeProxy; }
|
||||
set { this.exposeProxy = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the target <see cref="System.Type"/> to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
public virtual bool ProxyTargetType
|
||||
{
|
||||
get { return this.proxyTargetType; }
|
||||
set { this.proxyTargetType = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets and set the factory to be used to create AOP proxies.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This obviously allows one to customise the
|
||||
/// <see cref="Spring.Aop.Framework.IAopProxyFactory"/> implementation,
|
||||
/// allowing different strategies to be dropped in without changing the
|
||||
/// core framework. For example, an
|
||||
/// <see cref="Spring.Aop.Framework.IAopProxyFactory"/> implementation
|
||||
/// could return an <see cref="Spring.Aop.Framework.IAopProxy"/>
|
||||
/// using remoting proxies, <c>Reflection.Emit</c> or a code generation
|
||||
/// strategy.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual IAopProxyFactory AopProxyFactory
|
||||
{
|
||||
get { return this.aopProxyFactory; }
|
||||
set { this.aopProxyFactory = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is target type attributes, method attributes, method's return type attributes
|
||||
/// and method's parameter attributes to be proxied in addition
|
||||
/// to any interfaces declared on the proxied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
public virtual bool ProxyTargetAttributes
|
||||
{
|
||||
get { return this.proxyTargetAttributes; }
|
||||
set { this.proxyTargetAttributes = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Is this configuration frozen?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default is not frozen.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual bool IsFrozen
|
||||
{
|
||||
get { return this.frozen; }
|
||||
set { this.frozen = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Are any <i>agressive optimizations</i> to be performed?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The exact meaning of <i>agressive optimizations</i> will differ
|
||||
/// between proxies, but there is usually some tradeoff.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// For example, optimization will usually mean that advice changes
|
||||
/// won't take effect after a proxy has been created. For this reason,
|
||||
/// optimization is disabled by default. An optimize value of
|
||||
/// <see langword="true"/> may be ignored if other settings preclude
|
||||
/// optimization: for example, if the
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig.ExposeProxy"/> property
|
||||
/// is set to <see langword="true"/> and such a value is not compatible
|
||||
/// with the optimization.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// The default is <see langword="false"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual bool Optimize
|
||||
{
|
||||
get { return this.optimize; }
|
||||
set { this.optimize = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Copies the configuration from the supplied
|
||||
/// <paramref name="otherConfiguration"/> into this instance.
|
||||
/// </summary>
|
||||
/// <param name="otherConfiguration">
|
||||
/// The configuration to be copied.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="otherConfiguration"/> is
|
||||
/// <see langword="null"/>.
|
||||
/// </exception>
|
||||
public virtual void CopyFrom(ProxyConfig otherConfiguration)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(otherConfiguration, "otherConfiguration");
|
||||
|
||||
/// <summary>
|
||||
/// Should proxies obtained from this configuration expose
|
||||
/// the AOP proxy to the
|
||||
/// <see cref="Spring.Aop.Framework.AopContext"/> class?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default is <see langword="false"/>, as enabling this property
|
||||
/// may impair performance.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public bool ExposeProxy
|
||||
{
|
||||
get { return this.exposeProxy; }
|
||||
set { this.exposeProxy = value; }
|
||||
}
|
||||
this.optimize = otherConfiguration.optimize;
|
||||
this.proxyTargetType = otherConfiguration.proxyTargetType;
|
||||
this.proxyTargetAttributes = otherConfiguration.proxyTargetAttributes;
|
||||
this.exposeProxy = otherConfiguration.exposeProxy;
|
||||
this.frozen = otherConfiguration.frozen;
|
||||
this.aopProxyFactory = otherConfiguration.aopProxyFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and set the factory to be used to create AOP proxies.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This obviously allows one to customise the
|
||||
/// <see cref="Spring.Aop.Framework.IAopProxyFactory"/> implementation,
|
||||
/// allowing different strategies to be dropped in without changing the
|
||||
/// core framework. For example, an
|
||||
/// <see cref="Spring.Aop.Framework.IAopProxyFactory"/> implementation
|
||||
/// could return an <see cref="Spring.Aop.Framework.IAopProxy"/>
|
||||
/// using remoting proxies, <c>Reflection.Emit</c> or a code generation
|
||||
/// strategy.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual IAopProxyFactory AopProxyFactory
|
||||
{
|
||||
get { return this.aopProxyFactory; }
|
||||
set { this.aopProxyFactory = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this configuration frozen?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default is not frozen.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual bool IsFrozen
|
||||
{
|
||||
get { return this.frozen; }
|
||||
set { this.frozen = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the configuration from the supplied
|
||||
/// <paramref name="otherConfiguration"/> into this instance.
|
||||
/// </summary>
|
||||
/// <param name="otherConfiguration">
|
||||
/// The configuration to be copied.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="otherConfiguration"/> is
|
||||
/// <see langword="null"/>.
|
||||
/// </exception>
|
||||
public virtual void CopyFrom(ProxyConfig otherConfiguration)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(otherConfiguration, "otherConfiguration");
|
||||
|
||||
this.optimize = otherConfiguration.optimize;
|
||||
this.proxyTargetType = otherConfiguration.proxyTargetType;
|
||||
this.proxyTargetAttributes = otherConfiguration.proxyTargetAttributes;
|
||||
this.exposeProxy = otherConfiguration.exposeProxy;
|
||||
this.frozen = otherConfiguration.frozen;
|
||||
this.aopProxyFactory = otherConfiguration.aopProxyFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="System.String"/> that represents the current
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig"/> configuration.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents the current
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig"/> configuration.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("proxyTargetType=" + ProxyTargetType + "; ");
|
||||
buffer.Append("proxyTargetAttributes=" + ProxyTargetAttributes + "; ");
|
||||
buffer.Append("exposeProxy=" + ExposeProxy + "; ");
|
||||
buffer.Append("isFrozen=" + IsFrozen + "; ");
|
||||
buffer.Append("optimize=" + Optimize + "; ");
|
||||
buffer.Append("aopProxyFactory=" + AopProxyFactory.GetType().FullName + "; ");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// A <see cref="System.String"/> that represents the current
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig"/> configuration.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents the current
|
||||
/// <see cref="Spring.Aop.Framework.ProxyConfig"/> configuration.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("proxyTargetType=" + ProxyTargetType + "; ");
|
||||
buffer.Append("proxyTargetAttributes=" + ProxyTargetAttributes + "; ");
|
||||
buffer.Append("exposeProxy=" + ExposeProxy + "; ");
|
||||
buffer.Append("isFrozen=" + IsFrozen + "; ");
|
||||
buffer.Append("optimize=" + Optimize + "; ");
|
||||
buffer.Append("aopProxyFactory=" + AopProxyFactory.GetType().FullName + "; ");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,144 +19,141 @@
|
||||
#endregion
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using AopAlliance.Intercept;
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Factory for AOP proxies for programmatic use, rather than via a
|
||||
/// Spring.NET IoC container.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This class provides a simple way of obtaining and configuring AOP
|
||||
/// proxies in code.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class ProxyFactory : AdvisedSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory for AOP proxies for programmatic use, rather than via a
|
||||
/// Spring.NET IoC container.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This class provides a simple way of obtaining and configuring AOP
|
||||
/// proxies in code.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class ProxyFactory : AdvisedSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Spring.Aop.Framework.ProxyFactory"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
public ProxyFactory()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Spring.Aop.Framework.ProxyFactory"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
public ProxyFactory()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Spring.Aop.Framework.ProxyFactory"/>
|
||||
/// class that proxys all of the interfaces exposed by the supplied
|
||||
/// <paramref name="target"/>.
|
||||
/// </summary>
|
||||
/// <param name="target">The object to proxy.</param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the <paramref name="target"/> is <cref lang="null"/>.
|
||||
/// </exception>
|
||||
public ProxyFactory(object target) : base(target)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Spring.Aop.Framework.ProxyFactory"/>
|
||||
/// class that proxys all of the interfaces exposed by the supplied
|
||||
/// <paramref name="target"/>.
|
||||
/// </summary>
|
||||
/// <param name="target">The object to proxy.</param>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the <paramref name="target"/> is <cref lang="null"/>.
|
||||
/// </exception>
|
||||
public ProxyFactory(object target) : base(target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Spring.Aop.Framework.ProxyFactory"/>
|
||||
/// class that has no target object, only interfaces.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Interceptors must be added if this factory is to do anything useful.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="interfaces">The interfaces to implement.</param>
|
||||
public ProxyFactory(Type[] interfaces) : base(interfaces)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Spring.Aop.Framework.ProxyFactory"/>
|
||||
/// class that has no target object, only interfaces.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Interceptors must be added if this factory is to do anything useful.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="interfaces">The interfaces to implement.</param>
|
||||
public ProxyFactory(Type[] interfaces) : base(interfaces)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ProxyFactory"/> class for the
|
||||
/// given interface and interceptor.
|
||||
/// </summary>
|
||||
/// <remarks>Convenience method for creating a proxy for a single interceptor
|
||||
/// , assuming that the interceptor handles all calls itself rather than delegating
|
||||
/// to a target, like in the case of remoting proxies.</remarks>
|
||||
/// <param name="proxyInterface">The interface that the proxy should implement.</param>
|
||||
/// <param name="interceptor">The interceptor that the proxy should invoke.</param>
|
||||
public ProxyFactory(Type proxyInterface, IInterceptor interceptor)
|
||||
{
|
||||
AddInterface(proxyInterface);
|
||||
AddAdvice(interceptor);
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ProxyFactory"/> class for the
|
||||
/// given interface and interceptor.
|
||||
/// </summary>
|
||||
/// <remarks>Convenience method for creating a proxy for a single interceptor
|
||||
/// , assuming that the interceptor handles all calls itself rather than delegating
|
||||
/// to a target, like in the case of remoting proxies.</remarks>
|
||||
/// <param name="proxyInterface">The interface that the proxy should implement.</param>
|
||||
/// <param name="interceptor">The interceptor that the proxy should invoke.</param>
|
||||
public ProxyFactory(Type proxyInterface, IInterceptor interceptor)
|
||||
{
|
||||
AddInterface(proxyInterface);
|
||||
AddAdvice(interceptor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of the <see cref="ProxyFactory"/> class for the specified
|
||||
/// <see cref="ITargetSource"/> making the proxy implement the specified interface.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
/// <param name="proxyInterface">The interface that the proxy should implement.</param>
|
||||
/// <param name="targetSource">The target source that the proxy should invoek.</param>
|
||||
public ProxyFactory(Type proxyInterface, ITargetSource targetSource)
|
||||
{
|
||||
AddInterface(proxyInterface);
|
||||
TargetSource = targetSource;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of the <see cref="ProxyFactory"/> class for the specified
|
||||
/// <see cref="ITargetSource"/> making the proxy implement the specified interface.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
/// <param name="proxyInterface">The interface that the proxy should implement.</param>
|
||||
/// <param name="targetSource">The target source that the proxy should invoek.</param>
|
||||
public ProxyFactory(Type proxyInterface, ITargetSource targetSource)
|
||||
{
|
||||
AddInterface(proxyInterface);
|
||||
TargetSource = targetSource;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected ProxyFactory(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected ProxyFactory(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new proxy according to the settings in this factory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Can be called repeatedly; the effect of repeated invocations will
|
||||
/// (of course) vary if interfaces have been added or removed.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>An AOP proxy for target object.</returns>
|
||||
public virtual object GetProxy()
|
||||
{
|
||||
IAopProxy proxy = CreateAopProxy();
|
||||
return proxy.GetProxy();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new proxy according to the settings in this factory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Can be called repeatedly; the effect of repeated invocations will
|
||||
/// (of course) vary if interfaces have been added or removed.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>An AOP proxy for target object.</returns>
|
||||
public virtual object GetProxy()
|
||||
{
|
||||
IAopProxy proxy = CreateAopProxy();
|
||||
return proxy.GetProxy();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new proxy for the supplied <paramref name="proxyInterface"/>
|
||||
/// and <paramref name="interceptor"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a convenience method for creating a proxy for a single
|
||||
/// interceptor.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="proxyInterface">
|
||||
/// The interface that the proxy must implement.
|
||||
/// </param>
|
||||
/// <param name="interceptor">
|
||||
/// The interceptor that the proxy must invoke.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A new AOP proxy for the supplied <paramref name="proxyInterface"/>
|
||||
/// and <paramref name="interceptor"/>.
|
||||
/// </returns>
|
||||
public static object GetProxy(Type proxyInterface, IInterceptor interceptor)
|
||||
{
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.AddInterface(proxyInterface);
|
||||
proxyFactory.AddAdvice(interceptor);
|
||||
return proxyFactory.GetProxy();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new proxy for the supplied <paramref name="proxyInterface"/>
|
||||
/// and <paramref name="interceptor"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a convenience method for creating a proxy for a single
|
||||
/// interceptor.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="proxyInterface">
|
||||
/// The interface that the proxy must implement.
|
||||
/// </param>
|
||||
/// <param name="interceptor">
|
||||
/// The interceptor that the proxy must invoke.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A new AOP proxy for the supplied <paramref name="proxyInterface"/>
|
||||
/// and <paramref name="interceptor"/>.
|
||||
/// </returns>
|
||||
public static object GetProxy(Type proxyInterface, IInterceptor interceptor)
|
||||
{
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.AddInterface(proxyInterface);
|
||||
proxyFactory.AddAdvice(interceptor);
|
||||
return proxyFactory.GetProxy();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,112 +22,110 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
|
||||
using Spring.Util;
|
||||
using AopAlliance.Intercept;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework
|
||||
namespace Spring.Aop.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a target method using standard reflection.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <author>Rick Evans (.NET)</author>
|
||||
/// <author>Bruno Baia (.NET)</author>
|
||||
[Serializable]
|
||||
public class ReflectiveMethodInvocation : AbstractMethodInvocation
|
||||
{
|
||||
/// <summary>
|
||||
/// Invokes a target method using standard reflection.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <author>Rick Evans (.NET)</author>
|
||||
/// <author>Bruno Baia (.NET)</author>
|
||||
[Serializable]
|
||||
public class ReflectiveMethodInvocation : AbstractMethodInvocation
|
||||
{
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked on the proxy.
|
||||
/// </summary>
|
||||
private MethodInfo proxyMethod;
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked on the proxy.
|
||||
/// </summary>
|
||||
private MethodInfo proxyMethod;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.ReflectiveMethodInvocation"/> class.
|
||||
/// </summary>
|
||||
/// <param name="proxy">The AOP proxy.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="method">The target method proxied.</param>
|
||||
/// <param name="proxyMethod">The method to invoke on proxy.</param>
|
||||
/// <param name="arguments">The target method's arguments.</param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.</param>
|
||||
/// <param name="interceptors">
|
||||
/// The list of interceptors that are to be applied. May be
|
||||
/// <cref lang="null"/>.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If any of the <paramref name="target"/> or <paramref name="method"/>
|
||||
/// parameters is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public ReflectiveMethodInvocation(
|
||||
object proxy, object target, MethodInfo method, MethodInfo proxyMethod,
|
||||
object[] arguments, Type targetType, IList interceptors)
|
||||
: base(proxy, target, method, arguments, targetType, interceptors)
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Framework.ReflectiveMethodInvocation"/> class.
|
||||
/// </summary>
|
||||
/// <param name="proxy">The AOP proxy.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="method">The target method proxied.</param>
|
||||
/// <param name="proxyMethod">The method to invoke on proxy.</param>
|
||||
/// <param name="arguments">The target method's arguments.</param>
|
||||
/// <param name="targetType">
|
||||
/// The <see cref="System.Type"/> of the target object.</param>
|
||||
/// <param name="interceptors">
|
||||
/// The list of interceptors that are to be applied. May be
|
||||
/// <cref lang="null"/>.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If any of the <paramref name="target"/> or <paramref name="method"/>
|
||||
/// parameters is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public ReflectiveMethodInvocation(
|
||||
object proxy, object target, MethodInfo method, MethodInfo proxyMethod,
|
||||
object[] arguments, Type targetType, IList interceptors)
|
||||
: base(proxy, target, method, arguments, targetType, interceptors)
|
||||
{
|
||||
this.proxyMethod = proxyMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked on the proxy.
|
||||
/// </summary>
|
||||
protected MethodInfo ProxyMethod
|
||||
{
|
||||
get { return proxyMethod; }
|
||||
set { proxyMethod = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the joinpoint using standard reflection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses can override this to use custom invocation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The return value of the invocation of the joinpoint.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If invoking the joinpoint resulted in an exception.
|
||||
/// </exception>
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation.InvokeJoinpoint"/>
|
||||
protected override object InvokeJoinpoint()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.proxyMethod = proxyMethod;
|
||||
MethodInfo targetMethodInfo = ProxyMethod ?? Method;
|
||||
|
||||
AssertUtils.Understands(Target, "target", targetMethodInfo);
|
||||
return targetMethodInfo.Invoke(Target, Arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The method invocation that is to be invoked on the proxy.
|
||||
/// </summary>
|
||||
protected MethodInfo ProxyMethod
|
||||
{
|
||||
get { return proxyMethod; }
|
||||
set { proxyMethod = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the joinpoint using standard reflection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses can override this to use custom invocation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The return value of the invocation of the joinpoint.
|
||||
/// </returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If invoking the joinpoint resulted in an exception.
|
||||
/// </exception>
|
||||
/// <see cref="Spring.Aop.Framework.AbstractMethodInvocation.InvokeJoinpoint"/>
|
||||
protected override object InvokeJoinpoint()
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
MethodInfo targetMethodInfo = ProxyMethod ?? Method;
|
||||
|
||||
AssertUtils.Understands(Target, "target", targetMethodInfo);
|
||||
return targetMethodInfo.Invoke(Target, Arguments);
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
throw ReflectionUtils.UnwrapTargetInvocationException(ex);
|
||||
}
|
||||
throw ReflectionUtils.UnwrapTargetInvocationException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Spring.Aop.Framework.ReflectiveMethodInvocation"/> instance
|
||||
/// from the specified <see cref="AopAlliance.Intercept.IMethodInvocation"/> and
|
||||
/// increments the interceptor index.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The current <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The new <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance to use.
|
||||
/// </returns>
|
||||
protected override IMethodInvocation PrepareMethodInvocationForProceed(IMethodInvocation invocation)
|
||||
{
|
||||
var rmi = new ReflectiveMethodInvocation(Proxy, Target, Method, ProxyMethod, Arguments, TargetType, Interceptors);
|
||||
rmi.CurrentInterceptorIndex = CurrentInterceptorIndex + 1;
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Spring.Aop.Framework.ReflectiveMethodInvocation"/> instance
|
||||
/// from the specified <see cref="AopAlliance.Intercept.IMethodInvocation"/> and
|
||||
/// increments the interceptor index.
|
||||
/// </summary>
|
||||
/// <param name="invocation">
|
||||
/// The current <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The new <see cref="AopAlliance.Intercept.IMethodInvocation"/> instance to use.
|
||||
/// </returns>
|
||||
protected override IMethodInvocation PrepareMethodInvocationForProceed(IMethodInvocation invocation)
|
||||
{
|
||||
var rmi = new ReflectiveMethodInvocation(Proxy, Target, Method, ProxyMethod, Arguments, TargetType, Interceptors);
|
||||
rmi.CurrentInterceptorIndex = CurrentInterceptorIndex + 1;
|
||||
|
||||
return rmi;
|
||||
}
|
||||
}
|
||||
return rmi;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -24,71 +24,70 @@ using AopAlliance.Aop;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
{
|
||||
/// <summary>
|
||||
/// Base interface holding AOP advice and a filter determining the
|
||||
/// applicability of the advice (such as a pointcut).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <note>
|
||||
/// This interface is not for use by Spring.NET users, but exists rather to
|
||||
/// allow for commonality in the support for different types of advice
|
||||
/// within the framework.
|
||||
/// </note>
|
||||
/// <p>
|
||||
/// Spring.NET AOP is centered on <b>around advice</b> delivered via method
|
||||
/// <b>interception</b>, compliant with the AOP Alliance interception API.
|
||||
/// The <see cref="Spring.Aop.IAdvisor"/> interface allows support for
|
||||
/// different types of advice, such as <b>before</b> and <b>after</b>
|
||||
/// advice, which need not be implemented using interception.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IMethodBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IAdvisor
|
||||
{
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An advisor that was creating a mixin would be a per instance
|
||||
/// operation and would thus return <see langword="true"/>. If the
|
||||
/// advisor is not per instance, it is shared with all instances of the
|
||||
/// advised class obtained from the same Spring.NET IoC container.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Use <c>singleton</c> and <c>prototype</c> object definitions or
|
||||
/// appropriate programmatic proxy creation to ensure that
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>s have the correct lifecycle model.
|
||||
/// </p>
|
||||
/// <note>
|
||||
/// This method is not currently used by the framework.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
bool IsPerInstance { get; }
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An advice may be an interceptor, a throws advice, before advice,
|
||||
/// introduction etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
IAdvice Advice { get; }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Base interface holding AOP advice and a filter determining the
|
||||
/// applicability of the advice (such as a pointcut).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <note>
|
||||
/// This interface is not for use by Spring.NET users, but exists rather to
|
||||
/// allow for commonality in the support for different types of advice
|
||||
/// within the framework.
|
||||
/// </note>
|
||||
/// <p>
|
||||
/// Spring.NET AOP is centered on <b>around advice</b> delivered via method
|
||||
/// <b>interception</b>, compliant with the AOP Alliance interception API.
|
||||
/// The <see cref="Spring.Aop.IAdvisor"/> interface allows support for
|
||||
/// different types of advice, such as <b>before</b> and <b>after</b>
|
||||
/// advice, which need not be implemented using interception.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IMethodBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IAdvisor
|
||||
{
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An advisor that was creating a mixin would be a per instance
|
||||
/// operation and would thus return <see langword="true"/>. If the
|
||||
/// advisor is not per instance, it is shared with all instances of the
|
||||
/// advised class obtained from the same Spring.NET IoC container.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Use <c>singleton</c> and <c>prototype</c> object definitions or
|
||||
/// appropriate programmatic proxy creation to ensure that
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>s have the correct lifecycle model.
|
||||
/// </p>
|
||||
/// <note>
|
||||
/// This method is not currently used by the framework.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
bool IsPerInstance { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An advice may be an interceptor, a throws advice, before advice,
|
||||
/// introduction etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
IAdvice Advice { get; }
|
||||
}
|
||||
|
||||
@@ -22,21 +22,20 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// AOP Aspect abstraction, holding a list of <see cref="Spring.Aop.IAdvisor"/>s
|
||||
/// </summary>
|
||||
/// <seealso cref="IAdvisor"/>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisors
|
||||
{
|
||||
/// <summary>
|
||||
/// AOP Aspect abstraction, holding a list of <see cref="Spring.Aop.IAdvisor"/>s
|
||||
/// </summary>
|
||||
/// <seealso cref="IAdvisor"/>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IAdvisors
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a list of advisors.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A list of advisors.
|
||||
/// </value>
|
||||
IList<IAdvisor> Advisors { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a list of advisors.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A list of advisors.
|
||||
/// </value>
|
||||
IList<IAdvisor> Advisors { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -21,57 +21,55 @@
|
||||
#region Imports
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
using AopAlliance.Aop;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Advice that executes after a method returns <b>successfully</b>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// <i>After</i> returning advice is invoked only on a normal method
|
||||
/// return, but <b>not</b> if an exception is thrown. Such advice can see
|
||||
/// the return value of the advised method invocation, but cannot change it.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Possible uses for this type of advice would include performing access
|
||||
/// control checks on the return value of an advised method invocation, the
|
||||
/// ubiquitous logging of method invocation return values (useful during
|
||||
/// development), etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IMethodBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IAfterReturningAdvice : IAdvice
|
||||
{
|
||||
/// <summary>
|
||||
/// Advice that executes after a method returns <b>successfully</b>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// <i>After</i> returning advice is invoked only on a normal method
|
||||
/// return, but <b>not</b> if an exception is thrown. Such advice can see
|
||||
/// the return value of the advised method invocation, but cannot change it.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Possible uses for this type of advice would include performing access
|
||||
/// control checks on the return value of an advised method invocation, the
|
||||
/// ubiquitous logging of method invocation return values (useful during
|
||||
/// development), etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IMethodBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IAfterReturningAdvice : IAdvice
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes after <paramref name="target"/> <paramref name="method"/>
|
||||
/// returns <b>successfully</b>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Note that the supplied <paramref name="returnValue"/> <b>cannot</b>
|
||||
/// be changed by this type of advice... use the around advice type
|
||||
/// (<see cref="AopAlliance.Intercept.IMethodInterceptor"/>) if you
|
||||
/// need to change the return value of an advised method invocation.
|
||||
/// The data encapsulated by the supplied <paramref name="returnValue"/>
|
||||
/// can of course be modified though.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="returnValue">
|
||||
/// The value returned by the <paramref name="target"/>.
|
||||
/// </param>
|
||||
/// <param name="method">The intecepted method.</param>
|
||||
/// <param name="args">The intercepted method's arguments.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor.Invoke"/>
|
||||
void AfterReturning(object returnValue, MethodInfo method, object[] args, object target);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Executes after <paramref name="target"/> <paramref name="method"/>
|
||||
/// returns <b>successfully</b>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Note that the supplied <paramref name="returnValue"/> <b>cannot</b>
|
||||
/// be changed by this type of advice... use the around advice type
|
||||
/// (<see cref="AopAlliance.Intercept.IMethodInterceptor"/>) if you
|
||||
/// need to change the return value of an advised method invocation.
|
||||
/// The data encapsulated by the supplied <paramref name="returnValue"/>
|
||||
/// can of course be modified though.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="returnValue">
|
||||
/// The value returned by the <paramref name="target"/>.
|
||||
/// </param>
|
||||
/// <param name="method">The intecepted method.</param>
|
||||
/// <param name="args">The intercepted method's arguments.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor.Invoke"/>
|
||||
void AfterReturning(object returnValue, MethodInfo method, object[] args, object target);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -24,30 +24,29 @@ using AopAlliance.Aop;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Superinterface for all before advice.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// <i>Before</i> advice is advice that executes before a joinpoint, but
|
||||
/// which does not have the ability to prevent execution flow proceeding to
|
||||
/// the joinpoint (unless it throws an <see cref="System.Exception"/>).
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Spring.NET only supports <i>method</i> before advice. Although this
|
||||
/// is unlikely to change, this API is designed to allow <i>field</i>
|
||||
/// before advice in future if desired.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IMethodBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IBeforeAdvice : IAdvice
|
||||
{
|
||||
/// <summary>
|
||||
/// Superinterface for all before advice.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// <i>Before</i> advice is advice that executes before a joinpoint, but
|
||||
/// which does not have the ability to prevent execution flow proceeding to
|
||||
/// the joinpoint (unless it throws an <see cref="System.Exception"/>).
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Spring.NET only supports <i>method</i> before advice. Although this
|
||||
/// is unlikely to change, this API is designed to allow <i>field</i>
|
||||
/// before advice in future if desired.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IMethodBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IBeforeAdvice : IAdvice
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,69 +22,68 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Superinterface for advisors that perform one or more AOP
|
||||
/// <b>introductions</b>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This interface cannot be implemented directly; subinterfaces must
|
||||
/// provide the advice type implementing the introduction.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Introduction is the implementation of additional interfaces (not
|
||||
/// implemented by a target) via AOP advice.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.IIntroductionInterceptor"/>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IIntroductionAdvisor : IAdvisor
|
||||
{
|
||||
/// <summary>
|
||||
/// Superinterface for advisors that perform one or more AOP
|
||||
/// <b>introductions</b>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This interface cannot be implemented directly; subinterfaces must
|
||||
/// provide the advice type implementing the introduction.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Introduction is the implementation of additional interfaces (not
|
||||
/// implemented by a target) via AOP advice.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.IIntroductionInterceptor"/>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IIntroductionAdvisor : IAdvisor
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the filter determining which target classes this
|
||||
/// introduction should apply to.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is the <see cref="System.Type"/> part of a pointcut.
|
||||
/// Be advised that method matching doesn't make sense in the context
|
||||
/// of introductions.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The filter determining which target classes this introduction
|
||||
/// should apply to.
|
||||
/// </value>
|
||||
ITypeFilter TypeFilter { get; }
|
||||
/// <summary>
|
||||
/// Returns the filter determining which target classes this
|
||||
/// introduction should apply to.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is the <see cref="System.Type"/> part of a pointcut.
|
||||
/// Be advised that method matching doesn't make sense in the context
|
||||
/// of introductions.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The filter determining which target classes this introduction
|
||||
/// should apply to.
|
||||
/// </value>
|
||||
ITypeFilter TypeFilter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the interfaces introduced by this
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The interfaces introduced by this
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>.
|
||||
/// </value>
|
||||
Type[] Interfaces { get; }
|
||||
/// <summary>
|
||||
/// Gets the interfaces introduced by this
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The interfaces introduced by this
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>.
|
||||
/// </value>
|
||||
Type[] Interfaces { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Can the advised interfaces be implemented by the introduction
|
||||
/// advice?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked <b>before</b> adding an
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If the advised interfaces cannot be implemented by the introduction
|
||||
/// advice.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor.Interfaces"/>
|
||||
void ValidateInterfaces();
|
||||
}
|
||||
/// <summary>
|
||||
/// Can the advised interfaces be implemented by the introduction
|
||||
/// advice?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked <b>before</b> adding an
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If the advised interfaces cannot be implemented by the introduction
|
||||
/// advice.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor.Interfaces"/>
|
||||
void ValidateInterfaces();
|
||||
}
|
||||
|
||||
@@ -24,37 +24,36 @@ using AopAlliance.Intercept;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Subinterface of the AOP Alliance
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInterceptor"/> interface that
|
||||
/// allows additional interfaces to be implemented by the interceptor, and
|
||||
/// available via a proxy using that interceptor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a fundamental AOP concept called <b>introduction</b>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Introductions are often <b>mixins</b>, enabling the building of composite
|
||||
/// objects that can achieve many of the goals of multiple inheritance.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IIntroductionInterceptor : IMethodInterceptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Subinterface of the AOP Alliance
|
||||
/// <see cref="AopAlliance.Intercept.IMethodInterceptor"/> interface that
|
||||
/// allows additional interfaces to be implemented by the interceptor, and
|
||||
/// available via a proxy using that interceptor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a fundamental AOP concept called <b>introduction</b>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Introductions are often <b>mixins</b>, enabling the building of composite
|
||||
/// objects that can achieve many of the goals of multiple inheritance.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IIntroductionInterceptor : IMethodInterceptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Does this <see cref="Spring.Aop.IIntroductionInterceptor"/>
|
||||
/// implement the given interface?
|
||||
/// </summary>
|
||||
/// <param name="intf">The interface to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this
|
||||
/// <see cref="Spring.Aop.IIntroductionInterceptor"/>
|
||||
/// implements the given interface.
|
||||
/// </returns>
|
||||
bool ImplementsInterface(Type intf);
|
||||
}
|
||||
/// <summary>
|
||||
/// Does this <see cref="Spring.Aop.IIntroductionInterceptor"/>
|
||||
/// implement the given interface?
|
||||
/// </summary>
|
||||
/// <param name="intf">The interface to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this
|
||||
/// <see cref="Spring.Aop.IIntroductionInterceptor"/>
|
||||
/// implements the given interface.
|
||||
/// </returns>
|
||||
bool ImplementsInterface(Type intf);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -24,48 +24,47 @@ using System.Reflection;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Advice executed before a method is invoked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Such advice cannot prevent the method call proceeding, short of
|
||||
/// throwing an <see cref="System.Exception"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// The main advantage of <c>before</c> advice is that there is no
|
||||
/// possibility of inadvertently failing to proceed down the interceptor
|
||||
/// chain, since there is no need (and indeed means) to invoke the next
|
||||
/// interceptor in the call chain.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Possible uses for this type of advice would include performing class
|
||||
/// invariant checks prior to the actual method invocation, the ubiquitous
|
||||
/// logging of method invocations (useful during development), etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IMethodBeforeAdvice : IBeforeAdvice
|
||||
{
|
||||
/// <summary>
|
||||
/// Advice executed before a method is invoked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Such advice cannot prevent the method call proceeding, short of
|
||||
/// throwing an <see cref="System.Exception"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// The main advantage of <c>before</c> advice is that there is no
|
||||
/// possibility of inadvertently failing to proceed down the interceptor
|
||||
/// chain, since there is no need (and indeed means) to invoke the next
|
||||
/// interceptor in the call chain.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Possible uses for this type of advice would include performing class
|
||||
/// invariant checks prior to the actual method invocation, the ubiquitous
|
||||
/// logging of method invocations (useful during development), etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IThrowsAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IMethodBeforeAdvice : IBeforeAdvice
|
||||
{
|
||||
/// <summary>
|
||||
/// The callback before a given method is invoked.
|
||||
/// </summary>
|
||||
/// <param name="method">The method being invoked.</param>
|
||||
/// <param name="args">The arguments to the method.</param>
|
||||
/// <param name="target">
|
||||
/// The target of the method invocation. May be <see langword="null"/>.
|
||||
/// </param>
|
||||
/// <exception cref="System.Exception">
|
||||
/// Thrown when and if this object wishes to abort the call. Any
|
||||
/// exception so thrown will be propagated to the caller.
|
||||
/// </exception>
|
||||
void Before(MethodInfo method, object[] args, object target);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The callback before a given method is invoked.
|
||||
/// </summary>
|
||||
/// <param name="method">The method being invoked.</param>
|
||||
/// <param name="args">The arguments to the method.</param>
|
||||
/// <param name="target">
|
||||
/// The target of the method invocation. May be <see langword="null"/>.
|
||||
/// </param>
|
||||
/// <exception cref="System.Exception">
|
||||
/// Thrown when and if this object wishes to abort the call. Any
|
||||
/// exception so thrown will be propagated to the caller.
|
||||
/// </exception>
|
||||
void Before(MethodInfo method, object[] args, object target);
|
||||
}
|
||||
|
||||
@@ -24,126 +24,125 @@ using System.Reflection;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// That part of an <see cref="Spring.Aop.IPointcut"/> that checks whether a
|
||||
/// target method is eligible for advice.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An <see cref="Spring.Aop.IMethodMatcher"/> may be evaluated
|
||||
/// <b>statically</b> or at runtime (<b>dynamically</b>). Static
|
||||
/// matching involves only the method signature and (possibly) any
|
||||
/// <see cref="System.Attribute"/>s that have been applied to a method.
|
||||
/// Dynamic matching additionally takes into account the actual argument
|
||||
/// values passed to a method invocation.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// If the value of the <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/>
|
||||
/// property of an implementation instance returns <see langword="false"/>,
|
||||
/// evaluation can be performed statically, and the result will be the same
|
||||
/// for all invocations of this method, whatever their arguments. This
|
||||
/// means that if the value of the
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/> is
|
||||
/// <see langword="false"/>, the three argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
/// method will never be invoked for the lifetime of the
|
||||
/// <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// If an implementation returns <see langword="true"/> in its two argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type)"/>
|
||||
/// method, and the value of it's
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/> property is
|
||||
/// <see langword="true"/>, the three argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
/// method will be invoked <i>immediately before each and every potential
|
||||
/// execution of the related advice</i>, to decide whether the advice
|
||||
/// should run. All previous advice, such as earlier interceptors in an
|
||||
/// interceptor chain, will have run, so any state changes they have
|
||||
/// produced in parameters or thread local storage, will be available at
|
||||
/// the time of evaluation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="TrueMethodMatcher"/>
|
||||
public interface IMethodMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// That part of an <see cref="Spring.Aop.IPointcut"/> that checks whether a
|
||||
/// target method is eligible for advice.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An <see cref="Spring.Aop.IMethodMatcher"/> may be evaluated
|
||||
/// <b>statically</b> or at runtime (<b>dynamically</b>). Static
|
||||
/// matching involves only the method signature and (possibly) any
|
||||
/// <see cref="System.Attribute"/>s that have been applied to a method.
|
||||
/// Dynamic matching additionally takes into account the actual argument
|
||||
/// values passed to a method invocation.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// If the value of the <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/>
|
||||
/// property of an implementation instance returns <see langword="false"/>,
|
||||
/// evaluation can be performed statically, and the result will be the same
|
||||
/// for all invocations of this method, whatever their arguments. This
|
||||
/// means that if the value of the
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/> is
|
||||
/// <see langword="false"/>, the three argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
/// method will never be invoked for the lifetime of the
|
||||
/// <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// If an implementation returns <see langword="true"/> in its two argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type)"/>
|
||||
/// method, and the value of it's
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/> property is
|
||||
/// <see langword="true"/>, the three argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
/// method will be invoked <i>immediately before each and every potential
|
||||
/// execution of the related advice</i>, to decide whether the advice
|
||||
/// should run. All previous advice, such as earlier interceptors in an
|
||||
/// interceptor chain, will have run, so any state changes they have
|
||||
/// produced in parameters or thread local storage, will be available at
|
||||
/// the time of evaluation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="TrueMethodMatcher"/>
|
||||
public interface IMethodMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Is this <see cref="Spring.Aop.IMethodMatcher"/> dynamic?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If <see langword="true"/>, the three argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
/// method will be invoked if the two argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type)"/>
|
||||
/// method returns <see langword="true"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Note that this property can be checked when an AOP proxy is created,
|
||||
/// and implementations need not check the value of this property again
|
||||
/// before each method invocation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this
|
||||
/// <see cref="Spring.Aop.IMethodMatcher"/> is dynamic.
|
||||
/// </value>
|
||||
bool IsRuntime { get; }
|
||||
/// <summary>
|
||||
/// Is this <see cref="Spring.Aop.IMethodMatcher"/> dynamic?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If <see langword="true"/>, the three argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
/// method will be invoked if the two argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type)"/>
|
||||
/// method returns <see langword="true"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Note that this property can be checked when an AOP proxy is created,
|
||||
/// and implementations need not check the value of this property again
|
||||
/// before each method invocation.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this
|
||||
/// <see cref="Spring.Aop.IMethodMatcher"/> is dynamic.
|
||||
/// </value>
|
||||
bool IsRuntime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a static check. If this method invocation returns
|
||||
/// <see langword="false"/>,or if the
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/> property is
|
||||
/// <see langword="false"/>, then no runtime check will be made.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
bool Matches(MethodInfo method, Type targetType);
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is a static check. If this method invocation returns
|
||||
/// <see langword="false"/>,or if the
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/> property is
|
||||
/// <see langword="false"/>, then no runtime check will be made.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
bool Matches(MethodInfo method, Type targetType);
|
||||
|
||||
/// <summary>
|
||||
/// Is there a runtime (dynamic) match for the supplied
|
||||
/// <paramref name="method"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// In order for this method to have even been invoked, the supplied
|
||||
/// <paramref name="method"/> must have matched
|
||||
/// statically. This method is invoked only if the two argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type)"/>
|
||||
/// method returns <see langword="true"/> for the supplied
|
||||
/// <paramref name="method"/> and <paramref name="targetType"/>, and
|
||||
/// if the <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/> property
|
||||
/// is <see langword="true"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Invoked immediately <b>before</b> any potential running of the
|
||||
/// advice, and <b>after</b> any advice earlier in the advice chain has
|
||||
/// run.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <param name="args">The arguments to the method</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if there is a runtime match.</returns>
|
||||
bool Matches(MethodInfo method, Type targetType, object[] args);
|
||||
}
|
||||
/// <summary>
|
||||
/// Is there a runtime (dynamic) match for the supplied
|
||||
/// <paramref name="method"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// In order for this method to have even been invoked, the supplied
|
||||
/// <paramref name="method"/> must have matched
|
||||
/// statically. This method is invoked only if the two argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type)"/>
|
||||
/// method returns <see langword="true"/> for the supplied
|
||||
/// <paramref name="method"/> and <paramref name="targetType"/>, and
|
||||
/// if the <see cref="Spring.Aop.IMethodMatcher.IsRuntime"/> property
|
||||
/// is <see langword="true"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Invoked immediately <b>before</b> any potential running of the
|
||||
/// advice, and <b>after</b> any advice earlier in the advice chain has
|
||||
/// run.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <param name="args">The arguments to the method</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if there is a runtime match.</returns>
|
||||
bool Matches(MethodInfo method, Type targetType, object[] args);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -18,37 +18,36 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
{
|
||||
/// <summary>
|
||||
/// Spring.NET's core pointcut abstraction.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// A pointcut is composed of <see cref="Spring.Aop.ITypeFilter"/>s and
|
||||
/// <see cref="Spring.Aop.IMethodMatcher"/>s. Both these basic terms and an
|
||||
/// <see cref="Spring.Aop.IPointcut"/> itself can be combined to build up
|
||||
/// sophisticated combinations.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IPointcut
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
ITypeFilter TypeFilter { get; }
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </value>
|
||||
IMethodMatcher MethodMatcher { get; }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Spring.NET's core pointcut abstraction.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// A pointcut is composed of <see cref="Spring.Aop.ITypeFilter"/>s and
|
||||
/// <see cref="Spring.Aop.IMethodMatcher"/>s. Both these basic terms and an
|
||||
/// <see cref="Spring.Aop.IPointcut"/> itself can be combined to build up
|
||||
/// sophisticated combinations.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface IPointcut
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
ITypeFilter TypeFilter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </value>
|
||||
IMethodMatcher MethodMatcher { get; }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -18,26 +18,25 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Superinterface for all <see cref="Spring.Aop.IAdvisor"/>s that are
|
||||
/// driven by a pointcut.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This covers nearly all advisors except introduction advisors, for which
|
||||
/// method-level matching does not apply.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor"/>
|
||||
public interface IPointcutAdvisor : IAdvisor
|
||||
{
|
||||
/// <summary>
|
||||
/// Superinterface for all <see cref="Spring.Aop.IAdvisor"/>s that are
|
||||
/// driven by a pointcut.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This covers nearly all advisors except introduction advisors, for which
|
||||
/// method-level matching does not apply.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor"/>
|
||||
public interface IPointcutAdvisor : IAdvisor
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
IPointcut Pointcut { get; }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
IPointcut Pointcut { get; }
|
||||
}
|
||||
|
||||
@@ -22,56 +22,55 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Used to obtain the current "target" of an AOP invocation
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This target will be invoked via reflection if no around advice chooses
|
||||
/// to end the interceptor chain itself.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// If an <see cref="Spring.Aop.ITargetSource"/> is <c>"static"</c>, it
|
||||
/// will always return the same target, allowing optimizations in the AOP
|
||||
/// framework. Dynamic target sources can support pooling, hot swapping etc.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Application developers don't usually need to work with target sources
|
||||
/// directly: this is an AOP framework interface.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface ITargetSource
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to obtain the current "target" of an AOP invocation
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This target will be invoked via reflection if no around advice chooses
|
||||
/// to end the interceptor chain itself.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// If an <see cref="Spring.Aop.ITargetSource"/> is <c>"static"</c>, it
|
||||
/// will always return the same target, allowing optimizations in the AOP
|
||||
/// framework. Dynamic target sources can support pooling, hot swapping etc.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Application developers don't usually need to work with target sources
|
||||
/// directly: this is an AOP framework interface.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
public interface ITargetSource
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="System.Type"/> of the target object.
|
||||
/// </summary>
|
||||
Type TargetType { get; }
|
||||
/// <summary>
|
||||
/// The <see cref="System.Type"/> of the target object.
|
||||
/// </summary>
|
||||
Type TargetType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the target source static?
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if the target source is static.
|
||||
/// </value>
|
||||
bool IsStatic { get; }
|
||||
/// <summary>
|
||||
/// Is the target source static?
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if the target source is static.
|
||||
/// </value>
|
||||
bool IsStatic { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the target object.
|
||||
/// </summary>
|
||||
/// <returns>The target object.</returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If unable to obtain the target object.
|
||||
/// </exception>
|
||||
object GetTarget();
|
||||
/// <summary>
|
||||
/// Returns the target object.
|
||||
/// </summary>
|
||||
/// <returns>The target object.</returns>
|
||||
/// <exception cref="System.Exception">
|
||||
/// If unable to obtain the target object.
|
||||
/// </exception>
|
||||
object GetTarget();
|
||||
|
||||
/// <summary>
|
||||
/// Releases the target object.
|
||||
/// </summary>
|
||||
/// <param name="target">The target object to release.</param>
|
||||
void ReleaseTarget(object target);
|
||||
}
|
||||
/// <summary>
|
||||
/// Releases the target object.
|
||||
/// </summary>
|
||||
/// <param name="target">The target object to release.</param>
|
||||
void ReleaseTarget(object target);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2011 the original author or authors.
|
||||
* Copyright <EFBFBD> 2002-2011 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.
|
||||
@@ -24,36 +24,35 @@ using AopAlliance.Aop;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// Simple marker interface for throws advice.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// There are no methods on this interface, as methods are discovered and
|
||||
/// invoked via reflection. Please do see read the API documentation for the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor"/> class;
|
||||
/// said documention describes in detail the signature of the methods that
|
||||
/// implementations of the <see cref="Spring.Aop.IThrowsAdvice"/> interface
|
||||
/// must adhere to in the specific case of Spring.NET's implementation of
|
||||
/// throws advice.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// There are any number of possible uses for this type of advice. Some
|
||||
/// examples would include the ubiquitous logging of any such exceptions,
|
||||
/// monitoring the number and type of exceptions and sending emails to
|
||||
/// a support desk once certain criteria have been met, wrapping generic
|
||||
/// exceptions such as System.Data.SqlClient.SqlException in
|
||||
/// exceptions that are more meaningful to your business logic, etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IMethodBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IThrowsAdvice : IAdvice
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple marker interface for throws advice.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// There are no methods on this interface, as methods are discovered and
|
||||
/// invoked via reflection. Please do see read the API documentation for the
|
||||
/// <see cref="Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor"/> class;
|
||||
/// said documention describes in detail the signature of the methods that
|
||||
/// implementations of the <see cref="Spring.Aop.IThrowsAdvice"/> interface
|
||||
/// must adhere to in the specific case of Spring.NET's implementation of
|
||||
/// throws advice.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// There are any number of possible uses for this type of advice. Some
|
||||
/// examples would include the ubiquitous logging of any such exceptions,
|
||||
/// monitoring the number and type of exceptions and sending emails to
|
||||
/// a support desk once certain criteria have been met, wrapping generic
|
||||
/// exceptions such as System.Data.SqlClient.SqlException in
|
||||
/// exceptions that are more meaningful to your business logic, etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IMethodBeforeAdvice"/>
|
||||
/// <seealso cref="Spring.Aop.IAfterReturningAdvice"/>
|
||||
/// <seealso cref="AopAlliance.Intercept.IMethodInterceptor"/>
|
||||
public interface IThrowsAdvice : IAdvice
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,35 +22,34 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop
|
||||
namespace Spring.Aop;
|
||||
|
||||
/// <summary>
|
||||
/// A filter that restricts the matching of a pointcut or introduction to
|
||||
/// a given set of target types.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Can be used as part of a pointcut, or for the entire targeting of an
|
||||
/// introduction.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IPointcut"/>
|
||||
/// <seealso cref="TrueTypeFilter.True"/>
|
||||
public interface ITypeFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// A filter that restricts the matching of a pointcut or introduction to
|
||||
/// a given set of target types.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Can be used as part of a pointcut, or for the entire targeting of an
|
||||
/// introduction.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.IPointcut"/>
|
||||
/// <seealso cref="TrueTypeFilter.True"/>
|
||||
public interface ITypeFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied
|
||||
/// <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// The candidate <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
bool Matches(Type type);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied
|
||||
/// <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// The candidate <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
bool Matches(Type type);
|
||||
}
|
||||
@@ -20,59 +20,58 @@
|
||||
|
||||
using AopAlliance.Aop;
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract PointcutAdvisor that allows for any Advice to be configured.
|
||||
/// </summary>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractGenericPointcutAdvisor : AbstractPointcutAdvisor
|
||||
{
|
||||
private IAdvice advice;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract PointcutAdvisor that allows for any Advice to be configured.
|
||||
/// Return the advice part of this advisor.
|
||||
/// </summary>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractGenericPointcutAdvisor : AbstractPointcutAdvisor
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/>
|
||||
public override IAdvice Advice
|
||||
{
|
||||
private IAdvice advice;
|
||||
get { return this.advice; }
|
||||
set { this.advice = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this advisor.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/>
|
||||
public override IAdvice Advice
|
||||
{
|
||||
get { return this.advice; }
|
||||
set { this.advice = value; }
|
||||
}
|
||||
///<summary>
|
||||
/// 2 <see cref="AbstractGenericPointcutAdvisor"/>s are considered equals, if
|
||||
/// a) their pointcuts are equal
|
||||
/// b) their advices are equal
|
||||
///</summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj as AbstractGenericPointcutAdvisor);
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// 2 <see cref="AbstractGenericPointcutAdvisor"/>s are considered equals, if
|
||||
/// a) their pointcuts are equal
|
||||
/// b) their advices are equal
|
||||
///</summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj as AbstractGenericPointcutAdvisor);
|
||||
}
|
||||
/// <summary>
|
||||
/// Calculates a unique hashcode based on advice + pointcut
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a unique hashcode based on advice + pointcut
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents the current
|
||||
/// <see cref="System.Object"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> representation of this advisor.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return GetType().Name + ": advice=[" + Advice + "]";
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents the current
|
||||
/// <see cref="System.Object"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> representation of this advisor.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return GetType().Name + ": advice=[" + Advice + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,115 +22,114 @@ using AopAlliance.Aop;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract ObjectFactory-based IPointcutAdvisor that allows for any Advice to be
|
||||
/// configured as reference to an Advice object in an ObjectFactory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// specifying the name of an advice object instead of the advice object itself
|
||||
/// (if running within an ObjectFactory/ApplicationContext increses loose coupling
|
||||
/// at initialization time, in order not to initialize the advice object until the
|
||||
/// pointcut actually matches.
|
||||
/// </remarks>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack</author>
|
||||
public abstract class AbstractObjectFactoryPointcutAdvisor : AbstractPointcutAdvisor, IObjectFactoryAware
|
||||
{
|
||||
private string adviceObjectName;
|
||||
|
||||
private IObjectFactory objectFactory;
|
||||
|
||||
private IAdvice advice;
|
||||
|
||||
private object adviceMonitor = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Abstract ObjectFactory-based IPointcutAdvisor that allows for any Advice to be
|
||||
/// configured as reference to an Advice object in an ObjectFactory.
|
||||
/// Gets or sets the name of the advice object that this advisor should refer to.
|
||||
/// </summary>
|
||||
/// <remarks>An instance of the specified object will be obtained on first access of
|
||||
/// this advisor's advice. This advisor will only ever obtain at most one
|
||||
/// single instance of the advice object, caching the instance for the lifetime of
|
||||
/// the advisor.</remarks>
|
||||
/// <value>The name of the advice object.</value>
|
||||
public string AdviceObjectName
|
||||
{
|
||||
get { return adviceObjectName; }
|
||||
set { adviceObjectName = value; }
|
||||
}
|
||||
|
||||
#region IObjectFactoryAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Callback that supplies the owning factory to an object instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Owning <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// (may not be <see langword="null"/>). The object can immediately
|
||||
/// call methods on the factory.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of initialization errors.
|
||||
/// </exception>
|
||||
public IObjectFactory ObjectFactory
|
||||
{
|
||||
set { objectFactory = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// specifying the name of an advice object instead of the advice object itself
|
||||
/// (if running within an ObjectFactory/ApplicationContext increses loose coupling
|
||||
/// at initialization time, in order not to initialize the advice object until the
|
||||
/// pointcut actually matches.
|
||||
/// <p>
|
||||
/// An advice may be an interceptor, a throws advice, before advice,
|
||||
/// introduction etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack</author>
|
||||
public abstract class AbstractObjectFactoryPointcutAdvisor : AbstractPointcutAdvisor, IObjectFactoryAware
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
public override IAdvice Advice
|
||||
{
|
||||
private string adviceObjectName;
|
||||
|
||||
private IObjectFactory objectFactory;
|
||||
|
||||
private IAdvice advice;
|
||||
|
||||
private object adviceMonitor = new object();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the advice object that this advisor should refer to.
|
||||
/// </summary>
|
||||
/// <remarks>An instance of the specified object will be obtained on first access of
|
||||
/// this advisor's advice. This advisor will only ever obtain at most one
|
||||
/// single instance of the advice object, caching the instance for the lifetime of
|
||||
/// the advisor.</remarks>
|
||||
/// <value>The name of the advice object.</value>
|
||||
public string AdviceObjectName
|
||||
get
|
||||
{
|
||||
get { return adviceObjectName; }
|
||||
set { adviceObjectName = value; }
|
||||
}
|
||||
|
||||
#region IObjectFactoryAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Callback that supplies the owning factory to an object instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Owning <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// (may not be <see langword="null"/>). The object can immediately
|
||||
/// call methods on the factory.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of initialization errors.
|
||||
/// </exception>
|
||||
public IObjectFactory ObjectFactory
|
||||
{
|
||||
set { objectFactory = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An advice may be an interceptor, a throws advice, before advice,
|
||||
/// introduction etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
public override IAdvice Advice
|
||||
{
|
||||
get
|
||||
lock (adviceMonitor)
|
||||
{
|
||||
lock (adviceMonitor)
|
||||
if (advice == null && adviceObjectName != null)
|
||||
{
|
||||
if (advice == null && adviceObjectName != null)
|
||||
{
|
||||
AssertUtils.State(objectFactory != null,
|
||||
"ObjectFactory must be set to resolve 'adviceObjectName'");
|
||||
advice = objectFactory.GetObject(adviceObjectName, typeof (IAdvice)) as IAdvice;
|
||||
}
|
||||
AssertUtils.State(objectFactory != null,
|
||||
"ObjectFactory must be set to resolve 'adviceObjectName'");
|
||||
advice = objectFactory.GetObject(adviceObjectName, typeof(IAdvice)) as IAdvice;
|
||||
}
|
||||
return advice;
|
||||
}
|
||||
set
|
||||
{
|
||||
advice = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describe this Advisor, showing name of advice object.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Type name and advice object name.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
return advice;
|
||||
}
|
||||
set
|
||||
{
|
||||
return GetType().Name + ": advice object '" + AdviceObjectName + "'";
|
||||
advice = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describe this Advisor, showing name of advice object.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Type name and advice object name.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return GetType().Name + ": advice object '" + AdviceObjectName + "'";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,136 +17,136 @@
|
||||
using AopAlliance.Aop;
|
||||
using Spring.Core;
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base class for <see cref="IPointcutAdvisor"/> implementations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Can be subclassed for returning a specific pointcut/advice or a freely configurable pointcut/advice.
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractPointcutAdvisor : IPointcutAdvisor, IOrdered
|
||||
{
|
||||
private int _order = Int32.MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base class for <see cref="IPointcutAdvisor"/> implementations.
|
||||
/// Returns this <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// This <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </returns>
|
||||
public virtual int Order
|
||||
{
|
||||
get { return this._order; }
|
||||
set { this._order = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Can be subclassed for returning a specific pointcut/advice or a freely configurable pointcut/advice.
|
||||
/// <p>
|
||||
/// An advice may be an interceptor, a throws advice, before advice,
|
||||
/// introduction etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractPointcutAdvisor : IPointcutAdvisor, IOrdered
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
public abstract IAdvice Advice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Not supported for dynamic advisors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
/// <exception cref="System.NotSupportedException">Always.</exception>
|
||||
/// <see cref="Spring.Aop.IAdvisor.IsPerInstance"/>
|
||||
public virtual bool IsPerInstance
|
||||
{
|
||||
private int _order = Int32.MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// Returns this <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// This <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </returns>
|
||||
public virtual int Order
|
||||
get
|
||||
{
|
||||
get { return this._order; }
|
||||
set { this._order = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An advice may be an interceptor, a throws advice, before advice,
|
||||
/// introduction etc.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
public abstract IAdvice Advice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Not supported for dynamic advisors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
/// <exception cref="System.NotSupportedException">Always.</exception>
|
||||
/// <see cref="Spring.Aop.IAdvisor.IsPerInstance"/>
|
||||
public virtual bool IsPerInstance
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
"The 'IsPerInstance' property of the IAdvisor interface " +
|
||||
"is not yet supported in Spring.NET.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
public abstract IPointcut Pointcut { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="System.Object"/>
|
||||
/// is equal to the current <see cref="System.Object"/>.
|
||||
/// </summary>
|
||||
/// <param name="o">The advisor to compare with.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this instance is equal to the
|
||||
/// specified <see cref="System.Object"/>.
|
||||
/// </returns>
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (!(o is AbstractPointcutAdvisor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, o))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AbstractPointcutAdvisor otherAdvisor = (AbstractPointcutAdvisor)o;
|
||||
if (this.Order != otherAdvisor.Order)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (otherAdvisor.Advice == null && otherAdvisor.Pointcut == null)
|
||||
{
|
||||
return (this.Advice == null && this.Pointcut == null);
|
||||
}
|
||||
else if (otherAdvisor.Advice == null)
|
||||
{
|
||||
return (Advice == null && otherAdvisor.Pointcut.Equals(this.Pointcut));
|
||||
}
|
||||
else if (otherAdvisor.Pointcut == null)
|
||||
{
|
||||
return (this.Pointcut == null && otherAdvisor.Advice.Equals(this.Advice));
|
||||
}
|
||||
else
|
||||
{
|
||||
return otherAdvisor.Advice.Equals(this.Advice) && otherAdvisor.Pointcut.Equals(this.Pointcut);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a particular type, suitable for use
|
||||
/// in hashing algorithms and data structures like a hash table.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for the current <see cref="System.Object"/>.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return 0 // (SPRNET-847) base.GetHashCode()
|
||||
+ 13 * (Pointcut == null ? 0 : Pointcut.GetHashCode())
|
||||
+ 27 * (Advice == null ? 0 : Advice.GetHashCode())
|
||||
+ 31 * Order.GetHashCode();
|
||||
throw new NotSupportedException(
|
||||
"The 'IsPerInstance' property of the IAdvisor interface " +
|
||||
"is not yet supported in Spring.NET.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
public abstract IPointcut Pointcut { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="System.Object"/>
|
||||
/// is equal to the current <see cref="System.Object"/>.
|
||||
/// </summary>
|
||||
/// <param name="o">The advisor to compare with.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this instance is equal to the
|
||||
/// specified <see cref="System.Object"/>.
|
||||
/// </returns>
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (!(o is AbstractPointcutAdvisor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, o))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AbstractPointcutAdvisor otherAdvisor = (AbstractPointcutAdvisor) o;
|
||||
if (this.Order != otherAdvisor.Order)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (otherAdvisor.Advice == null && otherAdvisor.Pointcut == null)
|
||||
{
|
||||
return (this.Advice == null && this.Pointcut == null);
|
||||
}
|
||||
else if (otherAdvisor.Advice == null)
|
||||
{
|
||||
return (Advice == null && otherAdvisor.Pointcut.Equals(this.Pointcut));
|
||||
}
|
||||
else if (otherAdvisor.Pointcut == null)
|
||||
{
|
||||
return (this.Pointcut == null && otherAdvisor.Advice.Equals(this.Advice));
|
||||
}
|
||||
else
|
||||
{
|
||||
return otherAdvisor.Advice.Equals(this.Advice) && otherAdvisor.Pointcut.Equals(this.Pointcut);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a particular type, suitable for use
|
||||
/// in hashing algorithms and data structures like a hash table.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for the current <see cref="System.Object"/>.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return 0 // (SPRNET-847) base.GetHashCode()
|
||||
+ 13 * (Pointcut == null ? 0 : Pointcut.GetHashCode())
|
||||
+ 27 * (Advice == null ? 0 : Advice.GetHashCode())
|
||||
+ 31 * Order.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,236 +17,233 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
|
||||
using AopAlliance.Aop;
|
||||
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base regular expression pointcut object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The regular expressions must be a match. For example, the
|
||||
/// <code>.*Get.*</code> pattern will match <c>Com.Mycom.Foo.GetBar()</c>, and
|
||||
/// <code>Get.*</code> will not.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This base class is serializable. Subclasses should decorate all
|
||||
/// fields with the NonSerializedAttribute - the
|
||||
/// <see cref="AbstractRegularExpressionMethodPointcut.InitPatternRepresentation"/>
|
||||
/// method in this class will be invoked again on the client side on deserialization.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Simon White (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractRegularExpressionMethodPointcut
|
||||
: StaticMethodMatcherPointcut, ITypeFilter, ISerializable
|
||||
{
|
||||
[NonSerialized] private object[] _patterns = ObjectUtils.EmptyObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base regular expression pointcut object.
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AbstractRegularExpressionMethodPointcut"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The regular expressions must be a match. For example, the
|
||||
/// <code>.*Get.*</code> pattern will match <c>Com.Mycom.Foo.GetBar()</c>, and
|
||||
/// <code>Get.*</code> will not.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This base class is serializable. Subclasses should decorate all
|
||||
/// fields with the NonSerializedAttribute - the
|
||||
/// <see cref="AbstractRegularExpressionMethodPointcut.InitPatternRepresentation"/>
|
||||
/// method in this class will be invoked again on the client side on deserialization.
|
||||
/// This is an abstract class, and as such has no publicly
|
||||
/// visible constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Simon White (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractRegularExpressionMethodPointcut
|
||||
: StaticMethodMatcherPointcut, ITypeFilter, ISerializable
|
||||
protected AbstractRegularExpressionMethodPointcut()
|
||||
{
|
||||
[NonSerialized]
|
||||
private object[] _patterns = ObjectUtils.EmptyObjects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AbstractRegularExpressionMethodPointcut"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an abstract class, and as such has no publicly
|
||||
/// visible constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
protected AbstractRegularExpressionMethodPointcut()
|
||||
/// <inheritdoc />
|
||||
protected AbstractRegularExpressionMethodPointcut(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
_patterns = (object[]) info.GetValue("Patterns", typeof(object[]));
|
||||
if (_patterns == null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected AbstractRegularExpressionMethodPointcut(
|
||||
SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
_patterns = (object[])info.GetValue("Patterns", typeof(object[]));
|
||||
if (_patterns == null)
|
||||
{
|
||||
_patterns = ObjectUtils.EmptyObjects;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridden to ensure proper initialization
|
||||
/// </summary>
|
||||
protected override void OnDeserialization(object sender)
|
||||
{
|
||||
base.OnDeserialization(sender);
|
||||
try
|
||||
{
|
||||
InitPatternRepresentation(_patterns);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new AspectException(
|
||||
"Failed to deserialize AOP regular expression pointcut: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
public override ITypeFilter TypeFilter
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience property for setting a single pattern.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use this property or Patterns, not both.
|
||||
/// </remarks>
|
||||
public virtual object Pattern
|
||||
{
|
||||
get { return (_patterns.Length > 0 ? _patterns[0] : null); }
|
||||
set
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(value, "Pattern");
|
||||
this.Patterns = new object[] { value };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The regular expressions defining methods to match.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Matching will be the union of all these; if any match,
|
||||
/// the pointcut matches.
|
||||
/// </remarks>
|
||||
public virtual object[] Patterns
|
||||
{
|
||||
get { return _patterns; }
|
||||
set
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(value, "Patterns");
|
||||
this._patterns = value;
|
||||
InitPatternRepresentation(this.Patterns);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("Patterns", _patterns);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subclasses must implement this to initialize regular expression pointcuts.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Can be invoked multiple times.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This method will be invoked from the <see cref="Patterns"/> property,
|
||||
/// and also on deserialization.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="patterns">
|
||||
/// The patterns to initialize.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// In the case of an invalid pattern.
|
||||
/// </exception>
|
||||
protected abstract void InitPatternRepresentation(object[] patterns);
|
||||
|
||||
/// <summary>
|
||||
/// Does the pattern at the supplied <paramref name="patternIndex"/>
|
||||
/// match this <paramref name="pattern"/>?
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern to match</param>
|
||||
/// <param name="patternIndex">The index of pattern.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if there is a match.
|
||||
/// </returns>
|
||||
protected abstract bool Matches(string pattern, int patternIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Try to match the regular expression against the fully qualified name
|
||||
/// of the method's declaring <see cref="System.Type"/>, plus the name of
|
||||
/// the supplied <paramref name="method"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Note that the declaring <see cref="System.Type"/> is that
|
||||
/// <see cref="System.Type"/> that originally declared
|
||||
/// the method, not necessarily the <see cref="System.Type"/> that is
|
||||
/// currently exposing it. For example, <see cref="System.Object.Equals(object)"/>
|
||||
/// matches any subclass of <see cref="System.Object"/>'s
|
||||
/// <see cref="System.Object.Equals(object)"/> method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
public override bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
string patt = string.Empty;
|
||||
patt = String.Format("{0}.{1}", method.DeclaringType, method.Name);
|
||||
|
||||
if (method.DeclaringType.IsGenericType)
|
||||
{
|
||||
patt = String.Format("{0}.{1}", ReflectionUtils.GetTypeFriendlyName(method.DeclaringType), method.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
patt = String.Format("{0}.{1}", method.DeclaringType, method.Name);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.Patterns.Length; ++i)
|
||||
{
|
||||
bool matched = Matches(patt, i);
|
||||
if (matched)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied
|
||||
/// <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// In this instance, simply returns <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The candidate <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
public bool Matches(Type type)
|
||||
{
|
||||
return true;
|
||||
_patterns = ObjectUtils.EmptyObjects;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridden to ensure proper initialization
|
||||
/// </summary>
|
||||
protected override void OnDeserialization(object sender)
|
||||
{
|
||||
base.OnDeserialization(sender);
|
||||
try
|
||||
{
|
||||
InitPatternRepresentation(_patterns);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new AspectException(
|
||||
"Failed to deserialize AOP regular expression pointcut: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
public override ITypeFilter TypeFilter
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience property for setting a single pattern.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use this property or Patterns, not both.
|
||||
/// </remarks>
|
||||
public virtual object Pattern
|
||||
{
|
||||
get { return (_patterns.Length > 0 ? _patterns[0] : null); }
|
||||
set
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(value, "Pattern");
|
||||
this.Patterns = new object[] { value };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The regular expressions defining methods to match.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Matching will be the union of all these; if any match,
|
||||
/// the pointcut matches.
|
||||
/// </remarks>
|
||||
public virtual object[] Patterns
|
||||
{
|
||||
get { return _patterns; }
|
||||
set
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(value, "Patterns");
|
||||
this._patterns = value;
|
||||
InitPatternRepresentation(this.Patterns);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("Patterns", _patterns);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subclasses must implement this to initialize regular expression pointcuts.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Can be invoked multiple times.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This method will be invoked from the <see cref="Patterns"/> property,
|
||||
/// and also on deserialization.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="patterns">
|
||||
/// The patterns to initialize.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// In the case of an invalid pattern.
|
||||
/// </exception>
|
||||
protected abstract void InitPatternRepresentation(object[] patterns);
|
||||
|
||||
/// <summary>
|
||||
/// Does the pattern at the supplied <paramref name="patternIndex"/>
|
||||
/// match this <paramref name="pattern"/>?
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern to match</param>
|
||||
/// <param name="patternIndex">The index of pattern.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if there is a match.
|
||||
/// </returns>
|
||||
protected abstract bool Matches(string pattern, int patternIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Try to match the regular expression against the fully qualified name
|
||||
/// of the method's declaring <see cref="System.Type"/>, plus the name of
|
||||
/// the supplied <paramref name="method"/>.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Note that the declaring <see cref="System.Type"/> is that
|
||||
/// <see cref="System.Type"/> that originally declared
|
||||
/// the method, not necessarily the <see cref="System.Type"/> that is
|
||||
/// currently exposing it. For example, <see cref="System.Object.Equals(object)"/>
|
||||
/// matches any subclass of <see cref="System.Object"/>'s
|
||||
/// <see cref="System.Object.Equals(object)"/> method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
public override bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
string patt = string.Empty;
|
||||
patt = String.Format("{0}.{1}", method.DeclaringType, method.Name);
|
||||
|
||||
if (method.DeclaringType.IsGenericType)
|
||||
{
|
||||
patt = String.Format("{0}.{1}", ReflectionUtils.GetTypeFriendlyName(method.DeclaringType), method.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
patt = String.Format("{0}.{1}", method.DeclaringType, method.Name);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.Patterns.Length; ++i)
|
||||
{
|
||||
bool matched = Matches(patt, i);
|
||||
if (matched)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied
|
||||
/// <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// In this instance, simply returns <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The candidate <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
public bool Matches(Type type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2010 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.
|
||||
*/
|
||||
* Copyright 2002-2010 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
|
||||
|
||||
@@ -22,210 +22,210 @@
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.IPointcut"/> implementation that matches methods
|
||||
/// that have been decorated with a specified <see cref="System.Attribute"/>.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Ronald Wildenberg</author>
|
||||
[Serializable]
|
||||
public class AttributeMatchMethodPointcut : StaticMethodMatcherPointcut, ISerializable
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="Spring.Aop.IPointcut"/> implementation that matches methods
|
||||
/// that have been decorated with a specified <see cref="System.Attribute"/>.
|
||||
/// </summary>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
/// <author>Ronald Wildenberg</author>
|
||||
[Serializable]
|
||||
public class AttributeMatchMethodPointcut : StaticMethodMatcherPointcut, ISerializable
|
||||
{
|
||||
private Type _attribute;
|
||||
private bool _inherit = true;
|
||||
private bool _checkInterfaces = false;
|
||||
private Type _attribute;
|
||||
private bool _inherit = true;
|
||||
private bool _checkInterfaces = false;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.AttributeMatchMethodPointcut"/> class.
|
||||
/// </summary>
|
||||
public AttributeMatchMethodPointcut()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.AttributeMatchMethodPointcut"/> class.
|
||||
/// </summary>
|
||||
public AttributeMatchMethodPointcut()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.AttributeMatchMethodPointcut"/> class.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </param>
|
||||
public AttributeMatchMethodPointcut(Type attribute)
|
||||
: this(attribute, true, false)
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.AttributeMatchMethodPointcut"/> class.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </param>
|
||||
public AttributeMatchMethodPointcut(Type attribute)
|
||||
: this(attribute, true, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.AttributeMatchMethodPointcut"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </param>
|
||||
/// <param name="inherit">
|
||||
/// Flag that controls whether or not the inheritance tree of the
|
||||
/// method to be included in the search for the <see cref="Attribute"/>?
|
||||
/// </param>
|
||||
public AttributeMatchMethodPointcut(Type attribute, bool inherit)
|
||||
: this(attribute, inherit, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.AttributeMatchMethodPointcut"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </param>
|
||||
/// <param name="inherit">
|
||||
/// Flag that controls whether or not the inheritance tree of the
|
||||
/// method to be included in the search for the <see cref="Attribute"/>?
|
||||
/// </param>
|
||||
/// <param name="checkInterfaces">
|
||||
/// Flag that controls whether or not interfaces attributes of the
|
||||
/// method to be included in the search for the <see cref="Attribute"/>?
|
||||
/// </param>
|
||||
public AttributeMatchMethodPointcut(Type attribute, bool inherit, bool checkInterfaces)
|
||||
{
|
||||
Attribute = attribute;
|
||||
Inherit = inherit;
|
||||
CheckInterfaces = checkInterfaces;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected AttributeMatchMethodPointcut(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
Inherit = info.GetBoolean("Inherit");
|
||||
CheckInterfaces = info.GetBoolean("CheckInterfaces");
|
||||
var type = info.GetString("Attribute");
|
||||
Attribute = type != null ? Type.GetType(type) : null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("Attribute", Attribute?.AssemblyQualifiedName);
|
||||
info.AddValue("Inherit", Inherit);
|
||||
info.AddValue("CheckInterfaces", CheckInterfaces);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </summary>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If the supplied value is not a <see cref="System.Type"/> that
|
||||
/// derives from the <see cref="System.Attribute"/> class.
|
||||
/// </exception>
|
||||
public virtual Type Attribute
|
||||
{
|
||||
get { return _attribute; }
|
||||
set
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.AttributeMatchMethodPointcut"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </param>
|
||||
/// <param name="inherit">
|
||||
/// Flag that controls whether or not the inheritance tree of the
|
||||
/// method to be included in the search for the <see cref="Attribute"/>?
|
||||
/// </param>
|
||||
public AttributeMatchMethodPointcut(Type attribute, bool inherit)
|
||||
: this(attribute, inherit, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.AttributeMatchMethodPointcut"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </param>
|
||||
/// <param name="inherit">
|
||||
/// Flag that controls whether or not the inheritance tree of the
|
||||
/// method to be included in the search for the <see cref="Attribute"/>?
|
||||
/// </param>
|
||||
/// <param name="checkInterfaces">
|
||||
/// Flag that controls whether or not interfaces attributes of the
|
||||
/// method to be included in the search for the <see cref="Attribute"/>?
|
||||
/// </param>
|
||||
public AttributeMatchMethodPointcut(Type attribute, bool inherit, bool checkInterfaces)
|
||||
{
|
||||
Attribute = attribute;
|
||||
Inherit = inherit;
|
||||
CheckInterfaces = checkInterfaces;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected AttributeMatchMethodPointcut(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
Inherit = info.GetBoolean("Inherit");
|
||||
CheckInterfaces = info.GetBoolean("CheckInterfaces");
|
||||
var type = info.GetString("Attribute");
|
||||
Attribute = type != null ? Type.GetType(type) : null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("Attribute", Attribute?.AssemblyQualifiedName);
|
||||
info.AddValue("Inherit", Inherit);
|
||||
info.AddValue("CheckInterfaces", CheckInterfaces);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </summary>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If the supplied value is not a <see cref="System.Type"/> that
|
||||
/// derives from the <see cref="System.Attribute"/> class.
|
||||
/// </exception>
|
||||
public virtual Type Attribute
|
||||
{
|
||||
get { return _attribute; }
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
if (!typeof (Attribute).IsAssignableFrom(value))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
string.Format(
|
||||
"The [{0}] Type must be derived from the [System.Attribute] class.",
|
||||
value));
|
||||
}
|
||||
}
|
||||
_attribute = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the inheritance tree of the method to be included in the search for the
|
||||
/// <see cref="Attribute"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default is <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual bool Inherit
|
||||
{
|
||||
get { return _inherit; }
|
||||
set { _inherit = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the interfaces attributes of the method to be included in the search for theg
|
||||
/// <see cref="Attribute"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default is <see langword="false"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual bool CheckInterfaces
|
||||
{
|
||||
get { return _checkInterfaces; }
|
||||
set { _checkInterfaces = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
public override bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
if (method.IsDefined(Attribute, Inherit))
|
||||
if (value != null)
|
||||
{
|
||||
// Checks whether the attribute is defined on the method or a super definition of the method
|
||||
// but does not check attributes on implemented interfaces.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckInterfaces)
|
||||
if (!typeof(Attribute).IsAssignableFrom(value))
|
||||
{
|
||||
// Also check whether the attribute is defined on a method implemented from an interface.
|
||||
// First find all interfaces for the type that contains the method.
|
||||
// Next, check each interface for the presence of the attribute on the corresponding
|
||||
// method from the interface.
|
||||
Type[] parameterTypes = ReflectionUtils.GetParameterTypes(method);
|
||||
foreach (Type interfaceType in method.DeclaringType.GetInterfaces())
|
||||
{
|
||||
// The method may be implemented explicitly, so the method name
|
||||
// will include the interface name also
|
||||
string methodName = method.Name;
|
||||
if (methodName.IndexOf('.') != -1)
|
||||
{
|
||||
if (methodName.StartsWith(interfaceType.FullName.Replace('+', '.')))
|
||||
{
|
||||
methodName = methodName.Remove(0, interfaceType.FullName.Length + 1);
|
||||
}
|
||||
}
|
||||
throw new ArgumentException(
|
||||
string.Format(
|
||||
"The [{0}] Type must be derived from the [System.Attribute] class.",
|
||||
value));
|
||||
}
|
||||
}
|
||||
|
||||
MethodInfo intfMethod = interfaceType.GetMethod(methodName, parameterTypes);
|
||||
if (intfMethod != null && intfMethod.IsDefined(Attribute, Inherit))
|
||||
_attribute = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the inheritance tree of the method to be included in the search for the
|
||||
/// <see cref="Attribute"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default is <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual bool Inherit
|
||||
{
|
||||
get { return _inherit; }
|
||||
set { _inherit = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the interfaces attributes of the method to be included in the search for theg
|
||||
/// <see cref="Attribute"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The default is <see langword="false"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public virtual bool CheckInterfaces
|
||||
{
|
||||
get { return _checkInterfaces; }
|
||||
set { _checkInterfaces = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
public override bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
if (method.IsDefined(Attribute, Inherit))
|
||||
{
|
||||
// Checks whether the attribute is defined on the method or a super definition of the method
|
||||
// but does not check attributes on implemented interfaces.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckInterfaces)
|
||||
{
|
||||
// Also check whether the attribute is defined on a method implemented from an interface.
|
||||
// First find all interfaces for the type that contains the method.
|
||||
// Next, check each interface for the presence of the attribute on the corresponding
|
||||
// method from the interface.
|
||||
Type[] parameterTypes = ReflectionUtils.GetParameterTypes(method);
|
||||
foreach (Type interfaceType in method.DeclaringType.GetInterfaces())
|
||||
{
|
||||
// The method may be implemented explicitly, so the method name
|
||||
// will include the interface name also
|
||||
string methodName = method.Name;
|
||||
if (methodName.IndexOf('.') != -1)
|
||||
{
|
||||
if (methodName.StartsWith(interfaceType.FullName.Replace('+', '.')))
|
||||
{
|
||||
return true;
|
||||
methodName = methodName.Remove(0, interfaceType.FullName.Length + 1);
|
||||
}
|
||||
}
|
||||
|
||||
MethodInfo intfMethod = interfaceType.GetMethod(methodName, parameterTypes);
|
||||
if (intfMethod != null && intfMethod.IsDefined(Attribute, Inherit))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,133 +21,131 @@
|
||||
#region Imports
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using AopAlliance.Aop;
|
||||
using Spring.Core;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Convenient class for attribute-match method pointcuts that hold an Interceptor,
|
||||
/// making them an Advisor.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
[Serializable]
|
||||
public class AttributeMatchMethodPointcutAdvisor
|
||||
: AttributeMatchMethodPointcut, IPointcutAdvisor, IOrdered, ISerializable
|
||||
{
|
||||
/// <summary>
|
||||
/// Convenient class for attribute-match method pointcuts that hold an Interceptor,
|
||||
/// making them an Advisor.
|
||||
/// </summary>
|
||||
/// <author>Bruno Baia</author>
|
||||
[Serializable]
|
||||
public class AttributeMatchMethodPointcutAdvisor
|
||||
: AttributeMatchMethodPointcut, IPointcutAdvisor, IOrdered, ISerializable
|
||||
{
|
||||
private int _order = Int32.MaxValue;
|
||||
private IAdvice _advice;
|
||||
private int _order = Int32.MaxValue;
|
||||
private IAdvice _advice;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AttributeMatchMethodPointcutAdvisor"/> class.
|
||||
/// </summary>
|
||||
public AttributeMatchMethodPointcutAdvisor()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AttributeMatchMethodPointcutAdvisor"/> class.
|
||||
/// </summary>
|
||||
public AttributeMatchMethodPointcutAdvisor()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AttributeMatchMethodPointcutAdvisor"/> class
|
||||
/// for the supplied <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">the advice to apply if the pointcut matches</param>
|
||||
public AttributeMatchMethodPointcutAdvisor(IAdvice advice)
|
||||
{
|
||||
this._advice = advice;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AttributeMatchMethodPointcutAdvisor"/> class
|
||||
/// for the supplied <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">the advice to apply if the pointcut matches</param>
|
||||
public AttributeMatchMethodPointcutAdvisor(IAdvice advice)
|
||||
{
|
||||
this._advice = advice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AttributeMatchMethodPointcutAdvisor"/> class
|
||||
/// for the supplied <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </param>
|
||||
/// <param name="inherit">
|
||||
/// Flag that controls whether or not the inheritance tree of the
|
||||
/// method to be included in the search for the <see cref="Attribute"/>?
|
||||
/// </param>
|
||||
/// <param name="advice">the advice to apply if the pointcut matches</param>
|
||||
public AttributeMatchMethodPointcutAdvisor(Type attribute, bool inherit, IAdvice advice)
|
||||
:base(attribute, inherit)
|
||||
{
|
||||
this._advice = advice;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="AttributeMatchMethodPointcutAdvisor"/> class
|
||||
/// for the supplied <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// The <see cref="System.Attribute"/> to match.
|
||||
/// </param>
|
||||
/// <param name="inherit">
|
||||
/// Flag that controls whether or not the inheritance tree of the
|
||||
/// method to be included in the search for the <see cref="Attribute"/>?
|
||||
/// </param>
|
||||
/// <param name="advice">the advice to apply if the pointcut matches</param>
|
||||
public AttributeMatchMethodPointcutAdvisor(Type attribute, bool inherit, IAdvice advice)
|
||||
: base(attribute, inherit)
|
||||
{
|
||||
this._advice = advice;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
private AttributeMatchMethodPointcutAdvisor(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
Order = info.GetInt32("Order");
|
||||
Advice = (IAdvice) info.GetValue("Advice", typeof(IAdvice));
|
||||
}
|
||||
/// <inheritdoc />
|
||||
private AttributeMatchMethodPointcutAdvisor(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
Order = info.GetInt32("Order");
|
||||
Advice = (IAdvice) info.GetValue("Advice", typeof(IAdvice));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
info.AddValue("Order", Order);
|
||||
info.AddValue("Advice", Advice);
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
info.AddValue("Order", Order);
|
||||
info.AddValue("Advice", Advice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
/// <exception cref="System.NotSupportedException">
|
||||
/// Always; this property is not yet supported.
|
||||
/// </exception>
|
||||
public virtual bool IsPerInstance
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
"The 'IsPerInstance' property of the IAdvisor interface is " +
|
||||
"not yet supported in Spring.NET.");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
/// <exception cref="System.NotSupportedException">
|
||||
/// Always; this property is not yet supported.
|
||||
/// </exception>
|
||||
public virtual bool IsPerInstance
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
"The 'IsPerInstance' property of the IAdvisor interface is " +
|
||||
"not yet supported in Spring.NET.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// This <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </returns>
|
||||
public virtual int Order
|
||||
{
|
||||
get { return this._order; }
|
||||
set { this._order = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns this <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// This <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </returns>
|
||||
public virtual int Order
|
||||
{
|
||||
get { return this._order; }
|
||||
set { this._order = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this advisor.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/>
|
||||
public virtual IAdvice Advice
|
||||
{
|
||||
get { return this._advice; }
|
||||
set { this._advice = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Return the advice part of this advisor.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/>
|
||||
public virtual IAdvice Advice
|
||||
{
|
||||
get { return this._advice; }
|
||||
set { this._advice = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
public virtual IPointcut Pointcut
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
public virtual IPointcut Pointcut
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,102 +20,102 @@
|
||||
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Pointcut that looks for a specific attribute being present on a class or
|
||||
/// method.
|
||||
/// </summary>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
[Serializable]
|
||||
public class AttributeMatchingPointcut : IPointcut
|
||||
{
|
||||
private readonly ITypeFilter typeFilter;
|
||||
private readonly IMethodMatcher methodMatcher;
|
||||
|
||||
/// <summary>
|
||||
/// Pointcut that looks for a specific attribute being present on a class or
|
||||
/// method.
|
||||
/// Initializes a new instance of the <see cref="AttributeMatchingPointcut"/> class for the
|
||||
/// given attribute type.
|
||||
/// </summary>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
[Serializable]
|
||||
public class AttributeMatchingPointcut : IPointcut
|
||||
/// <param name="attributeType">Type of the attribute to look for at the class level.</param>
|
||||
public AttributeMatchingPointcut(Type attributeType)
|
||||
{
|
||||
private readonly ITypeFilter typeFilter;
|
||||
private readonly IMethodMatcher methodMatcher;
|
||||
ValidateAttributeTypeArgument(attributeType);
|
||||
this.typeFilter = new AttributeTypeFilter(attributeType);
|
||||
this.methodMatcher = TrueMethodMatcher.True;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeMatchingPointcut"/> class for the
|
||||
/// given attribute type
|
||||
/// </summary>
|
||||
/// <param name="attributeType">Type of the attribute.</param>
|
||||
/// <param name="checkInherited">if set to <c>true</c> [check inherited].</param>
|
||||
public AttributeMatchingPointcut(Type attributeType, bool checkInherited)
|
||||
{
|
||||
ValidateAttributeTypeArgument(attributeType);
|
||||
this.typeFilter = new AttributeTypeFilter(attributeType, checkInherited);
|
||||
this.methodMatcher = TrueMethodMatcher.True;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeMatchingPointcut"/> class for the
|
||||
/// given attribute type.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">Type of the attribute to look for at the class level.</param>
|
||||
public AttributeMatchingPointcut(Type attributeType)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeMatchingPointcut"/> class for the given
|
||||
/// attribute type
|
||||
/// </summary>
|
||||
/// <param name="classAttributeType">The attribute type to look for at the class level.</param>
|
||||
/// <param name="methodAttributeType">The attribute type to look for at the method attribute.</param>
|
||||
public AttributeMatchingPointcut(Type classAttributeType, Type methodAttributeType)
|
||||
{
|
||||
AssertUtils.IsTrue(classAttributeType != null || methodAttributeType != null,
|
||||
"Either Type attribute type or Method attribute type needs to be specified (or both)");
|
||||
|
||||
if (classAttributeType != null)
|
||||
{
|
||||
this.typeFilter = new AttributeTypeFilter(classAttributeType);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.typeFilter = TrueTypeFilter.True;
|
||||
}
|
||||
|
||||
if (methodAttributeType != null)
|
||||
{
|
||||
this.methodMatcher = new AttributeMethodMatcher(methodAttributeType);
|
||||
}
|
||||
else
|
||||
{
|
||||
ValidateAttributeTypeArgument(attributeType);
|
||||
this.typeFilter = new AttributeTypeFilter(attributeType);
|
||||
this.methodMatcher = TrueMethodMatcher.True;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeMatchingPointcut"/> class for the
|
||||
/// given attribute type
|
||||
/// </summary>
|
||||
/// <param name="attributeType">Type of the attribute.</param>
|
||||
/// <param name="checkInherited">if set to <c>true</c> [check inherited].</param>
|
||||
public AttributeMatchingPointcut(Type attributeType, bool checkInherited)
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>The current <see cref="Spring.Aop.ITypeFilter"/>.</value>
|
||||
public ITypeFilter TypeFilter
|
||||
{
|
||||
get { return this.typeFilter; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>The current <see cref="Spring.Aop.IMethodMatcher"/>.</value>
|
||||
public IMethodMatcher MethodMatcher
|
||||
{
|
||||
get { return this.methodMatcher; }
|
||||
}
|
||||
|
||||
private static void ValidateAttributeTypeArgument(Type attributeType)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(attributeType, "attributeType");
|
||||
if (!typeof(Attribute).IsAssignableFrom(attributeType))
|
||||
{
|
||||
ValidateAttributeTypeArgument(attributeType);
|
||||
this.typeFilter = new AttributeTypeFilter(attributeType, checkInherited);
|
||||
this.methodMatcher = TrueMethodMatcher.True;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeMatchingPointcut"/> class for the given
|
||||
/// attribute type
|
||||
/// </summary>
|
||||
/// <param name="classAttributeType">The attribute type to look for at the class level.</param>
|
||||
/// <param name="methodAttributeType">The attribute type to look for at the method attribute.</param>
|
||||
public AttributeMatchingPointcut(Type classAttributeType, Type methodAttributeType)
|
||||
{
|
||||
AssertUtils.IsTrue(classAttributeType != null || methodAttributeType != null,
|
||||
"Either Type attribute type or Method attribute type needs to be specified (or both)");
|
||||
|
||||
if (classAttributeType != null)
|
||||
{
|
||||
this.typeFilter = new AttributeTypeFilter(classAttributeType);
|
||||
} else
|
||||
{
|
||||
this.typeFilter = TrueTypeFilter.True;
|
||||
}
|
||||
|
||||
if (methodAttributeType != null)
|
||||
{
|
||||
this.methodMatcher = new AttributeMethodMatcher(methodAttributeType);
|
||||
} else
|
||||
{
|
||||
this.methodMatcher = TrueMethodMatcher.True;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>The current <see cref="Spring.Aop.ITypeFilter"/>.</value>
|
||||
public ITypeFilter TypeFilter
|
||||
{
|
||||
get { return this.typeFilter; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>The current <see cref="Spring.Aop.IMethodMatcher"/>.</value>
|
||||
public IMethodMatcher MethodMatcher
|
||||
{
|
||||
get { return this.methodMatcher; }
|
||||
}
|
||||
|
||||
private static void ValidateAttributeTypeArgument(Type attributeType)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(attributeType, "attributeType");
|
||||
if (!typeof(Attribute).IsAssignableFrom(attributeType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
string.Format(
|
||||
"The [{0}] Type must be derived from the [System.Attribute] class.",
|
||||
attributeType));
|
||||
}
|
||||
throw new ArgumentException(
|
||||
string.Format(
|
||||
"The [{0}] Type must be derived from the [System.Attribute] class.",
|
||||
attributeType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,105 +20,101 @@
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// MethodMatcher that looks for a specific attribute being present on the
|
||||
/// method (checking both the method on the onviked interface, if any and the corresponding
|
||||
/// method on the target class
|
||||
/// </summary>
|
||||
/// <author>Juergen hoeller</author>
|
||||
/// <author>Mark Pollack</author>
|
||||
/// <seealso cref="AttributeMatchingPointcut"/>
|
||||
[Serializable]
|
||||
public class AttributeMethodMatcher : StaticMethodMatcher, ISerializable
|
||||
{
|
||||
private readonly Type attributeType;
|
||||
|
||||
/// <summary>
|
||||
/// MethodMatcher that looks for a specific attribute being present on the
|
||||
/// method (checking both the method on the onviked interface, if any and the corresponding
|
||||
/// method on the target class
|
||||
/// Initializes a new instance of the <see cref="AttributeMethodMatcher"/> class for the
|
||||
/// given atribute type.
|
||||
/// </summary>
|
||||
/// <author>Juergen hoeller</author>
|
||||
/// <author>Mark Pollack</author>
|
||||
/// <seealso cref="AttributeMatchingPointcut"/>
|
||||
[Serializable]
|
||||
public class AttributeMethodMatcher : StaticMethodMatcher, ISerializable
|
||||
/// <param name="attributeType">Type of the attribute to look for.</param>
|
||||
public AttributeMethodMatcher(Type attributeType)
|
||||
{
|
||||
private readonly Type attributeType;
|
||||
ValidateAttributeTypeArgument(attributeType);
|
||||
this.attributeType = attributeType;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
private AttributeMethodMatcher(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
var type = info.GetString("AttributeType");
|
||||
attributeType = type != null ? Type.GetType(type) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeMethodMatcher"/> class for the
|
||||
/// given atribute type.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">Type of the attribute to look for.</param>
|
||||
public AttributeMethodMatcher(Type attributeType)
|
||||
/// <inheritdoc />
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("AttributeType", attributeType?.AssemblyQualifiedName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Must be implemented by a derived class in order to specify matching
|
||||
/// rules.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public override bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
if (method.IsDefined(attributeType, true))
|
||||
{
|
||||
ValidateAttributeTypeArgument(attributeType);
|
||||
this.attributeType = attributeType;
|
||||
// Checks whether the attribute is defined on the method or a super definition of the method
|
||||
// but does not check attributes on implemented interfaces.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
private AttributeMethodMatcher(SerializationInfo info, StreamingContext context)
|
||||
else
|
||||
{
|
||||
var type = info.GetString("AttributeType");
|
||||
attributeType = type != null ? Type.GetType(type) : null;
|
||||
}
|
||||
Type[] parameterTypes = ReflectionUtils.GetParameterTypes(method);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("AttributeType", attributeType?.AssemblyQualifiedName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Must be implemented by a derived class in order to specify matching
|
||||
/// rules.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public override bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
if (method.IsDefined(attributeType, true))
|
||||
// Also check whether the attribute is defined on a method implemented from an interface.
|
||||
// First find all interfaces for the type that contains the method.
|
||||
// Next, check each interface for the presence of the attribute on the corresponding
|
||||
// method from the interface.
|
||||
foreach (Type interfaceType in method.DeclaringType.GetInterfaces())
|
||||
{
|
||||
// Checks whether the attribute is defined on the method or a super definition of the method
|
||||
// but does not check attributes on implemented interfaces.
|
||||
return true;
|
||||
MethodInfo intfMethod = interfaceType.GetMethod(method.Name, parameterTypes);
|
||||
if (intfMethod != null && intfMethod.IsDefined(attributeType, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Type[] parameterTypes = ReflectionUtils.GetParameterTypes(method);
|
||||
|
||||
// Also check whether the attribute is defined on a method implemented from an interface.
|
||||
// First find all interfaces for the type that contains the method.
|
||||
// Next, check each interface for the presence of the attribute on the corresponding
|
||||
// method from the interface.
|
||||
foreach (Type interfaceType in method.DeclaringType.GetInterfaces())
|
||||
{
|
||||
MethodInfo intfMethod = interfaceType.GetMethod(method.Name, parameterTypes);
|
||||
if (intfMethod != null && intfMethod.IsDefined(attributeType, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateAttributeTypeArgument(Type attributeType)
|
||||
private static void ValidateAttributeTypeArgument(Type attributeType)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(attributeType, "attributeType");
|
||||
if (!typeof(Attribute).IsAssignableFrom(attributeType))
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(attributeType, "attributeType");
|
||||
if (!typeof(Attribute).IsAssignableFrom(attributeType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
string.Format(
|
||||
"The [{0}] Type must be derived from the [System.Attribute] class.",
|
||||
attributeType));
|
||||
}
|
||||
throw new ArgumentException(
|
||||
string.Format(
|
||||
"The [{0}] Type must be derived from the [System.Attribute] class.",
|
||||
attributeType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,88 +20,86 @@
|
||||
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// ITypeFilter that looks for a specific attribute being present on a class
|
||||
/// </summary>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
public class AttributeTypeFilter : ITypeFilter
|
||||
{
|
||||
private readonly Type attributeType;
|
||||
private readonly bool checkInherited;
|
||||
|
||||
/// <summary>
|
||||
/// ITypeFilter that looks for a specific attribute being present on a class
|
||||
/// The attribute <see cref="Type"/> for this filter.
|
||||
/// </summary>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
public class AttributeTypeFilter : ITypeFilter
|
||||
public Type AttributeType
|
||||
{
|
||||
private readonly Type attributeType;
|
||||
private readonly bool checkInherited;
|
||||
get { return attributeType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The attribute <see cref="Type"/> for this filter.
|
||||
/// </summary>
|
||||
public Type AttributeType
|
||||
/// <summary>
|
||||
/// Indicates, whether this filter considers base types for filtering.
|
||||
/// </summary>
|
||||
public bool CheckInherited
|
||||
{
|
||||
get { return checkInherited; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeTypeFilter"/> class for the
|
||||
/// given attribute type.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">Type of the attribute to look for.</param>
|
||||
public AttributeTypeFilter(Type attributeType) : this(attributeType, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeTypeFilter"/> class for the
|
||||
/// given attribute type.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">Type of the attribute.</param>
|
||||
/// <param name="checkInherited">if set to <c>true</c> [check inherited].</param>
|
||||
public AttributeTypeFilter(Type attributeType, bool checkInherited)
|
||||
{
|
||||
#region parameter validation
|
||||
|
||||
AssertUtils.ArgumentNotNull(attributeType, "attributeType");
|
||||
if (!typeof(Attribute).IsAssignableFrom(attributeType))
|
||||
{
|
||||
get { return attributeType; }
|
||||
throw new ArgumentException(
|
||||
string.Format(
|
||||
"The [{0}] Type must be derived from the [System.Attribute] class.",
|
||||
attributeType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates, whether this filter considers base types for filtering.
|
||||
/// </summary>
|
||||
public bool CheckInherited
|
||||
#endregion
|
||||
|
||||
this.attributeType = attributeType;
|
||||
this.checkInherited = checkInherited;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <param name="type">The candidate <see cref="System.Type"/>.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
public bool Matches(Type type)
|
||||
{
|
||||
if (checkInherited)
|
||||
{
|
||||
get { return checkInherited; }
|
||||
return AttributeUtils.FindAttribute(type, attributeType) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeTypeFilter"/> class for the
|
||||
/// given attribute type.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">Type of the attribute to look for.</param>
|
||||
public AttributeTypeFilter(Type attributeType) : this(attributeType, false)
|
||||
else
|
||||
{
|
||||
|
||||
object[] atts = type.GetCustomAttributes(attributeType, false);
|
||||
return ArrayUtils.HasLength(atts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributeTypeFilter"/> class for the
|
||||
/// given attribute type.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">Type of the attribute.</param>
|
||||
/// <param name="checkInherited">if set to <c>true</c> [check inherited].</param>
|
||||
public AttributeTypeFilter(Type attributeType, bool checkInherited)
|
||||
{
|
||||
#region parameter validation
|
||||
AssertUtils.ArgumentNotNull(attributeType, "attributeType");
|
||||
if (!typeof(Attribute).IsAssignableFrom(attributeType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
string.Format(
|
||||
"The [{0}] Type must be derived from the [System.Attribute] class.",
|
||||
attributeType));
|
||||
}
|
||||
#endregion
|
||||
this.attributeType = attributeType;
|
||||
this.checkInherited = checkInherited;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <param name="type">The candidate <see cref="System.Type"/>.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
public bool Matches(Type type)
|
||||
{
|
||||
if (checkInherited)
|
||||
{
|
||||
return AttributeUtils.FindAttribute(type, attributeType) != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
object[] atts = type.GetCustomAttributes(attributeType, false);
|
||||
return ArrayUtils.HasLength(atts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,152 +22,151 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Convenient class for building up pointcuts.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// All methods return a <see cref="Spring.Aop.Support.ComposablePointcut"/>
|
||||
/// instance, which facilitates the following concise usage pattern...
|
||||
/// </p>
|
||||
/// <code language="C#">
|
||||
/// IPointcut pointcut = new ComposablePointcut()
|
||||
/// .Union(typeFilter)
|
||||
/// .Intersection(methodMatcher)
|
||||
/// .Intersection(pointcut);
|
||||
/// </code>
|
||||
/// <p>
|
||||
/// There is no <c>Union()</c> method on this class. Use the
|
||||
/// <see cref="Spring.Aop.Support.Pointcuts.Union"/> method for such functionality.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class ComposablePointcut : IPointcut
|
||||
{
|
||||
/// <summary>
|
||||
/// Convenient class for building up pointcuts.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// All methods return a <see cref="Spring.Aop.Support.ComposablePointcut"/>
|
||||
/// instance, which facilitates the following concise usage pattern...
|
||||
/// </p>
|
||||
/// <code language="C#">
|
||||
/// IPointcut pointcut = new ComposablePointcut()
|
||||
/// .Union(typeFilter)
|
||||
/// .Intersection(methodMatcher)
|
||||
/// .Intersection(pointcut);
|
||||
/// </code>
|
||||
/// <p>
|
||||
/// There is no <c>Union()</c> method on this class. Use the
|
||||
/// <see cref="Spring.Aop.Support.Pointcuts.Union"/> method for such functionality.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class ComposablePointcut : IPointcut
|
||||
{
|
||||
private ITypeFilter _typeFilter;
|
||||
private IMethodMatcher _methodMatcher;
|
||||
private ITypeFilter _typeFilter;
|
||||
private IMethodMatcher _methodMatcher;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.ComposablePointcut"/> class
|
||||
/// that matches all the methods on all <see cref="System.Type"/>s.
|
||||
/// </summary>
|
||||
public ComposablePointcut()
|
||||
{
|
||||
_typeFilter = TrueTypeFilter.True;
|
||||
_methodMatcher = TrueMethodMatcher.True;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.ComposablePointcut"/> class
|
||||
/// that matches all the methods on all <see cref="System.Type"/>s.
|
||||
/// </summary>
|
||||
public ComposablePointcut()
|
||||
{
|
||||
_typeFilter = TrueTypeFilter.True;
|
||||
_methodMatcher = TrueMethodMatcher.True;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.ComposablePointcut"/> class
|
||||
/// that uses the supplied <paramref name="typeFilter"/> and
|
||||
/// <paramref name="methodMatcher"/>.
|
||||
/// </summary>
|
||||
/// <param name="typeFilter">
|
||||
/// The type filter to use.
|
||||
/// </param>
|
||||
/// <param name="methodMatcher">
|
||||
/// The method matcher to use.
|
||||
/// </param>
|
||||
public ComposablePointcut(ITypeFilter typeFilter, IMethodMatcher methodMatcher)
|
||||
{
|
||||
_typeFilter = typeFilter;
|
||||
_methodMatcher = methodMatcher;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.ComposablePointcut"/> class
|
||||
/// that uses the supplied <paramref name="typeFilter"/> and
|
||||
/// <paramref name="methodMatcher"/>.
|
||||
/// </summary>
|
||||
/// <param name="typeFilter">
|
||||
/// The type filter to use.
|
||||
/// </param>
|
||||
/// <param name="methodMatcher">
|
||||
/// The method matcher to use.
|
||||
/// </param>
|
||||
public ComposablePointcut(ITypeFilter typeFilter, IMethodMatcher methodMatcher)
|
||||
{
|
||||
_typeFilter = typeFilter;
|
||||
_methodMatcher = methodMatcher;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
public virtual ITypeFilter TypeFilter
|
||||
{
|
||||
get { return _typeFilter; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
public virtual ITypeFilter TypeFilter
|
||||
{
|
||||
get { return _typeFilter; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </value>
|
||||
public virtual IMethodMatcher MethodMatcher
|
||||
{
|
||||
get { return _methodMatcher; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </value>
|
||||
public virtual IMethodMatcher MethodMatcher
|
||||
{
|
||||
get { return _methodMatcher; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the current type filter to be the union of the existing filter and the
|
||||
/// supplied <paramref name="filter"/>.
|
||||
/// </summary>
|
||||
/// <param name="filter">The filter to union with.</param>
|
||||
/// <returns>
|
||||
/// The union of the existing filter and the supplied <paramref name="filter"/>.
|
||||
/// </returns>
|
||||
public virtual ComposablePointcut Union(ITypeFilter filter)
|
||||
{
|
||||
_typeFilter = TypeFilters.Union(_typeFilter, filter);
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes the current type filter to be the union of the existing filter and the
|
||||
/// supplied <paramref name="filter"/>.
|
||||
/// </summary>
|
||||
/// <param name="filter">The filter to union with.</param>
|
||||
/// <returns>
|
||||
/// The union of the existing filter and the supplied <paramref name="filter"/>.
|
||||
/// </returns>
|
||||
public virtual ComposablePointcut Union(ITypeFilter filter)
|
||||
{
|
||||
_typeFilter = TypeFilters.Union(_typeFilter, filter);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the current type filter to be the intersection of the existing filter
|
||||
/// and the supplied <paramref name="filter"/>.
|
||||
/// </summary>
|
||||
/// <param name="filter">The filter to diff against.</param>
|
||||
/// <returns>
|
||||
/// The intersection of the existing filter and the supplied <paramref name="filter"/>.
|
||||
/// </returns>
|
||||
public virtual ComposablePointcut Intersection(ITypeFilter filter)
|
||||
{
|
||||
_typeFilter = TypeFilters.Intersection(_typeFilter, filter);
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes the current type filter to be the intersection of the existing filter
|
||||
/// and the supplied <paramref name="filter"/>.
|
||||
/// </summary>
|
||||
/// <param name="filter">The filter to diff against.</param>
|
||||
/// <returns>
|
||||
/// The intersection of the existing filter and the supplied <paramref name="filter"/>.
|
||||
/// </returns>
|
||||
public virtual ComposablePointcut Intersection(ITypeFilter filter)
|
||||
{
|
||||
_typeFilter = TypeFilters.Intersection(_typeFilter, filter);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the current method matcher to be the union of the existing matcher and the
|
||||
/// supplied <paramref name="matcher"/>.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher to union with.</param>
|
||||
/// <returns>
|
||||
/// The union of the existing matcher and the supplied <paramref name="matcher"/>.
|
||||
/// </returns>
|
||||
public virtual ComposablePointcut Union(IMethodMatcher matcher)
|
||||
{
|
||||
_methodMatcher = MethodMatchers.Union(_methodMatcher, matcher);
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes the current method matcher to be the union of the existing matcher and the
|
||||
/// supplied <paramref name="matcher"/>.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher to union with.</param>
|
||||
/// <returns>
|
||||
/// The union of the existing matcher and the supplied <paramref name="matcher"/>.
|
||||
/// </returns>
|
||||
public virtual ComposablePointcut Union(IMethodMatcher matcher)
|
||||
{
|
||||
_methodMatcher = MethodMatchers.Union(_methodMatcher, matcher);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the current method matcher to be the intersection of the existing matcher
|
||||
/// and the supplied <paramref name="matcher"/>.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher to diff against.</param>
|
||||
/// <returns>
|
||||
/// The intersection of the existing matcher and the supplied <paramref name="matcher"/>.
|
||||
/// </returns>
|
||||
public virtual ComposablePointcut Intersection(IMethodMatcher matcher)
|
||||
{
|
||||
_methodMatcher = MethodMatchers.Intersection(_methodMatcher, matcher);
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes the current method matcher to be the intersection of the existing matcher
|
||||
/// and the supplied <paramref name="matcher"/>.
|
||||
/// </summary>
|
||||
/// <param name="matcher">The matcher to diff against.</param>
|
||||
/// <returns>
|
||||
/// The intersection of the existing matcher and the supplied <paramref name="matcher"/>.
|
||||
/// </returns>
|
||||
public virtual ComposablePointcut Intersection(IMethodMatcher matcher)
|
||||
{
|
||||
_methodMatcher = MethodMatchers.Intersection(_methodMatcher, matcher);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes current pointcut to intersection of the current and supplied pointcut
|
||||
/// </summary>
|
||||
/// <param name="other">pointcut to diff against</param>
|
||||
/// <returns>updated pointcut</returns>
|
||||
public virtual ComposablePointcut Intersection(IPointcut other)
|
||||
{
|
||||
_typeFilter = TypeFilters.Intersection(_typeFilter, other.TypeFilter);
|
||||
_methodMatcher = MethodMatchers.Intersection(_methodMatcher, other.MethodMatcher);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes current pointcut to intersection of the current and supplied pointcut
|
||||
/// </summary>
|
||||
/// <param name="other">pointcut to diff against</param>
|
||||
/// <returns>updated pointcut</returns>
|
||||
public virtual ComposablePointcut Intersection(IPointcut other)
|
||||
{
|
||||
_typeFilter = TypeFilters.Intersection(_typeFilter, other.TypeFilter);
|
||||
_methodMatcher = MethodMatchers.Intersection(_methodMatcher, other.MethodMatcher);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,222 +16,220 @@
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using Spring.Core;
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Pointcut and method matcher for use in simple <b>cflow</b>-style
|
||||
/// pointcuts.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Evaluating such pointcuts is slower than evaluating normal pointcuts,
|
||||
/// but can nevertheless be useful in some cases. Of course, your mileage
|
||||
/// may vary as to what 'slower' actually means.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Simon White (.NET)</author>
|
||||
[Serializable]
|
||||
public class ControlFlowPointcut : IPointcut, ITypeFilter, IMethodMatcher, ISerializable
|
||||
{
|
||||
/// <summary>
|
||||
/// Pointcut and method matcher for use in simple <b>cflow</b>-style
|
||||
/// pointcuts.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Evaluating such pointcuts is slower than evaluating normal pointcuts,
|
||||
/// but can nevertheless be useful in some cases. Of course, your mileage
|
||||
/// may vary as to what 'slower' actually means.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Simon White (.NET)</author>
|
||||
[Serializable]
|
||||
public class ControlFlowPointcut : IPointcut, ITypeFilter, IMethodMatcher, ISerializable
|
||||
{
|
||||
private Type _type;
|
||||
private string _methodName;
|
||||
private int _evaluationCount;
|
||||
private Type _type;
|
||||
private string _methodName;
|
||||
private int _evaluationCount;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ControlFlowPointcut"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// The class under which <b>all</b> control flows are to be matched.
|
||||
/// </param>
|
||||
public ControlFlowPointcut(Type type) : this(type, null)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ControlFlowPointcut"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// The class under which <b>all</b> control flows are to be matched.
|
||||
/// </param>
|
||||
public ControlFlowPointcut(Type type) : this(type, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new pointcut that matches all calls below the
|
||||
/// given method in the given class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If the supplied <paramref name="methodName"/> is
|
||||
/// <see langword="null"/>, <b>all</b> control flows below the given
|
||||
/// class will be successfully matched.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The class under which <b>all</b> control flows are to be matched.
|
||||
/// </param>
|
||||
/// <param name="methodName">
|
||||
/// The method name under which <b>all</b> control flows are to be matched.
|
||||
/// </param>
|
||||
public ControlFlowPointcut(Type type, string methodName)
|
||||
{
|
||||
_type = type;
|
||||
_methodName = methodName;
|
||||
}
|
||||
/// <summary>
|
||||
/// Construct a new pointcut that matches all calls below the
|
||||
/// given method in the given class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If the supplied <paramref name="methodName"/> is
|
||||
/// <see langword="null"/>, <b>all</b> control flows below the given
|
||||
/// class will be successfully matched.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The class under which <b>all</b> control flows are to be matched.
|
||||
/// </param>
|
||||
/// <param name="methodName">
|
||||
/// The method name under which <b>all</b> control flows are to be matched.
|
||||
/// </param>
|
||||
public ControlFlowPointcut(Type type, string methodName)
|
||||
{
|
||||
_type = type;
|
||||
_methodName = methodName;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
private ControlFlowPointcut(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
var type = info.GetString("Type");
|
||||
_type = type != null ? Type.GetType(type) : null;
|
||||
_methodName = info.GetString("MethodName");
|
||||
_evaluationCount = info.GetInt32("EvaluationCount");
|
||||
}
|
||||
/// <inheritdoc />
|
||||
private ControlFlowPointcut(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
var type = info.GetString("Type");
|
||||
_type = type != null ? Type.GetType(type) : null;
|
||||
_methodName = info.GetString("MethodName");
|
||||
_evaluationCount = info.GetInt32("EvaluationCount");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("Type", _type?.AssemblyQualifiedName);
|
||||
info.AddValue("MethodName", _methodName);
|
||||
info.AddValue("EvaluationCount", _evaluationCount);
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("Type", _type?.AssemblyQualifiedName);
|
||||
info.AddValue("MethodName", _methodName);
|
||||
info.AddValue("EvaluationCount", _evaluationCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
public ITypeFilter TypeFilter
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
public ITypeFilter TypeFilter
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of times this pointcut has been <i>evaluated</i>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Useful as a debugging aid.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Note that this value is distinct from the number of times that this
|
||||
/// pointcut sucessfully matches a target method, in that a
|
||||
/// <see cref="ControlFlowPointcut"/> may be evaluated many times but
|
||||
/// never actually match even once.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The number of times this pointcut has been <i>evaluated</i>.
|
||||
/// </value>
|
||||
public int EvaluationCount
|
||||
{
|
||||
get { return _evaluationCount; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the number of times this pointcut has been <i>evaluated</i>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Useful as a debugging aid.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Note that this value is distinct from the number of times that this
|
||||
/// pointcut sucessfully matches a target method, in that a
|
||||
/// <see cref="ControlFlowPointcut"/> may be evaluated many times but
|
||||
/// never actually match even once.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The number of times this pointcut has been <i>evaluated</i>.
|
||||
/// </value>
|
||||
public int EvaluationCount
|
||||
{
|
||||
get { return _evaluationCount; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </value>
|
||||
public IMethodMatcher MethodMatcher
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </value>
|
||||
public IMethodMatcher MethodMatcher
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this a runtime pointcut?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation is a runtime pointcut, and so always returns
|
||||
/// <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this is a runtime pointcut.
|
||||
/// </value>
|
||||
/// <seealso cref="Spring.Aop.IMethodMatcher.IsRuntime"/>
|
||||
public bool IsRuntime
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Is this a runtime pointcut?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation is a runtime pointcut, and so always returns
|
||||
/// <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this is a runtime pointcut.
|
||||
/// </value>
|
||||
/// <seealso cref="Spring.Aop.IMethodMatcher.IsRuntime"/>
|
||||
public bool IsRuntime
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses are encouraged to override this method for greater
|
||||
/// filtering (and performance).
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This, the default, implementation always matches (returns
|
||||
/// <see langword="true"/>).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="type">The candidate target class.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
public virtual bool Matches(Type type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses are encouraged to override this method for greater
|
||||
/// filtering (and performance).
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This, the default, implementation always matches (returns
|
||||
/// <see langword="true"/>).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="type">The candidate target class.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
public virtual bool Matches(Type type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// Perform static checking. If this returns false, or if the isRuntime() method
|
||||
/// returns false, no runtime check will be made.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses are encouraged to override this method if it is possible
|
||||
/// to filter out some candidate classes.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This, the default, implementation always matches (returns
|
||||
/// <see langword="true"/>). This means that the three argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
/// method will always be invoked.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target class (may be <see langword="null"/>, in which case the
|
||||
/// candidate class must be taken to be the <paramref name="method"/>'s
|
||||
/// declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
/// <seealso cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type)"/>
|
||||
public virtual bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// Perform static checking. If this returns false, or if the isRuntime() method
|
||||
/// returns false, no runtime check will be made.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses are encouraged to override this method if it is possible
|
||||
/// to filter out some candidate classes.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This, the default, implementation always matches (returns
|
||||
/// <see langword="true"/>). This means that the three argument
|
||||
/// <see cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
/// method will always be invoked.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target class (may be <see langword="null"/>, in which case the
|
||||
/// candidate class must be taken to be the <paramref name="method"/>'s
|
||||
/// declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
/// <seealso cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type)"/>
|
||||
public virtual bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is there a runtime (dynamic) match for the supplied
|
||||
/// <paramref name="method"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses are encouraged to override this method if it is possible
|
||||
/// to filter out some candidate classes.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">The target class.</param>
|
||||
/// <param name="args">The arguments to the method</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if there is a runtime match.</returns>
|
||||
/// <seealso cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
public virtual bool Matches(MethodInfo method, Type targetType, object[] args)
|
||||
{
|
||||
++_evaluationCount;
|
||||
IControlFlow cflow = ControlFlowFactory.CreateControlFlow();
|
||||
return (_methodName != null)
|
||||
? cflow.Under(_type, _methodName)
|
||||
: cflow.Under(_type);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Is there a runtime (dynamic) match for the supplied
|
||||
/// <paramref name="method"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Subclasses are encouraged to override this method if it is possible
|
||||
/// to filter out some candidate classes.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">The target class.</param>
|
||||
/// <param name="args">The arguments to the method</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if there is a runtime match.</returns>
|
||||
/// <seealso cref="Spring.Aop.IMethodMatcher.Matches(MethodInfo, Type, object[])"/>
|
||||
public virtual bool Matches(MethodInfo method, Type targetType, object[] args)
|
||||
{
|
||||
++_evaluationCount;
|
||||
IControlFlow cflow = ControlFlowFactory.CreateControlFlow();
|
||||
return (_methodName != null)
|
||||
? cflow.Under(_type, _methodName)
|
||||
: cflow.Under(_type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,255 +25,255 @@ using Spring.Collections;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Simple <seealso cref="Spring.Aop.IIntroductionAdvisor"/> implementation that
|
||||
/// by default applies to any class.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class DefaultIntroductionAdvisor : IIntroductionAdvisor, ITypeFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple <seealso cref="Spring.Aop.IIntroductionAdvisor"/> implementation that
|
||||
/// by default applies to any class.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class DefaultIntroductionAdvisor : IIntroductionAdvisor, ITypeFilter
|
||||
{
|
||||
private readonly IAdvice _introduction;
|
||||
private readonly ISet _interfaces = new HybridSet();
|
||||
private readonly IAdvice _introduction;
|
||||
private readonly ISet _interfaces = new HybridSet();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultIntroductionAdvisor"/> class using
|
||||
/// the supplied <paramref name="introduction"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This constructor adds all interfaces implemented by the supplied
|
||||
/// <paramref name="introduction"/> (except the
|
||||
/// <see cref="AopAlliance.Aop.IAdvice"/> interface) to the list of
|
||||
/// interfaces to introduce.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="introduction">The introduction to use.</param>
|
||||
public DefaultIntroductionAdvisor(IAdvice introduction)
|
||||
: this(introduction, introduction.GetType().GetInterfaces())
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultIntroductionAdvisor"/> class using
|
||||
/// the supplied <paramref name="introduction"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This constructor adds all interfaces implemented by the supplied
|
||||
/// <paramref name="introduction"/> (except the
|
||||
/// <see cref="AopAlliance.Aop.IAdvice"/> interface) to the list of
|
||||
/// interfaces to introduce.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="introduction">The introduction to use.</param>
|
||||
public DefaultIntroductionAdvisor(IAdvice introduction)
|
||||
: this(introduction, introduction.GetType().GetInterfaces())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultIntroductionAdvisor"/> class using
|
||||
/// the supplied <paramref name="introduction"/>
|
||||
/// </summary>
|
||||
/// <param name="introduction">The introduction to use.</param>
|
||||
/// <param name="intf">
|
||||
/// The interface to introduce.
|
||||
/// </param>
|
||||
public DefaultIntroductionAdvisor(IAdvice introduction, Type intf)
|
||||
: this(introduction, new Type[] {intf})
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultIntroductionAdvisor"/> class using
|
||||
/// the supplied <paramref name="introduction"/>
|
||||
/// </summary>
|
||||
/// <param name="introduction">The introduction to use.</param>
|
||||
/// <param name="intf">
|
||||
/// The interface to introduce.
|
||||
/// </param>
|
||||
public DefaultIntroductionAdvisor(IAdvice introduction, Type intf)
|
||||
: this(introduction, new Type[] { intf })
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultIntroductionAdvisor"/> class using
|
||||
/// the supplied <paramref name="introduction"/>
|
||||
/// </summary>
|
||||
/// <param name="introduction">The introduction to use.</param>
|
||||
/// <param name="interfaces">
|
||||
/// The interfaces to introduce.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="introduction"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public DefaultIntroductionAdvisor(IAdvice introduction, Type[] interfaces)
|
||||
{
|
||||
if (introduction == null)
|
||||
{
|
||||
throw new ArgumentNullException("introduction", "Introduction cannot be null");
|
||||
}
|
||||
_introduction = introduction;
|
||||
foreach (Type intf in interfaces)
|
||||
{
|
||||
if (intf != typeof (IAdvice))
|
||||
{
|
||||
AddInterface(intf);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultIntroductionAdvisor"/> class using
|
||||
/// the supplied <paramref name="introduction"/>
|
||||
/// </summary>
|
||||
/// <param name="introduction">The introduction to use.</param>
|
||||
/// <param name="interfaces">
|
||||
/// The interfaces to introduce.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// If the supplied <paramref name="introduction"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public DefaultIntroductionAdvisor(IAdvice introduction, Type[] interfaces)
|
||||
{
|
||||
if (introduction == null)
|
||||
{
|
||||
throw new ArgumentNullException("introduction", "Introduction cannot be null");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the filter determining which target classes this
|
||||
/// introduction should apply to.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The filter determining which target classes this introduction
|
||||
/// should apply to.
|
||||
/// </value>
|
||||
public virtual ITypeFilter TypeFilter
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
_introduction = introduction;
|
||||
foreach (Type intf in interfaces)
|
||||
{
|
||||
if (intf != typeof(IAdvice))
|
||||
{
|
||||
AddInterface(intf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the interfaces introduced by this
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The interfaces introduced by this
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>.
|
||||
/// </value>
|
||||
public virtual Type[] Interfaces
|
||||
{
|
||||
get
|
||||
{
|
||||
Type[] interfaces = new Type[_interfaces.Count];
|
||||
_interfaces.CopyTo(interfaces, 0);
|
||||
return interfaces;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns the filter determining which target classes this
|
||||
/// introduction should apply to.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The filter determining which target classes this introduction
|
||||
/// should apply to.
|
||||
/// </value>
|
||||
public virtual ITypeFilter TypeFilter
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Default for an introduction is per-instance interception.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
public virtual bool IsPerInstance
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the interfaces introduced by this
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The interfaces introduced by this
|
||||
/// <see cref="Spring.Aop.IAdvisor"/>.
|
||||
/// </value>
|
||||
public virtual Type[] Interfaces
|
||||
{
|
||||
get
|
||||
{
|
||||
Type[] interfaces = new Type[_interfaces.Count];
|
||||
_interfaces.CopyTo(interfaces, 0);
|
||||
return interfaces;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
public virtual IAdvice Advice
|
||||
{
|
||||
get { return this._introduction; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Default for an introduction is per-instance interception.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
public virtual bool IsPerInstance
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="intf"/> to the list of
|
||||
/// introduced interfaces.
|
||||
/// </summary>
|
||||
/// <param name="intf">The interface to add.</param>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If any of the <see cref="Interfaces"/> are not interface <see cref="System.Type"/>.
|
||||
/// </exception>
|
||||
public virtual void AddInterface(Type intf)
|
||||
{
|
||||
if(intf != null)
|
||||
{
|
||||
BailIfNotAnInterfaceType(intf);
|
||||
_interfaces.Add(intf);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
public virtual IAdvice Advice
|
||||
{
|
||||
get { return this._introduction; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied
|
||||
/// <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This, the default, implementation always returns <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The candidate <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
public virtual bool Matches(Type type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds the supplied <paramref name="intf"/> to the list of
|
||||
/// introduced interfaces.
|
||||
/// </summary>
|
||||
/// <param name="intf">The interface to add.</param>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If any of the <see cref="Interfaces"/> are not interface <see cref="System.Type"/>.
|
||||
/// </exception>
|
||||
public virtual void AddInterface(Type intf)
|
||||
{
|
||||
if (intf != null)
|
||||
{
|
||||
BailIfNotAnInterfaceType(intf);
|
||||
_interfaces.Add(intf);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the advised interfaces be implemented by the introduction
|
||||
/// advice?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked <b>before</b> adding an
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If the advised interfaces cannot be implemented by the introduction
|
||||
/// advice.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor.Interfaces"/>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If any of the <see cref="Interfaces"/> are not interface <see cref="System.Type"/>.
|
||||
/// </exception>
|
||||
public virtual void ValidateInterfaces()
|
||||
{
|
||||
foreach (Type intf in _interfaces)
|
||||
{
|
||||
BailIfNotAnInterfaceType(intf);
|
||||
if (! intf.IsAssignableFrom(_introduction.GetType()))
|
||||
{
|
||||
throw new ArgumentException("Introduction [" + _introduction.GetType().FullName + "] " +
|
||||
"does not implement interface '" + intf.FullName + "' specified in introduction advice.");
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Should the pointcut apply to the supplied
|
||||
/// <see cref="System.Type"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This, the default, implementation always returns <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The candidate <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advice should apply to the supplied
|
||||
/// <paramref name="type"/>
|
||||
/// </returns>
|
||||
public virtual bool Matches(Type type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void BailIfNotAnInterfaceType(Type intf)
|
||||
{
|
||||
if (intf != null && !intf.IsInterface)
|
||||
{
|
||||
throw new ArgumentException("Type [" + intf.FullName + "] is not an interface; cannot be used in an introduction.");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Can the advised interfaces be implemented by the introduction
|
||||
/// advice?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked <b>before</b> adding an
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If the advised interfaces cannot be implemented by the introduction
|
||||
/// advice.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.IIntroductionAdvisor.Interfaces"/>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// If any of the <see cref="Interfaces"/> are not interface <see cref="System.Type"/>.
|
||||
/// </exception>
|
||||
public virtual void ValidateInterfaces()
|
||||
{
|
||||
foreach (Type intf in _interfaces)
|
||||
{
|
||||
BailIfNotAnInterfaceType(intf);
|
||||
if (!intf.IsAssignableFrom(_introduction.GetType()))
|
||||
{
|
||||
throw new ArgumentException("Introduction [" + _introduction.GetType().FullName + "] " +
|
||||
"does not implement interface '" + intf.FullName + "' specified in introduction advice.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2 IntroductionAdvisors are considered equal if
|
||||
/// a) they are of the same type
|
||||
/// b) their introduction advices are equal
|
||||
/// c) they introduce the same interfaces
|
||||
/// </summary>
|
||||
public bool Equals(DefaultIntroductionAdvisor other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
if (other.GetType() != this.GetType())
|
||||
return false;
|
||||
return Equals(other._introduction, _introduction) && Equals(other._interfaces, _interfaces);
|
||||
}
|
||||
private static void BailIfNotAnInterfaceType(Type intf)
|
||||
{
|
||||
if (intf != null && !intf.IsInterface)
|
||||
{
|
||||
throw new ArgumentException("Type [" + intf.FullName + "] is not an interface; cannot be used in an introduction.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2 IntroductionAdvisors are considered equal if
|
||||
/// a) they are of the same type
|
||||
/// b) their introduction advices are equal
|
||||
/// c) they introduce the same interfaces
|
||||
/// </summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as DefaultIntroductionAdvisor);
|
||||
}
|
||||
/// <summary>
|
||||
/// 2 IntroductionAdvisors are considered equal if
|
||||
/// a) they are of the same type
|
||||
/// b) their introduction advices are equal
|
||||
/// c) they introduce the same interfaces
|
||||
/// </summary>
|
||||
public bool Equals(DefaultIntroductionAdvisor other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
if (other.GetType() != this.GetType())
|
||||
return false;
|
||||
return Equals(other._introduction, _introduction) && Equals(other._interfaces, _interfaces);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2 IntroductionAdvisors are considered equal if
|
||||
/// a) they are of the same type
|
||||
/// b) their introduction advices are equal
|
||||
/// c) they introduce the same interfaces
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((_introduction != null ? _introduction.GetHashCode() : 0)*397) ^ (_interfaces != null ? _interfaces.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 2 IntroductionAdvisors are considered equal if
|
||||
/// a) they are of the same type
|
||||
/// b) their introduction advices are equal
|
||||
/// c) they introduce the same interfaces
|
||||
/// </summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as DefaultIntroductionAdvisor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2 IntroductionAdvisors are considered equal if
|
||||
/// a) they are of the same type
|
||||
/// b) their introduction advices are equal
|
||||
/// c) they introduce the same interfaces
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((_introduction != null ? _introduction.GetHashCode() : 0) * 397) ^ (_interfaces != null ? _interfaces.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,42 +18,40 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Concrete ObjectFactory-based IPointcutAdvisor thta allows for any Advice to be
|
||||
/// configured as reference to an Advice object in the ObjectFatory, as well as
|
||||
/// the Pointcut to be configured through an object property.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Specifying the name of an advice object instead of the advice object itself
|
||||
/// (if running within a ObjectFactory/ApplicationContext) increases loose coupling
|
||||
/// at initialization time, in order to not intialize the advice object until the pointcut
|
||||
/// actually matches.
|
||||
/// </remarks>
|
||||
/// <author>Juerge Hoeller</author>
|
||||
/// <author>Mark Pollack</author>
|
||||
public class DefaultObjectFactoryPointcutAdvisor : AbstractObjectFactoryPointcutAdvisor
|
||||
{
|
||||
private IPointcut pointcut = TruePointcut.True;
|
||||
|
||||
/// <summary>
|
||||
/// Concrete ObjectFactory-based IPointcutAdvisor thta allows for any Advice to be
|
||||
/// configured as reference to an Advice object in the ObjectFatory, as well as
|
||||
/// the Pointcut to be configured through an object property.
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Specifying the name of an advice object instead of the advice object itself
|
||||
/// (if running within a ObjectFactory/ApplicationContext) increases loose coupling
|
||||
/// at initialization time, in order to not intialize the advice object until the pointcut
|
||||
/// actually matches.
|
||||
/// </remarks>
|
||||
/// <author>Juerge Hoeller</author>
|
||||
/// <author>Mark Pollack</author>
|
||||
public class DefaultObjectFactoryPointcutAdvisor : AbstractObjectFactoryPointcutAdvisor
|
||||
public override IPointcut Pointcut
|
||||
{
|
||||
private IPointcut pointcut = TruePointcut.True;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
public override IPointcut Pointcut
|
||||
{
|
||||
get { return pointcut; }
|
||||
set { pointcut = (pointcut != null ? value : TruePointcut.True); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describe this Advisor, showing pointcut and name of advice object.
|
||||
/// </summary>
|
||||
/// <returns>Type name , pointcut, and advice object name.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return GetType().Name + ": pointcut [" + Pointcut + "]; advice object = '" + AdviceObjectName + "'";
|
||||
}
|
||||
get { return pointcut; }
|
||||
set { pointcut = (pointcut != null ? value : TruePointcut.True); }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describe this Advisor, showing pointcut and name of advice object.
|
||||
/// </summary>
|
||||
/// <returns>Type name , pointcut, and advice object name.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return GetType().Name + ": pointcut [" + Pointcut + "]; advice object = '" + AdviceObjectName + "'";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,101 +24,99 @@ using AopAlliance.Aop;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Convenient pointcut-driven advisor implementation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is the most commonly used <see cref="Spring.Aop.IAdvisor"/> implementation.
|
||||
/// It can be used with any pointcut and advice type, except for introductions.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class DefaultPointcutAdvisor : AbstractGenericPointcutAdvisor
|
||||
{
|
||||
/// <summary>
|
||||
/// Convenient pointcut-driven advisor implementation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is the most commonly used <see cref="Spring.Aop.IAdvisor"/> implementation.
|
||||
/// It can be used with any pointcut and advice type, except for introductions.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public class DefaultPointcutAdvisor : AbstractGenericPointcutAdvisor
|
||||
{
|
||||
private IPointcut pointcut = TruePointcut.True;
|
||||
private IPointcut pointcut = TruePointcut.True;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultPointcutAdvisor"/> class.
|
||||
/// </summary>
|
||||
public DefaultPointcutAdvisor()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultPointcutAdvisor"/> class.
|
||||
/// </summary>
|
||||
public DefaultPointcutAdvisor()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// class for the supplied <paramref name="advice"/>,
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The advice to use.
|
||||
/// </param>
|
||||
public DefaultPointcutAdvisor(IAdvice advice)
|
||||
: this(TruePointcut.True, advice)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// class for the supplied <paramref name="advice"/>,
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The advice to use.
|
||||
/// </param>
|
||||
public DefaultPointcutAdvisor(IAdvice advice)
|
||||
: this(TruePointcut.True, advice)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// class for the supplied <paramref name="advice"/> and
|
||||
/// <paramref name="pointcut"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The advice to use.
|
||||
/// </param>
|
||||
/// <param name="pointcut">
|
||||
/// The pointcut to use.
|
||||
/// </param>
|
||||
public DefaultPointcutAdvisor(IPointcut pointcut, IAdvice advice)
|
||||
{
|
||||
this.pointcut = pointcut;
|
||||
Advice = advice;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DefaultPointcutAdvisor"/>
|
||||
/// class for the supplied <paramref name="advice"/> and
|
||||
/// <paramref name="pointcut"/>.
|
||||
/// </summary>
|
||||
/// <param name="advice">
|
||||
/// The advice to use.
|
||||
/// </param>
|
||||
/// <param name="pointcut">
|
||||
/// The pointcut to use.
|
||||
/// </param>
|
||||
public DefaultPointcutAdvisor(IPointcut pointcut, IAdvice advice)
|
||||
{
|
||||
this.pointcut = pointcut;
|
||||
Advice = advice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
public override IPointcut Pointcut
|
||||
{
|
||||
get { return pointcut; }
|
||||
set { pointcut = value;}
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
public override IPointcut Pointcut
|
||||
{
|
||||
get { return pointcut; }
|
||||
set { pointcut = value; }
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// 2 <see cref="DefaultPointcutAdvisor"/>s are considered equal, if
|
||||
/// a) their pointcuts are equal
|
||||
/// b) their advices are equal
|
||||
///</summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj as DefaultPointcutAdvisor);
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// 2 <see cref="DefaultPointcutAdvisor"/>s are considered equal, if
|
||||
/// a) their pointcuts are equal
|
||||
/// b) their advices are equal
|
||||
///</summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj as DefaultPointcutAdvisor);
|
||||
}
|
||||
/// <summary>
|
||||
/// Calculates a unique hashcode based on advice + pointcut
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a unique hashcode based on advice + pointcut
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents the current
|
||||
/// <see cref="System.Object"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> representation of this advisor.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return GetType().Name + ": pointcut=[" + pointcut + "] advice=[" + Advice + "]";
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents the current
|
||||
/// <see cref="System.Object"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> representation of this advisor.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return GetType().Name + ": pointcut=[" + pointcut + "] advice=[" + Advice + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,90 +24,89 @@ using System.Reflection;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Convenient abstract superclass for dynamic method matchers that do
|
||||
/// care about arguments at runtime.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class DynamicMethodMatcher : IMethodMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Convenient abstract superclass for dynamic method matchers that do
|
||||
/// care about arguments at runtime.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class DynamicMethodMatcher : IMethodMatcher
|
||||
{
|
||||
#region Constructor (s) / Destructor
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DynamicMethodMatcher"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an <see langword="abstract"/> class, and as such exposes no
|
||||
/// public constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
protected DynamicMethodMatcher()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DynamicMethodMatcher"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an <see langword="abstract"/> class, and as such exposes no
|
||||
/// public constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
protected DynamicMethodMatcher()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Is this <see cref="Spring.Aop.IMethodMatcher"/> dynamic?
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always returns <see langword="true"/>, to specify that this is a
|
||||
/// dynamic matcher.
|
||||
/// </value>
|
||||
public virtual bool IsRuntime
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Is this <see cref="Spring.Aop.IMethodMatcher"/> dynamic?
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always returns <see langword="true"/>, to specify that this is a
|
||||
/// dynamic matcher.
|
||||
/// </value>
|
||||
public virtual bool IsRuntime
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Derived classes can override this method to add preconditions for
|
||||
/// dynamic matching.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This implementation always returns <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
public virtual bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Does the supplied <paramref name="method"/> satisfy this matcher?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Derived classes can override this method to add preconditions for
|
||||
/// dynamic matching.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This implementation always returns <see langword="true"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/> (may be <see langword="null"/>,
|
||||
/// in which case the candidate <see cref="System.Type"/> must be taken
|
||||
/// to be the <paramref name="method"/>'s declaring class).
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if this this method matches statically.
|
||||
/// </returns>
|
||||
public virtual bool Matches(MethodInfo method, Type targetType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is there a runtime (dynamic) match for the supplied
|
||||
/// <paramref name="method"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Must be overriden by derived classes to provide criteria for dynamic matching.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <param name="args">The arguments to the method</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if there is a runtime match.</returns>
|
||||
public abstract bool Matches(MethodInfo method, Type targetType, object[] args);
|
||||
}
|
||||
/// <summary>
|
||||
/// Is there a runtime (dynamic) match for the supplied
|
||||
/// <paramref name="method"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Must be overriden by derived classes to provide criteria for dynamic matching.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="method">The candidate method.</param>
|
||||
/// <param name="targetType">
|
||||
/// The target <see cref="System.Type"/>.
|
||||
/// </param>
|
||||
/// <param name="args">The arguments to the method</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if there is a runtime match.</returns>
|
||||
public abstract bool Matches(MethodInfo method, Type targetType, object[] args);
|
||||
}
|
||||
|
||||
@@ -25,150 +25,149 @@ using Spring.Core;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Support
|
||||
namespace Spring.Aop.Support;
|
||||
|
||||
/// <summary>
|
||||
/// Convenient superclass for <see cref="Spring.Aop.IAdvisor"/>s
|
||||
/// that are also dynamic pointcuts.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class DynamicMethodMatcherPointcutAdvisor
|
||||
: DynamicMethodMatcher, IPointcutAdvisor, IPointcut, IOrdered
|
||||
{
|
||||
/// <summary>
|
||||
/// Convenient superclass for <see cref="Spring.Aop.IAdvisor"/>s
|
||||
/// that are also dynamic pointcuts.
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Aleksandar Seovic (.NET)</author>
|
||||
[Serializable]
|
||||
public abstract class DynamicMethodMatcherPointcutAdvisor
|
||||
: DynamicMethodMatcher, IPointcutAdvisor, IPointcut, IOrdered
|
||||
{
|
||||
private int _order = Int32.MaxValue;
|
||||
private IAdvice _advice;
|
||||
private int _order = Int32.MaxValue;
|
||||
private IAdvice _advice;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DynamicMethodMatcherPointcutAdvisor"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an abstract class, and as such has no publicly
|
||||
/// visible constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
protected DynamicMethodMatcherPointcutAdvisor()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DynamicMethodMatcherPointcutAdvisor"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an abstract class, and as such has no publicly
|
||||
/// visible constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
protected DynamicMethodMatcherPointcutAdvisor()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DynamicMethodMatcherPointcutAdvisor"/>
|
||||
/// class for the supplied <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an abstract class, and as such has no publicly
|
||||
/// visible constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advice">
|
||||
/// The advice portion of this advisor.
|
||||
/// </param>
|
||||
protected DynamicMethodMatcherPointcutAdvisor(IAdvice advice)
|
||||
{
|
||||
this._advice = advice;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Aop.Support.DynamicMethodMatcherPointcutAdvisor"/>
|
||||
/// class for the supplied <paramref name="advice"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an abstract class, and as such has no publicly
|
||||
/// visible constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advice">
|
||||
/// The advice portion of this advisor.
|
||||
/// </param>
|
||||
protected DynamicMethodMatcherPointcutAdvisor(IAdvice advice)
|
||||
{
|
||||
this._advice = advice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Not supported for dynamic advisors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
/// <exception cref="System.NotSupportedException">Always.</exception>
|
||||
/// <see cref="Spring.Aop.IAdvisor.IsPerInstance"/>
|
||||
public virtual bool IsPerInstance
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
"The 'IsPerInstance' property of the IAdvisor interface " +
|
||||
"is not yet supported in Spring.NET.");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Is this advice associated with a particular instance?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Not supported for dynamic advisors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this advice is associated with a
|
||||
/// particular instance.
|
||||
/// </value>
|
||||
/// <exception cref="System.NotSupportedException">Always.</exception>
|
||||
/// <see cref="Spring.Aop.IAdvisor.IsPerInstance"/>
|
||||
public virtual bool IsPerInstance
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
"The 'IsPerInstance' property of the IAdvisor interface " +
|
||||
"is not yet supported in Spring.NET.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation always returns a filter that evaluates to <see langword="true"/>
|
||||
/// for any <see cref="System.Type"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
public virtual ITypeFilter TypeFilter
|
||||
{
|
||||
get { return TrueTypeFilter.True; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.ITypeFilter"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation always returns a filter that evaluates to <see langword="true"/>
|
||||
/// for any <see cref="System.Type"/>.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.ITypeFilter"/>.
|
||||
/// </value>
|
||||
public virtual ITypeFilter TypeFilter
|
||||
{
|
||||
get { return TrueTypeFilter.True; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation always returns itself (this object).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </value>
|
||||
public virtual IMethodMatcher MethodMatcher
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IMethodMatcher"/> for this pointcut.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation always returns itself (this object).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// The current <see cref="Spring.Aop.IMethodMatcher"/>.
|
||||
/// </value>
|
||||
public virtual IMethodMatcher MethodMatcher
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// This <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </returns>
|
||||
public virtual int Order
|
||||
{
|
||||
get { return this._order; }
|
||||
set { this._order = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns this <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// This <see cref="Spring.Aop.IAdvisor"/>s order in the
|
||||
/// interception chain.
|
||||
/// </returns>
|
||||
public virtual int Order
|
||||
{
|
||||
get { return this._order; }
|
||||
set { this._order = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/>
|
||||
public virtual IAdvice Advice
|
||||
{
|
||||
get { return this._advice; }
|
||||
set { this._advice = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Return the advice part of this aspect.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The advice that should apply if the pointcut matches.
|
||||
/// </returns>
|
||||
/// <see cref="Spring.Aop.IAdvisor.Advice"/>
|
||||
public virtual IAdvice Advice
|
||||
{
|
||||
get { return this._advice; }
|
||||
set { this._advice = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation always returns itself (this object).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public IPointcut Pointcut
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The <see cref="Spring.Aop.IPointcut"/> that drives this advisor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This implementation always returns itself (this object).
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public IPointcut Pointcut
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user