コード例 #1
0
 private DerivedTypeConstructorSelectorPolicy(
     Type interceptingType,
     IConstructorSelectorPolicy originalConstructorSelectorPolicy)
 {
     _interceptingType = interceptingType;
     _originalConstructorSelectorPolicy = originalConstructorSelectorPolicy;
 }
コード例 #2
0
        public void InjectionConstructorInsertsChooserForConstructorWithParameters()
        {
            string expectedString = "Hello";
            int    expectedInt    = 12;

            InjectionConstructor  ctor    = new InjectionConstructor(expectedString, expectedInt);
            TestingBuilderContext context = new TestingBuilderContext();

            context.BuildKey = typeof(GuineaPig);
            IPolicyList policies = context.PersistentPolicies;

            ctor.AddPolicies(typeof(GuineaPig), policies);

            IConstructorSelectorPolicy selector = policies.Get <IConstructorSelectorPolicy>(
                new NamedTypeBuildKey(typeof(GuineaPig)));

            SelectedConstructor selected = selector.SelectConstructor(context);

            string[] keys = selected.GetParameterKeys();

            Assert.AreEqual(typeof(GuineaPig).GetConstructor(Sequence.Collect(typeof(string), typeof(int))), selected.Constructor);
            Assert.AreEqual(2, keys.Length);

            Assert.AreEqual(expectedString, (string)ResolveValue(policies, keys[0]));
            Assert.AreEqual(expectedInt, (int)ResolveValue(policies, keys[1]));
        }
コード例 #3
0
        public void InjectionConstructorSetsResolverForInterfaceToLookupInContainer()
        {
            InjectionConstructor  ctor    = new InjectionConstructor("Logger", typeof(ILogger));
            TestingBuilderContext context = new TestingBuilderContext();

            context.BuildKey = typeof(GuineaPig);
            IPolicyList policies = context.PersistentPolicies;

            ctor.AddPolicies(typeof(GuineaPig), policies);

            IConstructorSelectorPolicy selector = policies.Get <IConstructorSelectorPolicy>(
                new NamedTypeBuildKey(typeof(GuineaPig)));

            SelectedConstructor selected = selector.SelectConstructor(context);

            string[] keys = selected.GetParameterKeys();

            Assert.AreEqual(typeof(GuineaPig).GetConstructor(Sequence.Collect(typeof(string), typeof(ILogger))), selected.Constructor);
            Assert.AreEqual(2, keys.Length);

            IDependencyResolverPolicy policy =
                context.Policies.Get <IDependencyResolverPolicy>(keys[1]);

            Assert.IsTrue(policy is NamedTypeDependencyResolverPolicy);
        }
コード例 #4
0
 public DerivedTypeConstructorSelectorPolicy(
     Type interceptingType,
     IConstructorSelectorPolicy originalConstructorSelectorPolicy)
 {
     this.interceptingType = interceptingType;
     this.originalConstructorSelectorPolicy = originalConstructorSelectorPolicy;
 }
コード例 #5
0
        public void SelectorPicksDefaultConstructor()
        {
            IConstructorSelectorPolicy policy       = CreateSelector();
            ConstructorInfo            expectedCtor = GetConstructor <object>();
            MockBuilderContext         context      = GetContext <object>();
            SelectedConstructor        result       = policy.SelectConstructor(context, new PolicyList());

            Assert.AreEqual(expectedCtor, result.Constructor);
        }
コード例 #6
0
        public void SelectorPicksConstructorWithAttribute()
        {
            IConstructorSelectorPolicy policy   = CreateSelector();
            ConstructorInfo            expected = GetConstructor <ObjectWithMarkedConstructor>(typeof(string));

            SelectedConstructor result = policy.SelectConstructor(GetContext <ObjectWithMarkedConstructor>(), new PolicyList());

            Assert.AreEqual(expected, result.Constructor);
        }
コード例 #7
0
        public void SelectorPicksLongestConstructor()
        {
            IConstructorSelectorPolicy policy   = CreateSelector();
            ConstructorInfo            expected = GetConstructor <ObjectWithMultipleConstructors>(
                typeof(int), typeof(string));

            SelectedConstructor result =
                policy.SelectConstructor(GetContext <ObjectWithMultipleConstructors>(), new PolicyList());

            Assert.AreEqual(expected, result.Constructor);
        }
コード例 #8
0
        public void SelectorPicksMarkedConstructorEvenIfOtherwiseAmbiguous()
        {
            IConstructorSelectorPolicy policy   = CreateSelector();
            ConstructorInfo            expected = GetConstructor <ObjectWithAmbiguousMarkedConstructor>(
                typeof(string), typeof(string), typeof(int));

            SelectedConstructor result =
                policy.SelectConstructor(GetContext <ObjectWithAmbiguousMarkedConstructor>(), new PolicyList());

            Assert.AreEqual(expected, result.Constructor);
        }
コード例 #9
0
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            DynamicBuildPlanGenerationContext buildContext =
                (DynamicBuildPlanGenerationContext)context.Existing;

            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey);

            SelectedConstructor selectedCtor = selector.SelectConstructor(context);
            // Method preamble - test if we have an existing object
            // First off, set up jump - if there's an existing object, skip us entirely
            Label existingObjectNotNull = buildContext.IL.DefineLabel();

            buildContext.EmitLoadExisting();
            buildContext.IL.Emit(OpCodes.Ldnull);
            buildContext.IL.Emit(OpCodes.Ceq);
            buildContext.IL.Emit(OpCodes.Brfalse, existingObjectNotNull);

            if (selectedCtor != null)
            {
                // Resolve parameters
                ParameterInfo[] parameters = selectedCtor.Constructor.GetParameters();

                int i = 0;
                foreach (string parameterKey in selectedCtor.GetParameterKeys())
                {
                    buildContext.EmitResolveDependency(parameters[i].ParameterType, parameterKey);
                    ++i;
                }

                // Call the constructor

                buildContext.IL.Emit(OpCodes.Newobj, selectedCtor.Constructor);
                buildContext.EmitStoreExisting();
            }
            else
            {
                // If we get here, object has no constructors. It's either
                // an interface or a primitive (like int). In this case,
                // verify that we have an Existing object, and if not,
                // throw (via helper function).
                buildContext.EmitLoadContext();
                buildContext.IL.EmitCall(OpCodes.Call, throwForNullExistingObject, null);
            }

            buildContext.IL.MarkLabel(existingObjectNotNull);
        }
コード例 #10
0
        public void SelectorThrowsIfConstructorsAreAmbiguous()
        {
            IConstructorSelectorPolicy policy = CreateSelector();

            try
            {
                policy.SelectConstructor(GetContext <ObjectWithAmbiguousConstructors>(), new PolicyList());
            }
            catch (InvalidOperationException)
            {
                // If we got here we're ok
                return;
            }
            Assert.Fail("Expected exception did not occur");
        }
コード例 #11
0
        public void InjectionConstructorInsertsChooserForDefaultConstructor()
        {
            InjectionConstructor  ctor     = new InjectionConstructor();
            TestingBuilderContext context  = new TestingBuilderContext();
            IPolicyList           policies = context.PersistentPolicies;

            ctor.AddPolicies(typeof(GuineaPig), policies);

            IConstructorSelectorPolicy selector = policies.Get <IConstructorSelectorPolicy>(
                new NamedTypeBuildKey(typeof(GuineaPig)));

            SelectedConstructor selected = selector.SelectConstructor(context);

            Assert.AreEqual(typeof(GuineaPig).GetConstructor(new Type[0]), selected.Constructor);
            Assert.AreEqual(0, selected.GetParameterKeys().Length);
        }
コード例 #12
0
        internal Expression CreateInstanceBuildupExpression(DynamicBuildPlanGenerationContext buildContext, IBuilderContext context)
        {
            var targetTypeInfo = context.BuildKey.Type.GetTypeInfo();

            if (targetTypeInfo.IsInterface)
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructInterfaceMethod));
            }

            if (targetTypeInfo.IsAbstract)
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructAbstractClassMethod));
            }

            if (targetTypeInfo.IsSubclassOf(typeof(Delegate)))
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructDelegateMethod));
            }

            var ss = ((System.Collections.IEnumerable)context.Policies);

            IPolicyList resolverPolicyDestination;
            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey, out resolverPolicyDestination);

            SelectedConstructor selectedConstructor = selector.SelectConstructor(context, resolverPolicyDestination);

            if (selectedConstructor == null)
            {
                return(CreateThrowWithContext(buildContext, ThrowForNullExistingObjectMethod));
            }

            string signature = CreateSignatureString(selectedConstructor.Constructor);

            if (selectedConstructor.Constructor.GetParameters().Any(pi => pi.ParameterType.IsByRef))
            {
                return(CreateThrowForNullExistingObjectWithInvalidConstructor(buildContext, signature));
            }

            if (IsInvalidConstructor(targetTypeInfo, context, selectedConstructor))
            {
                return(CreateThrowForReferenceItselfMethodConstructor(buildContext, signature));
            }


            return(Expression.Block(CreateNewBuildupSequence(buildContext, selectedConstructor, signature)));
        }
コード例 #13
0
        internal Expression CreateInstanceBuildupExpression(DynamicBuildPlanGenerationContext buildContext, IBuilderContext context)
        {
            var targetTypeInfo = context.BuildKey.Type.GetTypeInfo();

            if (targetTypeInfo.IsInterface)
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructInterfaceMethod));
            }

            if (targetTypeInfo.IsAbstract)
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructAbstractClassMethod));
            }

            if (targetTypeInfo.IsSubclassOf(typeof(Delegate)))
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructDelegateMethod));
            }

            IPolicyList resolverPolicyDestination;
            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey, out resolverPolicyDestination);

            SelectedConstructor selectedConstructor = selector.SelectConstructor(context, resolverPolicyDestination);

            if (selectedConstructor == null)
            {
                return(CreateThrowWithContext(buildContext, ThrowForNullExistingObjectMethod));
            }

            string signature = DynamicMethodConstructorStrategy.CreateSignatureString(selectedConstructor.Constructor);

            if (IsInvalidConstructor(selectedConstructor))
            {
                return(CreateThrowForNullExistingObjectWithInvalidConstructor(buildContext, signature));
            }

            // psuedo-code:
            // throw if attempting interface
            // if (context.Existing == null) {
            //   collect parameters
            //   set operation to invoking constructor
            //   context.Existing = new {objectType}({constructorparameter}...)
            //   clear current operation
            // }
            return(Expression.Block(this.CreateNewBuildupSequence(buildContext, selectedConstructor, signature)));
        }
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.AssertNotNull(context, "context");
            Guard.AssertNotNull(context.BuildKey, "context.BuildKey");
            Guard.AssertNotNull(context.Policies, "context.Policies");

            if (context.Policies.Get <IMapParameterNameToRegistrationNamePolicy>(context.BuildKey) == null)
            {
                return;
            }

            IPolicyList resolverPolicyDestination;
            IConstructorSelectorPolicy selector = context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey, out resolverPolicyDestination);

            if (selector == null)
            {
                return;
            }

            var selectedConstructor = selector.SelectConstructor(context, resolverPolicyDestination);

            if (selectedConstructor == null)
            {
                return;
            }

            ParameterInfo[] parameters = selectedConstructor.Constructor.GetParameters();

            //string[] parameterKeys = selectedConstructor.GetParameterKeys();

            for (int i = 0; i < parameters.Length; i++)
            {
                Type parameterType = parameters[i].ParameterType;

                if (parameterType.IsAbstract || parameterType.IsInterface || (parameterType.IsClass && parameterType != typeof(string)))
                {
                    IDependencyResolverPolicy resolverPolicy = new NamedTypeDependencyResolverPolicy(parameterType, parameters[i].Name);
                    //context.Policies.Set<IDependencyResolverPolicy>(resolverPolicy, parameterKeys[i]);
                    context.Policies.Set <IDependencyResolverPolicy>(resolverPolicy, parameters[i].Name);
                }
            }

            resolverPolicyDestination.Set <IConstructorSelectorPolicy>(new SelectedConstructorCache(selectedConstructor), context.BuildKey);
        }
コード例 #15
0
			public DerivedTypeConstructorSelectorPolicy(Type interceptingType, IConstructorSelectorPolicy originalConstructorSelectorPolicy)
			{
				_interceptingType = interceptingType;
				_originalConstructorSelectorPolicy = originalConstructorSelectorPolicy;
			}
コード例 #16
0
        public void SelectorThrowsIfConstructorsAreAmbiguous()
        {
            IConstructorSelectorPolicy policy = CreateSelector();

            Assert.Throws <InvalidOperationException>(() => policy.SelectConstructor(GetContext <ObjectWithAmbiguousConstructors>(), new PolicyList()));
        }
コード例 #17
0
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            DynamicBuildPlanGenerationContext buildContext =
                (DynamicBuildPlanGenerationContext)context.Existing;

            IPolicyList resolverPolicyDestination;
            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey, out resolverPolicyDestination);

            SelectedConstructor selectedCtor = selector.SelectConstructor(context, resolverPolicyDestination);

            GuardTypeIsNonPrimitive(context, selectedCtor);

            // Method preamble - test if we have an existing object
            // First off, set up jump - if there's an existing object, skip us entirely
            Label existingObjectNotNull = buildContext.IL.DefineLabel();

            if (!buildContext.TypeToBuild.IsValueType)
            {
                buildContext.EmitLoadExisting();
                buildContext.IL.Emit(OpCodes.Brtrue, existingObjectNotNull);
            }

            // Verify we're not attempting to create an instance of an interface
            buildContext.EmitLoadContext();
            buildContext.IL.EmitCall(OpCodes.Call, throwForAttemptingToConstructInterface, null);

            if (selectedCtor != null)
            {
                string signatureString = CreateSignatureString(selectedCtor.Constructor);

                // Resolve parameters
                ParameterInfo[] parameters = selectedCtor.Constructor.GetParameters();

                if (!parameters.Any(pi => pi.ParameterType.IsByRef))
                {
                    int i = 0;
                    foreach (string parameterKey in selectedCtor.GetParameterKeys())
                    {
                        // Set the current operation
                        buildContext.IL.Emit(OpCodes.Ldstr, parameters[i].Name);
                        buildContext.IL.Emit(OpCodes.Ldstr, signatureString);
                        buildContext.EmitLoadContext();
                        buildContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToResolvingParameter, null);

                        // Resolve the parameter
                        buildContext.EmitResolveDependency(parameters[i].ParameterType, parameterKey);
                        ++i;
                    }

                    // Set the current operation
                    buildContext.IL.Emit(OpCodes.Ldstr, signatureString);
                    buildContext.EmitLoadContext();
                    buildContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToInvokingConstructor, null);

                    // Call the constructor
                    buildContext.IL.Emit(OpCodes.Newobj, selectedCtor.Constructor);

                    // Store the existing object
                    buildContext.EmitStoreExisting();

                    // Clear the current operation
                    buildContext.EmitClearCurrentOperation();

                    // Store existing object back into context - makes it available for future resolvers
                    buildContext.EmitLoadContext();
                    buildContext.EmitLoadExisting();
                    if (buildContext.TypeToBuild.IsValueType)
                    {
                        buildContext.IL.Emit(OpCodes.Box, buildContext.TypeToBuild);
                    }
                    buildContext.IL.EmitCall(OpCodes.Callvirt, setExistingInContext, null);

                    // Is this object a per-build singleton? If so, then emit code to stuff in
                    // the appropriate lifetime manager.
                    buildContext.EmitLoadContext();
                    buildContext.IL.EmitCall(OpCodes.Call, setPerBuildSingleton, null);
                }
                else
                {
                    // if we get here the selected constructor has ref or out parameters.
                    buildContext.EmitLoadContext();
                    buildContext.IL.Emit(OpCodes.Ldstr, signatureString);
                    buildContext.IL.EmitCall(OpCodes.Call, throwForNullExistingObjectWithInvalidConstructor, null);
                }
            }
            else
            {
                // If we get here, object has no constructors. It's either
                // an interface or a primitive (like int). In this case,
                // verify that we have an Existing object, and if not,
                // throw (via helper function).
                buildContext.EmitLoadContext();
                buildContext.IL.EmitCall(OpCodes.Call, throwForNullExistingObject, null);
            }

            buildContext.IL.MarkLabel(existingObjectNotNull);
        }
コード例 #18
0
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            DynamicBuildPlanGenerationContext buildContext =
                (DynamicBuildPlanGenerationContext)context.Existing;

            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey);

            SelectedConstructor selectedCtor = selector.SelectConstructor(context);
            // Method preamble - test if we have an existing object
            // First off, set up jump - if there's an existing object, skip us entirely
            Label existingObjectNotNull = buildContext.IL.DefineLabel();

            buildContext.EmitLoadExisting();
            buildContext.IL.Emit(OpCodes.Ldnull);
            buildContext.IL.Emit(OpCodes.Ceq);
            buildContext.IL.Emit(OpCodes.Brfalse, existingObjectNotNull);

            // Verify we're not attempting to create an instance of an interface
            buildContext.EmitLoadContext();
            buildContext.IL.EmitCall(OpCodes.Call, throwForAttemptingToConstructInterface, null);

            if (selectedCtor != null)
            {
                string       signatureString      = CreateSignatureString(selectedCtor.Constructor);
                LocalBuilder currentParameterName = buildContext.IL.DeclareLocal(typeof(string));

                // Resolve parameters
                ParameterInfo[] parameters = selectedCtor.Constructor.GetParameters();

                buildContext.IL.BeginExceptionBlock();

                int i = 0;
                foreach (string parameterKey in selectedCtor.GetParameterKeys())
                {
                    buildContext.IL.Emit(OpCodes.Ldstr, parameters[i].Name);
                    buildContext.IL.Emit(OpCodes.Stloc, currentParameterName);
                    buildContext.EmitResolveDependency(parameters[i].ParameterType, parameterKey);
                    ++i;
                }

                // Call the constructor

                buildContext.IL.Emit(OpCodes.Ldnull);
                buildContext.IL.Emit(OpCodes.Stloc, currentParameterName);

                buildContext.IL.Emit(OpCodes.Newobj, selectedCtor.Constructor);
                buildContext.EmitStoreExisting();

                buildContext.IL.BeginCatchBlock(typeof(Exception));
                Label exceptionOccuredInResolution = buildContext.IL.DefineLabel();

                buildContext.IL.Emit(OpCodes.Ldloc, currentParameterName);
                buildContext.IL.Emit(OpCodes.Ldnull);
                buildContext.IL.Emit(OpCodes.Ceq);
                buildContext.IL.Emit(OpCodes.Brfalse, exceptionOccuredInResolution);
                buildContext.IL.Emit(OpCodes.Rethrow);

                buildContext.IL.MarkLabel(exceptionOccuredInResolution);
                buildContext.IL.Emit(OpCodes.Ldloc, currentParameterName);
                buildContext.IL.Emit(OpCodes.Ldstr, signatureString);
                buildContext.EmitLoadContext();
                buildContext.IL.EmitCall(OpCodes.Call, throwForResolutionFailed, null);

                buildContext.IL.EndExceptionBlock();
            }
            else
            {
                // If we get here, object has no constructors. It's either
                // an interface or a primitive (like int). In this case,
                // verify that we have an Existing object, and if not,
                // throw (via helper function).
                buildContext.EmitLoadContext();
                buildContext.IL.EmitCall(OpCodes.Call, throwForNullExistingObject, null);
            }

            buildContext.IL.MarkLabel(existingObjectNotNull);
        }
コード例 #19
0
        private static SelectedConstructor GetCurrentConstructor(IBuilderContext context)
        {
            IConstructorSelectorPolicy originalSelector = context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey);

            return(originalSelector.SelectConstructor(context));
        }
 public DerivedTypeConstructorSelectorPolicy(IUnityContainer container, IConstructorSelectorPolicy originalSelectorPolicy)
 {
     this._originalConstructorSelectorPolicy = originalSelectorPolicy;
     this._container = container;
 }