/// <inheritdoc/>
        public IGetsFailureMessage GetNonGenericFailureMessageProvider(MessageProviderTypeInfo providerType, Type ruleInterface)
        {
            var ruleInterfaceInfo = ruleInterface.GetTypeInfo();
            var method            = getSingleGenericFailureMessageMethod.MakeGenericMethod(ruleInterfaceInfo.GenericTypeArguments[0]);

            return((IGetsFailureMessage)method.Invoke(this, new[] { providerType.ProviderType }));
        }
        public void GetMessageProviderInfoShouldCreateProviderUsingLazyResolutionFromTheFactory([Frozen] IGetsCandidateMessageTypes typeRegistry,
                                                                                                [Frozen] IGetsMessageProviderFactoryStrategy factoryStrategySelector,
                                                                                                MessageProviderInfoFactory sut,
                                                                                                int irrelevantPriority,
                                                                                                [RuleResult] ValidationRuleResult ruleResult,
                                                                                                IGetsNonGenericMessageProvider factory,
                                                                                                IGetsFailureMessage provider)
        {
            MessageProviderTypeInfo
                type = new MessageProviderTypeInfo(typeof(string), irrelevantPriority);

            Mock.Get(typeRegistry).Setup(x => x.GetCandidateMessageProviderTypes(ruleResult)).Returns(new[] { type });
            Mock.Get(factoryStrategySelector).Setup(x => x.GetMessageProviderFactory(type, ruleResult.RuleInterface)).Returns(factory);
            Mock.Get(factory).Setup(x => x.GetNonGenericFailureMessageProvider(type, ruleResult.RuleInterface)).Returns(provider);

            var result = sut.GetMessageProviderInfo(ruleResult);

            Assert.Multiple(() =>
            {
                Mock.Get(factory).Verify(x => x.GetNonGenericFailureMessageProvider(type, It.IsAny <Type>()),
                                         Times.Never,
                                         "Because the provider hasn't been accessed, the factory should not have yet been used");
                Assert.That(result.Single().MessageProvider,
                            Is.SameAs(provider),
                            "The returned message provider is the same as the expected one.");
                Mock.Get(factory).Verify(x => x.GetNonGenericFailureMessageProvider(type, ruleResult.RuleInterface),
                                         Times.Once,
                                         "Now that the provider has been accessed, the factory should have been executed");
            });
        }
 public void GetCandidateMessageProviderTypesShouldAlwaysReturnWrappedResults([Frozen] IGetsCandidateMessageTypes wrapped,
                                                                              RuleWithMessageCandidateTypeDecorator sut,
                                                                              MessageProviderTypeInfo typeInfo1,
                                                                              MessageProviderTypeInfo typeInfo2,
                                                                              MessageProviderTypeInfo typeInfo3,
                                                                              [RuleResult] ValidationRuleResult result)
 {
     Mock.Get(wrapped).Setup(x => x.GetCandidateMessageProviderTypes(result)).Returns(new[] { typeInfo1, typeInfo2, typeInfo3 });
     Assert.That(() => sut.GetCandidateMessageProviderTypes(result), Is.SupersetOf(new[] { typeInfo1, typeInfo2, typeInfo3 }));
 }
        /// <summary>
        /// Initialises a new instance of <see cref="MessageProviderTypeInfo"/>.
        /// </summary>
        /// <param name="copyFrom">An instance to copy from.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="copyFrom"/> is <see langword="null" />.</exception>
        protected MessageProviderTypeInfo(MessageProviderTypeInfo copyFrom)
        {
            if (copyFrom is null)
            {
                throw new ArgumentNullException(nameof(copyFrom));
            }

            this.ProviderType     = copyFrom.ProviderType;
            this.ProviderTypeInfo = copyFrom.ProviderTypeInfo;
            this.Priority         = copyFrom.Priority;
        }
        public void GetMessageProviderInfoShouldReturnProvidersCreatedFromRegistryTypeInfoExcludingThoseForWhichThereIsNoFactory([Frozen] IGetsCandidateMessageTypes typeRegistry,
                                                                                                                                 [Frozen] IGetsMessageProviderFactoryStrategy factoryStrategySelector,
                                                                                                                                 MessageProviderInfoFactory sut,
                                                                                                                                 int irrelevantPriority,
                                                                                                                                 [RuleResult] ValidationRuleResult ruleResult,
                                                                                                                                 IGetsNonGenericMessageProvider factory)
        {
            MessageProviderTypeInfo
                type1 = new MessageProviderTypeInfo(typeof(string), irrelevantPriority),
                type2 = new MessageProviderTypeInfo(typeof(int), irrelevantPriority),
                type3 = new MessageProviderTypeInfo(typeof(bool), irrelevantPriority);

            Mock.Get(typeRegistry).Setup(x => x.GetCandidateMessageProviderTypes(ruleResult)).Returns(new[] { type1, type2, type3 });
            Mock.Get(factoryStrategySelector).Setup(x => x.GetMessageProviderFactory(type1, ruleResult.RuleInterface)).Returns(factory);
            Mock.Get(factoryStrategySelector).Setup(x => x.GetMessageProviderFactory(type2, ruleResult.RuleInterface)).Returns(() => null);
            Mock.Get(factoryStrategySelector).Setup(x => x.GetMessageProviderFactory(type3, ruleResult.RuleInterface)).Returns(factory);

            var result = sut.GetMessageProviderInfo(ruleResult);

            Assert.That(result.Select(x => x.ProviderType), Is.EquivalentTo(new[] { typeof(string), typeof(bool) }));
        }
Esempio n. 6
0
        /// <summary>
        /// Gets a message provider factory which is appropriate for the specified provider type and rule interface.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method will examine the message provider interfaces which are implemented by the
        /// <see cref="MessageProviderTypeInfo.ProviderTypeInfo"/> of the <paramref name="messageProviderTypeInfo"/>.
        /// Specifically it will consider all implementations of any of:
        /// </para>
        /// <list type="number">
        /// <item><description><see cref="IGetsFailureMessage{TValidated, TParent}"/></description></item>
        /// <item><description><see cref="IGetsFailureMessage{TValidated}"/></description></item>
        /// <item><description><see cref="IGetsFailureMessage"/></description></item>
        /// </list>
        /// <para>
        /// It will then return a message-provider-factory strategy implementation which best-matches the interfaces
        /// indicated by the <paramref name="messageProviderTypeInfo"/>, based upon the actual validation rule interface
        /// which is in-use: <paramref name="ruleInterface"/>.
        /// </para>
        /// <para>
        /// This 'matching' process will look for matches in the order the message provider interfaces are listed
        /// above.  For example, if a message provider implements the interface with two generic types, and for types that
        /// are compatible with the generic types present upon the rule interface, then the double-generic strategy
        /// will be given preference over a single-generic strategy.  This is true even if the message provider type also
        /// implements a single-generic message provider interface that is compatible with the rule interface.
        /// </para>
        /// <para>
        /// Obviously, if the message provider type implements the non-generic <see cref="IGetsFailureMessage"/> then
        /// this will match every possible rule interface, as it is non-generic.  This behaviour may be leveraged as
        /// a fall-back option for unexpected scenarios (such as validating <see cref="RuleOutcome.Errored"/> results).
        /// </para>
        /// <para>
        /// If this method cannot find any suitable strategy for getting a message provider - the provider type indicated
        /// by <paramref name="messageProviderTypeInfo"/> does not implement any interface which is compatible with the
        /// <paramref name="ruleInterface"/> - then it will return <see langword="null" />.  This means that no factory
        /// strategy is applicable and that the provider type is not compatible with the rule interface.
        /// </para>
        /// </remarks>
        /// <param name="messageProviderTypeInfo">The candidate message provider type.</param>
        /// <param name="ruleInterface">The interface used for the validation rule.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">If any parameter is <see langword="null" />.</exception>
        public IGetsNonGenericMessageProvider GetMessageProviderFactory(MessageProviderTypeInfo messageProviderTypeInfo, Type ruleInterface)
        {
            if (messageProviderTypeInfo is null)
            {
                throw new ArgumentNullException(nameof(messageProviderTypeInfo));
            }
            if (ruleInterface is null)
            {
                throw new ArgumentNullException(nameof(ruleInterface));
            }

            if (messageProviderTypeInfo is InstanceMessageProviderInfo)
            {
                return(serviceProvider.GetRequiredService <UseExistingInstanceMessageProviderStrategy>());
            }

            var providerTypeInfo  = messageProviderTypeInfo.ProviderTypeInfo;
            var ruleInterfaceInfo = ruleInterface.GetTypeInfo();

            if (!IsValidRuleInterface(ruleInterfaceInfo))
            {
                throw GetIncorrectRuleInterfaceException(ruleInterface);
            }

            if (ImplementsDoubleGenericMessageInterface(providerTypeInfo, ruleInterfaceInfo))
            {
                return(serviceProvider.GetRequiredService <DoubleGenericMessageProviderStrategy>());
            }
            if (ImplementsSingleGenericMessageInterface(providerTypeInfo, ruleInterfaceInfo))
            {
                return(serviceProvider.GetRequiredService <SingleGenericMessageProviderStrategy>());
            }
            if (nonGenericProviderTypeInfo.IsAssignableFrom(providerTypeInfo))
            {
                return(serviceProvider.GetRequiredService <NonGenericMessageProviderStrategy>());
            }

            return(null);
        }
Esempio n. 7
0
        static MessageProviderTypeInfo GetNonGenericMessageProvider(ValidationRuleResult result,
                                                                    Type openGenericRuleInterface,
                                                                    Type openGenericRuleWithMessageInterface,
                                                                    Type openGenericAdapterType)
        {
            if (!result.RuleInterface.IsGenericType ||
                result.RuleInterface.GetGenericTypeDefinition() != openGenericRuleInterface)
            {
                return(null);
            }

            var ruleWithMessageType = openGenericRuleWithMessageInterface.MakeGenericType(result.RuleInterface.GenericTypeArguments);

            if (!ruleWithMessageType.IsInstanceOfType(result.ValidationLogic.RuleObject))
            {
                return(null);
            }

            var adapterType = openGenericAdapterType.MakeGenericType(result.RuleInterface.GenericTypeArguments);
            var provider    = (IGetsFailureMessage)Activator.CreateInstance(adapterType, new[] { result.ValidationLogic.RuleObject });
            var typeInfo    = new MessageProviderTypeInfo(result.ValidationLogic.RuleObject.GetType(), priorityForRuleWithMessage);

            return(new InstanceMessageProviderInfo(typeInfo, provider));
        }
 /// <summary>
 /// Initialises a new instance of <see cref="LazyMessageProviderInfo"/>.
 /// </summary>
 /// <param name="typeInfo">Message provider type info.</param>
 /// <param name="messageProvider">A lazy message provider.</param>
 /// <exception cref="ArgumentNullException">If either <paramref name="typeInfo"/> or <paramref name="messageProvider"/> is <see langword="null" />.</exception>
 public LazyMessageProviderInfo(MessageProviderTypeInfo typeInfo,
                                Lazy <IGetsFailureMessage> messageProvider) : base(typeInfo)
 {
     this.messageProvider = messageProvider ?? throw new ArgumentNullException(nameof(messageProvider));
 }
Esempio n. 9
0
 /// <summary>
 /// Initialises a new instance of <see cref="MessageProviderInfo"/>.
 /// </summary>
 /// <param name="copyFrom">An instance to copy from.</param>
 /// <exception cref="ArgumentNullException">If <paramref name="copyFrom"/> is <see langword="null" />.</exception>
 protected MessageProviderInfo(MessageProviderTypeInfo copyFrom) : base(copyFrom)
 {
 }
Esempio n. 10
0
 /// <inheritdoc/>
 public IGetsFailureMessage GetNonGenericFailureMessageProvider(MessageProviderTypeInfo providerType, Type ruleInterface)
 => (IGetsFailureMessage)serviceProvider.GetService(providerType.ProviderType);
 static Func <IGetsFailureMessage> GetProviderFactory(IGetsNonGenericMessageProvider factory, MessageProviderTypeInfo typeInfo, ValidationRuleResult ruleResult)
 {
     return(() => factory.GetNonGenericFailureMessageProvider(typeInfo,
                                                              ruleResult.RuleInterface));
 }
 static MessageProviderInfo GetMessageProviderInfo(IGetsNonGenericMessageProvider factory, MessageProviderTypeInfo typeInfo, ValidationRuleResult ruleResult)
 => new LazyMessageProviderInfo(typeInfo, new Lazy <IGetsFailureMessage>(GetProviderFactory(factory, typeInfo, ruleResult)));
Esempio n. 13
0
 /// <inheritdoc/>
 public IGetsFailureMessage GetNonGenericFailureMessageProvider(MessageProviderTypeInfo providerType, Type ruleInterface)
 => ((InstanceMessageProviderInfo)providerType).MessageProvider;