/// <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 proxiable, and if so, replacing it with a proxy class.</remarks> /// <param name="context">Context of the build operation.</param> public override void PreBuildUp(IBuilderContext context) { Guard.ArgumentNotNull(context, "context"); if (context.Existing != null) { return; } Type typeToBuild; if (!BuildKey.TryGetType(context.BuildKey, out typeToBuild)) { return; } ITypeInterceptionPolicy interceptionPolicy = GetInterceptionPolicy(context); if (interceptionPolicy == null) { return; } if (!interceptionPolicy.Interceptor.CanIntercept(typeToBuild)) { return; } lock (lockObj) { if (interceptionPolicy.ProxyType == null) { Type typeToIntercept = typeToBuild; if (typeToIntercept.IsGenericType) { typeToIntercept = typeToIntercept.GetGenericTypeDefinition(); } interceptionPolicy.ProxyType = interceptionPolicy.Interceptor.CreateProxyType(typeToIntercept); } } Type interceptingType = interceptionPolicy.ProxyType; if (interceptingType.IsGenericTypeDefinition) { interceptingType = interceptingType.MakeGenericType(typeToBuild.GetGenericArguments()); } SelectedConstructor currentConstructor = GetCurrentConstructor(context); SelectedConstructor newConstructor = FindNewConstructor(currentConstructor, interceptingType); IConstructorSelectorPolicy newSelector = new ConstructorWithResolverKeysSelectorPolicy(newConstructor); context.Policies.Set(newSelector, context.BuildKey); }
/// <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(IBuilderContext context) { Guard.ArgumentNotNull(context, "context"); IInterceptingProxy proxy = context.Existing as IInterceptingProxy; if (proxy == null) { return; } ITypeInterceptionPolicy interceptionPolicy = GetInterceptionPolicy(context); Type typeToIntercept = BuildKey.GetType(context.BuildKey); PolicySet interceptionPolicies = new PolicySet(BuilderContext.NewBuildUp <InjectionPolicy[]>(context)); IUnityContainer currentContainer = BuilderContext.NewBuildUp <IUnityContainer>(context); foreach (MethodImplementationInfo item in interceptionPolicy.Interceptor.GetInterceptableMethods(typeToIntercept, typeToIntercept)) { HandlerPipeline pipeline = new HandlerPipeline( interceptionPolicies.GetHandlersFor(item, currentContainer)); proxy.SetPipeline(interceptionPolicy.Interceptor.MethodInfoForPipeline(item), pipeline); } }