PageRenderTime 12ms CodeModel.GetById 2ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/Bifrost/Validation/CommandValidatorProvider.cs

#
C# | 156 lines | 96 code | 23 blank | 37 comment | 7 complexity | 6fcec3e2e54f4fd7289a726341bb4aaa MD5 | raw file
  1#region License
  2//
  3// Copyright (c) 2008-2012, DoLittle Studios and Komplett ASA
  4//
  5// Licensed under the Microsoft Permissive License (Ms-PL), Version 1.1 (the "License")
  6// With one exception :
  7//   Commercial libraries that is based partly or fully on Bifrost and is sold commercially, 
  8//   must obtain a commercial license.
  9//
 10// You may not use this file except in compliance with the License.
 11// You may obtain a copy of the license at 
 12//
 13//   http://bifrost.codeplex.com/license
 14//
 15// Unless required by applicable law or agreed to in writing, software
 16// distributed under the License is distributed on an "AS IS" BASIS,
 17// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 18// See the License for the specific language governing permissions and
 19// limitations under the License.
 20//
 21#endregion
 22using System;
 23using System.Collections.Generic;
 24using System.Linq;
 25using Bifrost.Commands;
 26using Bifrost.Execution;
 27using Microsoft.Practices.ServiceLocation;
 28using Bifrost.Configuration;
 29
 30namespace Bifrost.Validation
 31{
 32    /// <summary>
 33    /// Represents an instance of an <see cref="ICommandValidatorProvider">ICommandValidatorProvider.</see>
 34    /// </summary>
 35    [Singleton]
 36    public class CommandValidatorProvider : ICommandValidatorProvider
 37    {
 38        static ICommandInputValidator NullInputValidator = new NullCommandInputValidator();
 39        static ICommandBusinessValidator NullBusinessValidator = new NullCommandBusinessValidator();
 40        static Type _inputValidatorType = typeof (ICommandInputValidator);
 41        static Type _businessValidatorType = typeof (ICommandBusinessValidator);
 42        static Type _validatesType = typeof (ICanValidate<>);
 43
 44        ITypeDiscoverer _typeDiscoverer;
 45        IContainer _container;
 46        IConfigure _configuration;
 47
 48        Dictionary<Type, Type> _inputValidators;
 49        Dictionary<Type, Type> _businessValidators;
 50
 51        /// <summary>
 52        /// Initializes an instance of <see cref="CommandValidatorProvider"/> CommandValidatorProvider
 53        /// </summary>
 54        /// <param name="typeDiscoverer">
 55        /// An instance of ITypeDiscoverer to help identify and register <see cref="ICommandInputValidator"/> implementations
 56        /// and  <see cref="ICommandBusinessValidator"/> implementations
 57        /// </param>
 58        /// <param name="container">An instance of <see cref="IContainer"/> to manage instances of any <see cref="ICommandInputValidator"/></param>
 59        /// <param name="configuration">An instance of <see cref="IConfigure"/> that holds the current configuration</param>
 60        public CommandValidatorProvider(ITypeDiscoverer typeDiscoverer, IContainer container, IConfigure configuration)
 61        {
 62            _typeDiscoverer = typeDiscoverer;
 63            _container = container;
 64            _configuration = configuration;
 65
 66            Initialize();
 67        }
 68
 69#pragma warning disable 1591 // Xml Comments
 70        public ICommandInputValidator GetInputValidatorFor(ICommand command)
 71        {
 72            return GetInputValidatorFor(command.GetType());
 73        }
 74
 75        public ICommandBusinessValidator GetBusinessValidatorFor(ICommand command)
 76        {
 77            return GetBusinessValidatorFor(command.GetType());
 78        }
 79
 80        public ICommandInputValidator GetInputValidatorFor(Type type)
 81        {
 82            Type registeredType;
 83            _inputValidators.TryGetValue(type, out registeredType);
 84
 85            var inputValidator = registeredType != null ? _container.Get(registeredType) as ICommandInputValidator : NullInputValidator;
 86            return inputValidator;
 87        }
 88
 89        public ICommandBusinessValidator GetBusinessValidatorFor(Type type)
 90        {
 91            Type registeredType;
 92            _businessValidators.TryGetValue(type, out registeredType);
 93
 94            var businessValidator = registeredType != null ? _container.Get(registeredType) as ICommandBusinessValidator : NullBusinessValidator;
 95            return businessValidator;
 96        }
 97#pragma warning restore 1591 // Xml Comments
 98
 99        /// <summary>
100        /// Gets a list of registered input validator types
101        /// </summary>
102        public IEnumerable<Type> RegisteredInputValidators
103        {
104            get { return _inputValidators.Values; }
105        }
106
107        /// <summary>
108        ///  Gets a list of registered business validator types
109        /// </summary>
110        public IEnumerable<Type> RegisteredBusinessValidators
111        {
112            get { return _businessValidators.Values; }
113        }
114
115
116        void Initialize()
117        {
118            _inputValidators = new Dictionary<Type, Type>();
119            _businessValidators = new Dictionary<Type, Type>();
120
121            var inputValidators = _typeDiscoverer.FindMultiple(_inputValidatorType);
122            var businessValidators = _typeDiscoverer.FindMultiple(_businessValidatorType);
123
124            Array.ForEach(inputValidators, type => Register(type, _inputValidatorType));
125            Array.ForEach(businessValidators, type => Register(type, _businessValidatorType));
126        }
127
128        void Register(Type typeToRegister, Type registerFor)
129        {
130            var validatorRegistry = registerFor == _inputValidatorType
131                                        ? _inputValidators
132                                        : _businessValidators;
133
134            var commandType = GetCommandType(typeToRegister);
135
136            if (commandType == null || 
137                commandType.IsInterface ||
138                validatorRegistry.ContainsKey(commandType))
139                return;
140
141            validatorRegistry.Add(commandType, typeToRegister);
142            _container.Bind(typeToRegister, typeToRegister, _configuration.DefaultObjectLifecycle);
143        }
144
145        Type GetCommandType(Type typeToRegister)
146        {
147            var types = from interfaceType in typeToRegister.GetInterfaces()
148                        where interfaceType.IsGenericType
149                        let baseInterface = interfaceType.GetGenericTypeDefinition()
150                        where baseInterface == _validatesType
151                        select interfaceType.GetGenericArguments().FirstOrDefault();
152
153            return types.FirstOrDefault();
154        }
155    }
156}