Refactoring
This commit is contained in:
Родитель
53e93fe435
Коммит
c3122fdab7
|
@ -32,8 +32,8 @@ namespace Unity.Interception.ContainerIntegration
|
|||
|
||||
private PolicyDefinition UpdateRuleDrivenPolicyInjection()
|
||||
{
|
||||
_extension.Container
|
||||
.RegisterType<InjectionPolicy, RuleDrivenPolicy>(_policyName,
|
||||
|
||||
UnityContainerExtensions.RegisterType<InjectionPolicy, RuleDrivenPolicy>(_extension.Container, _policyName,
|
||||
new InjectionConstructor(_policyName,
|
||||
new ResolvedArrayParameter<IMatchingRule>(_rulesParameters.ToArray()),
|
||||
_handlersNames.ToArray()));
|
||||
|
|
|
@ -32,10 +32,11 @@ namespace Unity.Interception
|
|||
/// </summary>
|
||||
protected override void Initialize()
|
||||
{
|
||||
Context.Strategies.Add(new InstanceInterceptionStrategy(), UnityBuildStage.Lifetime);
|
||||
Context.Strategies.Add(new TypeInterceptionStrategy(), UnityBuildStage.PreCreation);
|
||||
Context.Container.RegisterInstance<InjectionPolicy>(typeof(AttributeDrivenPolicy).AssemblyQualifiedName,
|
||||
new AttributeDrivenPolicy());
|
||||
throw new NotImplementedException();
|
||||
//Context.Strategies.Add(new InstanceInterceptionStrategy(), UnityBuildStage.Lifetime);
|
||||
//Context.Strategies.Add(new TypeInterceptionStrategy(), UnityBuildStage.PreCreation);
|
||||
//Context.Container.RegisterInstance<InjectionPolicy>(typeof(AttributeDrivenPolicy).AssemblyQualifiedName,
|
||||
// new AttributeDrivenPolicy());
|
||||
}
|
||||
|
||||
|
||||
|
@ -133,19 +134,21 @@ namespace Unity.Interception
|
|||
/// <returns>This extension object.</returns>
|
||||
public Interception SetDefaultInterceptorFor(Type typeToIntercept, ITypeInterceptor interceptor)
|
||||
{
|
||||
Guard.ArgumentNotNull(typeToIntercept, "typeToIntercept");
|
||||
Guard.ArgumentNotNull(interceptor, "interceptor");
|
||||
GuardTypeInterceptable(typeToIntercept, interceptor);
|
||||
throw new NotImplementedException();
|
||||
|
||||
Context.Policies.Set(typeToIntercept, UnityContainer.All, typeof(ITypeInterceptionPolicy),
|
||||
new FixedTypeInterceptionPolicy(interceptor));
|
||||
//Guard.ArgumentNotNull(typeToIntercept, "typeToIntercept");
|
||||
//Guard.ArgumentNotNull(interceptor, "interceptor");
|
||||
//GuardTypeInterceptable(typeToIntercept, interceptor);
|
||||
|
||||
// add policy injection behavior if using this configuration API to set the interceptor
|
||||
var interceptionBehaviorsPolicy = new InterceptionBehaviorsPolicy();
|
||||
interceptionBehaviorsPolicy.AddBehaviorKey(NamedTypeBuildKey.Make<PolicyInjectionBehavior>());
|
||||
Context.Policies.Set(typeToIntercept, UnityContainer.All,
|
||||
typeof(IInterceptionBehaviorsPolicy), interceptionBehaviorsPolicy);
|
||||
return this;
|
||||
//Context.Policies.Set(typeToIntercept, UnityContainer.All, typeof(ITypeInterceptionPolicy),
|
||||
// new FixedTypeInterceptionPolicy(interceptor));
|
||||
|
||||
//// add policy injection behavior if using this configuration API to set the interceptor
|
||||
//var interceptionBehaviorsPolicy = new InterceptionBehaviorsPolicy();
|
||||
//interceptionBehaviorsPolicy.AddBehaviorKey(NamedTypeBuildKey.Make<PolicyInjectionBehavior>());
|
||||
//Context.Policies.Set(typeToIntercept, UnityContainer.All,
|
||||
// typeof(IInterceptionBehaviorsPolicy), interceptionBehaviorsPolicy);
|
||||
//return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -201,18 +204,20 @@ namespace Unity.Interception
|
|||
/// <returns>This extension object.</returns>
|
||||
public Interception SetDefaultInterceptorFor(Type typeToIntercept, IInstanceInterceptor interceptor)
|
||||
{
|
||||
Guard.ArgumentNotNull(typeToIntercept, "typeToIntercept");
|
||||
Guard.ArgumentNotNull(interceptor, "interceptor");
|
||||
GuardTypeInterceptable(typeToIntercept, interceptor);
|
||||
throw new NotImplementedException();
|
||||
|
||||
Context.Policies.Set(typeToIntercept, UnityContainer.All, typeof(IInstanceInterceptionPolicy), new FixedInstanceInterceptionPolicy(interceptor));
|
||||
//Guard.ArgumentNotNull(typeToIntercept, "typeToIntercept");
|
||||
//Guard.ArgumentNotNull(interceptor, "interceptor");
|
||||
//GuardTypeInterceptable(typeToIntercept, interceptor);
|
||||
|
||||
// add policy injection behavior if using this configuration API to set the interceptor
|
||||
var interceptionBehaviorsPolicy = new InterceptionBehaviorsPolicy();
|
||||
interceptionBehaviorsPolicy.AddBehaviorKey(NamedTypeBuildKey.Make<PolicyInjectionBehavior>());
|
||||
Context.Policies.Set(typeToIntercept, UnityContainer.All, typeof(IInterceptionBehaviorsPolicy), interceptionBehaviorsPolicy);
|
||||
//Context.Policies.Set(typeToIntercept, UnityContainer.All, typeof(IInstanceInterceptionPolicy), new FixedInstanceInterceptionPolicy(interceptor));
|
||||
|
||||
return this;
|
||||
//// add policy injection behavior if using this configuration API to set the interceptor
|
||||
//var interceptionBehaviorsPolicy = new InterceptionBehaviorsPolicy();
|
||||
//interceptionBehaviorsPolicy.AddBehaviorKey(NamedTypeBuildKey.Make<PolicyInjectionBehavior>());
|
||||
//Context.Policies.Set(typeToIntercept, UnityContainer.All, typeof(IInterceptionBehaviorsPolicy), interceptionBehaviorsPolicy);
|
||||
|
||||
//return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
@ -229,3 +227,4 @@ namespace Unity.Interception.Interceptors.InstanceInterceptors.InterfaceIntercep
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Security;
|
||||
using Unity.Lifetime;
|
||||
using Unity.Policy;
|
||||
using Unity.Resolution;
|
||||
|
||||
namespace Unity.Builder
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the context in which a build-up or tear-down operation runs.
|
||||
/// </summary>
|
||||
[SecuritySafeCritical]
|
||||
[DebuggerDisplay("Resolving: {Type}, Name: {Name}")]
|
||||
public partial struct BuilderContext : IResolveContext
|
||||
{
|
||||
#region Fields
|
||||
|
||||
public IPolicyList List;
|
||||
public ILifetimeContainer? Scope;
|
||||
public ResolverOverride[]? Overrides;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region IResolveContext
|
||||
|
||||
public IUnityContainer Container => Lifetime?.Container!;
|
||||
|
||||
public Type Type { get; set; }
|
||||
|
||||
public string? Name { get; set; }
|
||||
|
||||
public object? Resolve(Type type, string? name)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region IPolicyList
|
||||
|
||||
public object? Get(Type policyInterface)
|
||||
{
|
||||
return List.Get(RegistrationType, Name, policyInterface) ??
|
||||
Registration.Get(policyInterface);
|
||||
}
|
||||
|
||||
public object? Get(Type? type, string? name, Type policyInterface)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public object? Get(Type type, Type policyInterface)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Set(Type policyInterface, object policy)
|
||||
{
|
||||
List.Set(RegistrationType, Name, policyInterface, policy);
|
||||
}
|
||||
|
||||
public void Set(Type type, Type policyInterface, object policy)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Set(Type? type, string? name, Type policyInterface, object policy)
|
||||
{
|
||||
List.Set(type, name, policyInterface, policy);
|
||||
}
|
||||
|
||||
public void Clear(Type? type, string? name, Type policyInterface)
|
||||
{
|
||||
List.Clear(type, name, policyInterface);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Registration
|
||||
|
||||
public Type RegistrationType { get; set; }
|
||||
|
||||
public IPolicySet Registration { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public object? Existing { get; set; }
|
||||
|
||||
public ILifetimeContainer Lifetime;
|
||||
|
||||
public SynchronizedLifetimeManager? RequiresRecovery;
|
||||
|
||||
public bool BuildComplete;
|
||||
|
||||
public Type? DeclaringType;
|
||||
#if !NET40
|
||||
public IntPtr Parent;
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to resolve an instance with requested <see cref="Type"/> and name.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of the contract</param>
|
||||
/// <param name="name">Name of the contract</param>
|
||||
/// <returns>An instance of requested contract or <see cref="LifetimeManager.NoValue"/> value
|
||||
/// if requested object could not be created</returns>
|
||||
object TryResolve(Type type, string? name)
|
||||
{
|
||||
return LifetimeManager.NoValue;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Unity.Builder
|
||||
{
|
||||
/// <summary>
|
||||
/// Build key used to combine a type object with a string name. Used by
|
||||
/// ObjectBuilder to indicate exactly what is being built.
|
||||
/// </summary>
|
||||
public class NamedTypeBuildKey
|
||||
{
|
||||
private readonly int _hash;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="NamedTypeBuildKey"/> instance with the given
|
||||
/// type and name.
|
||||
/// </summary>
|
||||
/// <param name="type"><see cref="Type"/> to build.</param>
|
||||
/// <param name="name">Key to use to look up type mappings and singletons.</param>
|
||||
public NamedTypeBuildKey(Type type, string? name)
|
||||
{
|
||||
Type = type;
|
||||
Name = !string.IsNullOrEmpty(name) ? name : null;
|
||||
_hash = (Type?.GetHashCode() ?? 0 + 37) ^ (Name?.GetHashCode() ?? 0 + 17);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="NamedTypeBuildKey"/> instance for the default
|
||||
/// buildup of the given type.
|
||||
/// </summary>
|
||||
/// <param name="type"><see cref="Type"/> to build.</param>
|
||||
public NamedTypeBuildKey(Type type)
|
||||
: this(type, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This helper method creates a new <see cref="NamedTypeBuildKey"/> instance. It is
|
||||
/// initialized for the default key for the given type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type to build.</typeparam>
|
||||
/// <returns>A new <see cref="NamedTypeBuildKey"/> instance.</returns>
|
||||
public static NamedTypeBuildKey Make<T>()
|
||||
{
|
||||
return new NamedTypeBuildKey(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This helper method creates a new <see cref="NamedTypeBuildKey"/> instance for
|
||||
/// the given type and key.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type to build</typeparam>
|
||||
/// <param name="name">Key to use to look up type mappings and singletons.</param>
|
||||
/// <returns>A new <see cref="NamedTypeBuildKey"/> instance initialized with the given type and name.</returns>
|
||||
public static NamedTypeBuildKey Make<T>(string name)
|
||||
{
|
||||
return new NamedTypeBuildKey(typeof(T), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the <see cref="Type"/> stored in this build key.
|
||||
/// </summary>
|
||||
/// <value>The type to build.</value>
|
||||
public Type Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the name stored in this build key.
|
||||
/// </summary>
|
||||
/// <remarks>The name to use when building.</remarks>
|
||||
public string? Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Compare two <see cref="NamedTypeBuildKey"/> instances.
|
||||
/// </summary>
|
||||
/// <remarks>Two <see cref="NamedTypeBuildKey"/> instances compare equal
|
||||
/// if they contain the same name and the same type. Also, comparing
|
||||
/// against a different type will also return false.</remarks>
|
||||
/// <param name="obj">Object to compare to.</param>
|
||||
/// <returns>True if the two keys are equal, false if not.</returns>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is NamedTypeBuildKey namedType && Type == namedType.Type && Name == namedType.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A hash code.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two <see cref="NamedTypeBuildKey"/> instances for equality.
|
||||
/// </summary>
|
||||
/// <remarks>Two <see cref="NamedTypeBuildKey"/> instances compare equal
|
||||
/// if they contain the same name and the same type.</remarks>
|
||||
/// <param name="left">First of the two keys to compare.</param>
|
||||
/// <param name="right">Second of the two keys to compare.</param>
|
||||
/// <returns>True if the values of the keys are the same, else false.</returns>
|
||||
public static bool operator ==(NamedTypeBuildKey left, NamedTypeBuildKey right)
|
||||
{
|
||||
return left?._hash == right?._hash &&
|
||||
left?.Type == right?.Type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two <see cref="NamedTypeBuildKey"/> instances for inequality.
|
||||
/// </summary>
|
||||
/// <remarks>Two <see cref="NamedTypeBuildKey"/> instances compare equal
|
||||
/// if they contain the same name and the same type. If either field differs
|
||||
/// the keys are not equal.</remarks>
|
||||
/// <param name="left">First of the two keys to compare.</param>
|
||||
/// <param name="right">Second of the two keys to compare.</param>
|
||||
/// <returns>false if the values of the keys are the same, else true.</returns>
|
||||
public static bool operator !=(NamedTypeBuildKey left, NamedTypeBuildKey right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats the build key as a string (primarily for debugging).
|
||||
/// </summary>
|
||||
/// <returns>A readable string representation of the build key.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "Build Key[{0}, {1}]", Type, Name ?? "null");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A generic version of <see cref="NamedTypeBuildKey"/> so that
|
||||
/// you can new up a key using generic syntax.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type for the key.</typeparam>
|
||||
public class NamedTypeBuildKey<T> : NamedTypeBuildKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Construct a new <see cref="NamedTypeBuildKey{T}"/> that
|
||||
/// specifies the given type.
|
||||
/// </summary>
|
||||
public NamedTypeBuildKey()
|
||||
: base(typeof(T), null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new <see cref="NamedTypeBuildKey{T}"/> that
|
||||
/// specifies the given type and name.
|
||||
/// </summary>
|
||||
/// <param name="name">Name for the key.</param>
|
||||
public NamedTypeBuildKey(string name)
|
||||
: base(typeof(T), name)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.Builder;
|
||||
using Unity.Interception.InterceptionBehaviors;
|
||||
using Unity.Interception.Interceptors;
|
||||
using Unity.Strategies;
|
||||
|
||||
namespace Unity.Interception.ContainerIntegration.ObjectBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="BuilderStrategy"/> that intercepts objects
|
||||
/// in the build chain by creating a proxy object.
|
||||
/// </summary>
|
||||
public class InstanceInterceptionStrategy : BuilderStrategy
|
||||
{
|
||||
/// <summary>
|
||||
/// Called during the chain of responsibility for a build operation. The
|
||||
/// PostBuildUp method is called when the chain has finished the PreBuildUp
|
||||
/// phase and executes in reverse order from the PreBuildUp calls.
|
||||
/// </summary>
|
||||
/// <param name="context">Context of the build operation.</param>
|
||||
public override void PostBuildUp(ref BuilderContext context)
|
||||
{
|
||||
// If it's already been intercepted, don't do it again.
|
||||
if (context.Existing is IInterceptingProxy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IInstanceInterceptionPolicy interceptionPolicy =
|
||||
FindInterceptionPolicy<IInstanceInterceptionPolicy>(ref context, true);
|
||||
if (interceptionPolicy == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var interceptor = interceptionPolicy.GetInterceptor(ref context);
|
||||
|
||||
IInterceptionBehaviorsPolicy interceptionBehaviorsPolicy =
|
||||
FindInterceptionPolicy<IInterceptionBehaviorsPolicy>(ref context, true);
|
||||
if (interceptionBehaviorsPolicy == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IAdditionalInterfacesPolicy additionalInterfacesPolicy =
|
||||
FindInterceptionPolicy<IAdditionalInterfacesPolicy>(ref context, false);
|
||||
IEnumerable<Type> additionalInterfaces =
|
||||
additionalInterfacesPolicy != null ? additionalInterfacesPolicy.AdditionalInterfaces : Type.EmptyTypes;
|
||||
|
||||
Type typeToIntercept = context.RegistrationType;
|
||||
Type implementationType = context.Existing.GetType();
|
||||
|
||||
IInterceptionBehavior[] interceptionBehaviors =
|
||||
interceptionBehaviorsPolicy.GetEffectiveBehaviors(
|
||||
ref context, interceptor, typeToIntercept, implementationType)
|
||||
.ToArray();
|
||||
|
||||
if (interceptionBehaviors.Length > 0)
|
||||
{
|
||||
context.Existing =
|
||||
Intercept.ThroughProxyWithAdditionalInterfaces(
|
||||
typeToIntercept,
|
||||
context.Existing,
|
||||
interceptor,
|
||||
interceptionBehaviors,
|
||||
additionalInterfaces);
|
||||
}
|
||||
}
|
||||
|
||||
private static T FindInterceptionPolicy<T>(ref BuilderContext context, bool probeOriginalKey)
|
||||
where T : class
|
||||
{
|
||||
// First, try for an original build key
|
||||
var policy = GetPolicyOrDefault<T>(ref context);
|
||||
|
||||
if (policy != null) return policy;
|
||||
|
||||
if (!probeOriginalKey) return null;
|
||||
|
||||
// Next, try the build type
|
||||
policy = GetPolicyOrDefault<T>(ref context);
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
public static TPolicyInterface GetPolicyOrDefault<TPolicyInterface>(ref BuilderContext context)
|
||||
{
|
||||
return (TPolicyInterface)(GetNamedPolicy(ref context, context.RegistrationType, context.Name) ??
|
||||
GetNamedPolicy(ref context, context.RegistrationType, UnityContainer.All));
|
||||
|
||||
object GetNamedPolicy(ref BuilderContext c, Type t, string n)
|
||||
{
|
||||
return (c.Get(t, n, typeof(TPolicyInterface)) ?? (
|
||||
#if NETCOREAPP1_0 || NETSTANDARD1_0
|
||||
t.GetTypeInfo().IsGenericType
|
||||
#else
|
||||
t.IsGenericType
|
||||
#endif
|
||||
? c.Get(t.GetGenericTypeDefinition(), n, typeof(TPolicyInterface)) ?? c.Get(null, null, typeof(TPolicyInterface))
|
||||
: c.Get(null, null, typeof(TPolicyInterface))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.Builder;
|
||||
using Unity.Interception.InterceptionBehaviors;
|
||||
using Unity.Interception.Interceptors;
|
||||
using Unity.Strategies;
|
||||
|
||||
namespace Unity.Interception.ContainerIntegration.ObjectBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="BuilderStrategy"/> that hooks up type interception. It looks for
|
||||
/// a <see cref="ITypeInterceptionPolicy"/> for the current build key, or the current
|
||||
/// build type. If present, it substitutes types so that that proxy class gets
|
||||
/// built up instead. On the way back, it hooks up the appropriate handlers.
|
||||
/// </summary>
|
||||
public class TypeInterceptionStrategy : BuilderStrategy
|
||||
{
|
||||
#region BuilderStrategy
|
||||
|
||||
/// <summary>
|
||||
/// Called during the chain of responsibility for a build operation. The
|
||||
/// PreBuildUp method is called when the chain is being executed in the
|
||||
/// forward direction.
|
||||
/// </summary>
|
||||
/// <remarks>In this class, PreBuildUp is responsible for figuring out if the
|
||||
/// class is proxyable, and if so, replacing it with a proxy class.</remarks>
|
||||
/// <param name="context">Context of the build operation.</param>
|
||||
public override void PreBuildUp(ref BuilderContext context)
|
||||
{
|
||||
if (context.Existing != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Type typeToBuild = context.Type;
|
||||
|
||||
var interceptionPolicy = GetPolicyOrDefault<ITypeInterceptionPolicy>(ref context);
|
||||
if (interceptionPolicy == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var interceptor = interceptionPolicy.GetInterceptor(ref context);
|
||||
if (!interceptor.CanIntercept(typeToBuild))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var interceptionBehaviorsPolicy = GetPolicyOrDefault<IInterceptionBehaviorsPolicy>(ref context);
|
||||
|
||||
IEnumerable<IInterceptionBehavior> interceptionBehaviors =
|
||||
interceptionBehaviorsPolicy == null
|
||||
?
|
||||
Enumerable.Empty<IInterceptionBehavior>()
|
||||
:
|
||||
interceptionBehaviorsPolicy.GetEffectiveBehaviors(
|
||||
ref context, interceptor, typeToBuild, typeToBuild)
|
||||
.Where(ib => ib.WillExecute);
|
||||
|
||||
IAdditionalInterfacesPolicy additionalInterfacesPolicy =
|
||||
GetPolicyOrDefault<IAdditionalInterfacesPolicy>(ref context);
|
||||
|
||||
IEnumerable<Type> additionalInterfaces =
|
||||
additionalInterfacesPolicy != null ? additionalInterfacesPolicy.AdditionalInterfaces : Type.EmptyTypes;
|
||||
|
||||
var enumerable = interceptionBehaviors as IInterceptionBehavior[] ?? interceptionBehaviors.ToArray();
|
||||
context.Registration.Set(typeof(EffectiveInterceptionBehaviorsPolicy),
|
||||
new EffectiveInterceptionBehaviorsPolicy { Behaviors = enumerable });
|
||||
|
||||
Type[] allAdditionalInterfaces =
|
||||
Intercept.GetAllAdditionalInterfaces(enumerable, additionalInterfaces);
|
||||
|
||||
context.Type = interceptor.CreateProxyType(typeToBuild, allAdditionalInterfaces);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called during the chain of responsibility for a build operation. The
|
||||
/// PostBuildUp method is called when the chain has finished the PreBuildUp
|
||||
/// phase and executes in reverse order from the PreBuildUp calls.
|
||||
/// </summary>
|
||||
/// <remarks>In this class, PostBuildUp checks to see if the object was proxyable,
|
||||
/// and if it was, wires up the handlers.</remarks>
|
||||
/// <param name="context">Context of the build operation.</param>
|
||||
public override void PostBuildUp(ref BuilderContext context)
|
||||
{
|
||||
IInterceptingProxy proxy = context.Existing as IInterceptingProxy;
|
||||
|
||||
if (proxy == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var effectiveInterceptionBehaviorsPolicy = (EffectiveInterceptionBehaviorsPolicy)context.Registration.Get(
|
||||
typeof(EffectiveInterceptionBehaviorsPolicy));
|
||||
|
||||
if (effectiveInterceptionBehaviorsPolicy == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var interceptionBehavior in effectiveInterceptionBehaviorsPolicy.Behaviors)
|
||||
{
|
||||
proxy.AddInterceptionBehavior(interceptionBehavior);
|
||||
}
|
||||
}
|
||||
|
||||
public static TPolicyInterface GetPolicyOrDefault<TPolicyInterface>(ref BuilderContext context)
|
||||
{
|
||||
return (TPolicyInterface)(GetNamedPolicy(ref context, context.RegistrationType, context.Name) ??
|
||||
GetNamedPolicy(ref context, context.RegistrationType, UnityContainer.All));
|
||||
|
||||
object GetNamedPolicy(ref BuilderContext c, Type t, string n)
|
||||
{
|
||||
return (c.Get(t, n, typeof(TPolicyInterface)) ?? (
|
||||
#if NETCOREAPP1_0 || NETSTANDARD1_0
|
||||
t.GetTypeInfo().IsGenericType
|
||||
#else
|
||||
t.IsGenericType
|
||||
#endif
|
||||
? c.Get(t.GetGenericTypeDefinition(), n, typeof(TPolicyInterface)) ?? c.Get(null, null, typeof(TPolicyInterface))
|
||||
: c.Get(null, null, typeof(TPolicyInterface))));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Nested Types
|
||||
|
||||
|
||||
private class EffectiveInterceptionBehaviorsPolicy
|
||||
{
|
||||
public EffectiveInterceptionBehaviorsPolicy()
|
||||
{
|
||||
Behaviors = new List<IInterceptionBehavior>();
|
||||
}
|
||||
|
||||
public IEnumerable<IInterceptionBehavior> Behaviors { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -20,6 +20,8 @@
|
|||
<AssemblyOriginatorKeyFile>package.snk</AssemblyOriginatorKeyFile>
|
||||
<DelaySign>false</DelaySign>
|
||||
<TargetFrameworks>netstandard2.0;net47;net46;net45;netcoreapp2.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -237,15 +237,16 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests
|
|||
.AddPolicy("policy1")
|
||||
.AddMatchingRule("rule1")
|
||||
.AddCallHandler("handler1")
|
||||
.AddCallHandler("handler2").Interception.Container
|
||||
.RegisterType<IMatchingRule, AlwaysMatchingRule>("rule1")
|
||||
.RegisterType<ICallHandler, GlobalCountCallHandler>(
|
||||
"handler1",
|
||||
new InjectionConstructor("handler1"))
|
||||
.RegisterType<ICallHandler, GlobalCountCallHandler>(
|
||||
"handler2",
|
||||
new InjectionConstructor("handler2"),
|
||||
new InjectionProperty("Order", 10));
|
||||
.AddCallHandler("handler2");
|
||||
|
||||
container.RegisterType<IMatchingRule, AlwaysMatchingRule>("rule1")
|
||||
.RegisterType<ICallHandler, GlobalCountCallHandler>(
|
||||
"handler1",
|
||||
new InjectionConstructor("handler1"))
|
||||
.RegisterType<ICallHandler, GlobalCountCallHandler>(
|
||||
"handler2",
|
||||
new InjectionConstructor("handler2"),
|
||||
new InjectionProperty("Order", 10));
|
||||
|
||||
GlobalCountCallHandler.Calls.Clear();
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace UnityInterception.Tests
|
|||
[TestMethod]
|
||||
public void unitycontainer_unity_177()
|
||||
{
|
||||
var container = new UnityContainer();
|
||||
IUnityContainer container = new UnityContainer();
|
||||
container.AddNewExtension<Interception>();
|
||||
|
||||
container.RegisterType<MyClass>(new ContainerControlledLifetimeManager());
|
||||
|
@ -79,7 +79,8 @@ namespace UnityInterception.Tests
|
|||
[TestMethod]
|
||||
public void unitycontainer_interception_162()
|
||||
{
|
||||
var container = new UnityContainer();
|
||||
IUnityContainer container = new UnityContainer();
|
||||
|
||||
container.AddNewExtension<Interception>();
|
||||
container.RegisterType<IMyClass, MyClass>(new ContainerControlledLifetimeManager(),
|
||||
new Interceptor<InterfaceInterceptor>(),
|
||||
|
|
|
@ -78,10 +78,10 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests
|
|||
callCountHandler = new CallCountHandler();
|
||||
returnHandler = new StringReturnRewriteHandler("REWRITE");
|
||||
|
||||
IUnityContainer container
|
||||
= new UnityContainer()
|
||||
.RegisterInstance<ICallHandler>("call count", callCountHandler)
|
||||
.RegisterInstance<ICallHandler>("rewrite", returnHandler);
|
||||
IUnityContainer container = new UnityContainer();
|
||||
|
||||
container.RegisterInstance<ICallHandler>("call count", callCountHandler)
|
||||
.RegisterInstance<ICallHandler>("rewrite", returnHandler);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
|
|
@ -111,11 +111,10 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests
|
|||
|
||||
private static IUnityContainer CreateConfiguredContainer()
|
||||
{
|
||||
IUnityContainer container =
|
||||
new UnityContainer()
|
||||
.RegisterType<ICallHandler, Handler1>("handler1")
|
||||
.RegisterType<ICallHandler, Handler2>("handler2")
|
||||
.RegisterType<ICallHandler, Handler3>("handler3");
|
||||
IUnityContainer container = new UnityContainer();
|
||||
container.RegisterType<ICallHandler, Handler1>("handler1")
|
||||
.RegisterType<ICallHandler, Handler2>("handler2")
|
||||
.RegisterType<ICallHandler, Handler3>("handler3");
|
||||
return container;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,17 +22,19 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.PolicyInjection
|
|||
protected virtual void Arrange()
|
||||
{
|
||||
Container =
|
||||
new UnityContainer()
|
||||
.RegisterType<BaseClass, DerivedClass>("derived",
|
||||
new UnityContainer();
|
||||
|
||||
Container.RegisterType<BaseClass, DerivedClass>("derived",
|
||||
new Interceptor<TransparentProxyInterceptor>(),
|
||||
new InterceptionBehavior<PolicyInjectionBehavior>())
|
||||
.RegisterType<BaseClass, DerivedWithNoOverrideClass>("derived-nooverride",
|
||||
new InterceptionBehavior<PolicyInjectionBehavior>());
|
||||
Container.RegisterType<BaseClass, DerivedWithNoOverrideClass>("derived-nooverride",
|
||||
new Interceptor<TransparentProxyInterceptor>(),
|
||||
new InterceptionBehavior<PolicyInjectionBehavior>())
|
||||
.RegisterType<BaseClass>(
|
||||
new InterceptionBehavior<PolicyInjectionBehavior>());
|
||||
Container.RegisterType<BaseClass>(
|
||||
new Interceptor<TransparentProxyInterceptor>(),
|
||||
new InterceptionBehavior<PolicyInjectionBehavior>())
|
||||
.AddNewExtension<Interception>()
|
||||
new InterceptionBehavior<PolicyInjectionBehavior>());
|
||||
|
||||
Container.AddNewExtension<Interception>()
|
||||
.Configure<Interception>()
|
||||
.AddPolicy("base")
|
||||
.AddMatchingRule(new TypeMatchingRule(typeof(BaseClass)))
|
||||
|
@ -47,9 +49,7 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.PolicyInjection
|
|||
.AddPolicy("derived")
|
||||
.AddMatchingRule(new TypeMatchingRule(typeof(DerivedClass)))
|
||||
.AddMatchingRule(new MemberNameMatchingRule("InterceptedMethod"))
|
||||
.AddCallHandler(new AppendSuffixCallHandler { Suffix = "-derivedhandler", Order = 3 })
|
||||
.Interception
|
||||
.Container;
|
||||
.AddCallHandler(new AppendSuffixCallHandler { Suffix = "-derivedhandler", Order = 3 });
|
||||
}
|
||||
|
||||
public IUnityContainer Container { get; set; }
|
||||
|
|
|
@ -15,7 +15,8 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.TransparentProxy
|
|||
[TestMethod]
|
||||
public void CanInterceptGenericMethodWithHandlerAttributeThroughInterface()
|
||||
{
|
||||
var container = new UnityContainer();
|
||||
IUnityContainer container = new UnityContainer();
|
||||
|
||||
container.AddNewExtension<Interception>();
|
||||
container.RegisterType<IInterfaceWithGenericMethod, ClassWithGenericMethod>(
|
||||
new Interceptor(new TransparentProxyInterceptor()));
|
||||
|
|
|
@ -118,14 +118,12 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.VirtualMethodInt
|
|||
[TestMethod]
|
||||
public void CanInterceptWithInterceptorSetAsDefaultForBaseClassWithMultipleImplementations()
|
||||
{
|
||||
IUnityContainer container =
|
||||
new UnityContainer()
|
||||
.RegisterType<BaseClass, ImplementationOne>("one")
|
||||
.RegisterType<BaseClass, ImplementationTwo>("two")
|
||||
.AddNewExtension<Interception>()
|
||||
.Configure<Interception>()
|
||||
.SetDefaultInterceptorFor<BaseClass>(new VirtualMethodInterceptor())
|
||||
.Container;
|
||||
IUnityContainer container = new UnityContainer();
|
||||
container.RegisterType<BaseClass, ImplementationOne>("one")
|
||||
.RegisterType<BaseClass, ImplementationTwo>("two")
|
||||
.AddNewExtension<Interception>()
|
||||
.Configure<Interception>()
|
||||
.SetDefaultInterceptorFor<BaseClass>(new VirtualMethodInterceptor());
|
||||
|
||||
BaseClass instanceOne = container.Resolve<BaseClass>("one");
|
||||
BaseClass instanceTwo = container.Resolve<BaseClass>("two");
|
||||
|
|
Загрузка…
Ссылка в новой задаче