diff --git a/ExpressMapper NET40/Constants.cs b/ExpressMapper NET40/Constants.cs new file mode 100644 index 0000000..e901a34 --- /dev/null +++ b/ExpressMapper NET40/Constants.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ExpressMapper +{ + public class Constants + { + } +} diff --git a/ExpressMapper NET40/ExpressMapper NET40.csproj b/ExpressMapper NET40/ExpressMapper NET40.csproj index 96347a5..5f7e08f 100644 --- a/ExpressMapper NET40/ExpressMapper NET40.csproj +++ b/ExpressMapper NET40/ExpressMapper NET40.csproj @@ -51,9 +51,12 @@ + + + diff --git a/ExpressMapper NET40/Ioc/DependencyResolver.cs b/ExpressMapper NET40/Ioc/DependencyResolver.cs new file mode 100644 index 0000000..9ca0520 --- /dev/null +++ b/ExpressMapper NET40/Ioc/DependencyResolver.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace ExpressMapper.Ioc +{ + public class DependencyResolver : IContainer + { + #region Constructors + + private DependencyResolver() + { + Initialize(); + } + + #endregion + + #region Privates + + private readonly Dictionary> _cache = new Dictionary>(); + private static IContainer _container; + + #endregion + + internal static IContainer GetContainer() + { + return _container ?? (_container = new DependencyResolver()); + } + + public T Resolve() + { + var interfHash = typeof(T).GetHashCode(); + NotImplementedCheck(interfHash, typeof(T).FullName); + MoreThanOnImplCheck(interfHash, typeof(T).FullName); + + var implInstance = (T)_cache[interfHash].First().Value.DynamicInvoke(); + return implInstance; + } + + #region Checks and throw exceptions + + private void MoreThanOnImplCheck(int interfHash, string typeFullName) + { + if (_cache[interfHash].Count > 1) + { + throw new NotImplementedException( + string.Format("There more than one implementation have been found for the {0} interface.", + typeFullName)); + } + } + + private void NotImplementedCheck(int interfHash, string typeFullName) + { + if (!_cache.ContainsKey(interfHash) || _cache[interfHash].Count == 0) + { + throw new NotImplementedException( + string.Format("No implementation has been found for the {0} interface.", typeFullName)); + } + + } + + #endregion + + public IEnumerable ResolveAll() + { + var interfHash = typeof(T).GetHashCode(); + NotImplementedCheck(interfHash, typeof(T).FullName); + var implArray = new T[_cache[interfHash].Count]; + for (var i = 0; i < _cache[interfHash].Values.Count; i++) + { + implArray[i] = (T) _cache[interfHash].Values.ElementAt(i).DynamicInvoke(); + } + return implArray; + } + + #region Initialization and compilation + private void Initialize() + { + var expressMapperAssembly = Assembly.GetExecutingAssembly(); + var expressInterfaces = expressMapperAssembly.GetTypes().Where(t => t.IsInterface); + foreach (var expressInterface in expressInterfaces) + { + var implementations = expressMapperAssembly.GetTypes().Where(t => expressInterface.IsAssignableFrom(t)); + Compile(expressInterface, implementations); + } + + } + + private void Compile(Type inter, IEnumerable implementations) + { + foreach (var impl in implementations) + { + var interHash = inter.GetHashCode(); + if (!_cache.ContainsKey(interHash)) + { + _cache[interHash] = new Dictionary(); + } + + var implHash = impl.GetHashCode(); + + if (!_cache[interHash].ContainsKey(implHash)) + { + var newExpression = Expression.New(impl); + var lambdaExpression = Expression.Lambda(newExpression); + var del = lambdaExpression.Compile(); + _cache[interHash][implHash] = del; + } + } + } + + #endregion + } +} diff --git a/ExpressMapper NET40/Ioc/IContainer.cs b/ExpressMapper NET40/Ioc/IContainer.cs new file mode 100644 index 0000000..de24adc --- /dev/null +++ b/ExpressMapper NET40/Ioc/IContainer.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +namespace ExpressMapper.Ioc +{ + public interface IContainer + { + T Resolve(); + IEnumerable ResolveAll(); + } +}