예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
            }
        }