diff --git a/Borepin/Borepin.iOS/Borepin.iOS.csproj b/Borepin/Borepin.iOS/Borepin.iOS.csproj
index e966ce7..65a106b 100644
--- a/Borepin/Borepin.iOS/Borepin.iOS.csproj
+++ b/Borepin/Borepin.iOS/Borepin.iOS.csproj
@@ -82,30 +82,78 @@
false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
diff --git a/Borepin/Borepin/App.xaml.cs b/Borepin/Borepin/App.xaml.cs
index 83f9ddb..cf0276d 100644
--- a/Borepin/Borepin/App.xaml.cs
+++ b/Borepin/Borepin/App.xaml.cs
@@ -1,4 +1,8 @@
-using System;
+using Borepin.Base;
+using Borepin.PageModel;
+using Borepin.Service.Navigation;
+using System;
+using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@@ -9,12 +13,17 @@ namespace Borepin
public App()
{
InitializeComponent();
-
- MainPage = new MainPage();
}
- protected override void OnStart()
+ Task InitNavigation()
{
+ var navService = PageModelLocator.Resolve();
+ return navService.NaviagteToAsync();
+ }
+
+ protected override async void OnStart()
+ {
+ await InitNavigation();
}
protected override void OnSleep()
diff --git a/Borepin/Borepin/Base/PageModelBase.cs b/Borepin/Borepin/Base/PageModelBase.cs
new file mode 100644
index 0000000..e8c160e
--- /dev/null
+++ b/Borepin/Borepin/Base/PageModelBase.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using Xamarin.Forms;
+
+namespace Borepin.Base
+{
+ public class PageModelBase : BindableObject
+ {
+ public virtual Task InitializeAsync(object naviagitionData = null)
+ {
+ return Task.CompletedTask;
+ }
+
+ protected bool SetProperty(ref T storage, T value, [CallerMemberName]string propertyName = null)
+ {
+ if(EqualityComparer.Default.Equals(storage, value))
+ {
+ return false;
+ }
+
+ storage = value;
+ OnPropertyChanged(propertyName);
+ return true;
+ }
+ }
+}
diff --git a/Borepin/Borepin/Base/PageModelLocator.cs b/Borepin/Borepin/Base/PageModelLocator.cs
new file mode 100644
index 0000000..8f2963b
--- /dev/null
+++ b/Borepin/Borepin/Base/PageModelLocator.cs
@@ -0,0 +1,49 @@
+using Borepin.Page;
+using Borepin.PageModel;
+using Borepin.Service.Navigation;
+using System;
+using System.Collections.Generic;
+using TinyIoC;
+
+namespace Borepin.Base
+{
+ public class PageModelLocator
+ {
+ private static TinyIoCContainer _Container;
+ private static Dictionary _ViewLookUp;
+
+ static PageModelLocator()
+ {
+ _Container = new TinyIoCContainer();
+ _ViewLookUp = new Dictionary();
+
+ // Register Pages and PageModels
+ Register();
+ Register();
+
+ // Register Services (Services are registered by Singeltons default)
+ _Container.Register();
+ }
+
+ public static T Resolve() where T : class
+ {
+ return _Container.Resolve();
+ }
+
+ public static Xamarin.Forms.Page CreatePage(Type pageModelType)
+ {
+ Type pageType = _ViewLookUp[pageModelType];
+ Xamarin.Forms.Page page = (Xamarin.Forms.Page)Activator.CreateInstance(pageType);
+ object pageModel = _Container.Resolve(pageModelType);
+
+ page.BindingContext = pageModel;
+ return page;
+ }
+
+ static void Register() where TPageModel : PageModelBase where TPage : Xamarin.Forms.Page
+ {
+ _ViewLookUp.Add(typeof(TPageModel), typeof(TPage));
+ _Container.Register();
+ }
+ }
+}
diff --git a/Borepin/Borepin/Base/TinyIoC.cs b/Borepin/Borepin/Base/TinyIoC.cs
new file mode 100644
index 0000000..6ccb030
--- /dev/null
+++ b/Borepin/Borepin/Base/TinyIoC.cs
@@ -0,0 +1,4341 @@
+//===============================================================================
+// TinyIoC
+//
+// An easy to use, hassle free, Inversion of Control Container for small projects
+// and beginners alike.
+//
+// https://github.com/grumpydev/TinyIoC
+//===============================================================================
+// Copyright © Steven Robbins. All rights reserved.
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE.
+//===============================================================================
+
+#region Preprocessor Directives
+// Uncomment this line if you want the container to automatically
+// register the TinyMessenger messenger/event aggregator
+//#define TINYMESSENGER
+
+// Uncomment this line if you want to internalize this library
+//#define TINYIOC_INTERNAL
+
+// Uncomment this line if you want to target PCL.
+//#define PORTABLE
+
+// Preprocessor directives for enabling/disabling functionality
+// depending on platform features. If the platform has an appropriate
+// #DEFINE then these should be set automatically below.
+#define EXPRESSIONS
+
+// Platform supports System.Linq.Expressions
+#define COMPILED_EXPRESSIONS // Platform supports compiling expressions
+#define APPDOMAIN_GETASSEMBLIES // Platform supports getting all assemblies from the AppDomain object
+#define UNBOUND_GENERICS_GETCONSTRUCTORS // Platform supports GetConstructors on unbound generic types
+#define GETPARAMETERS_OPEN_GENERICS // Platform supports GetParameters on open generics
+#define RESOLVE_OPEN_GENERICS // Platform supports resolving open generics
+#define READER_WRITER_LOCK_SLIM // Platform supports ReaderWriterLockSlim
+#define SERIALIZABLE // Platform supports SerializableAttribute/SerializationInfo/StreamingContext
+
+#if PORTABLE
+#undef APPDOMAIN_GETASSEMBLIES
+#undef COMPILED_EXPRESSIONS
+#undef READER_WRITER_LOCK_SLIM
+#undef SERIALIZABLE
+#endif
+
+#if NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2
+#undef COMPILED_EXPRESSIONS
+#undef READER_WRITER_LOCK_SLIM
+#endif
+
+#if NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2
+#undef APPDOMAIN_GETASSEMBLIES
+#endif
+
+#if NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 || NETSTANDARD1_3 || NETSTANDARD1_4 || NETSTANDARD1_5 || NETSTANDARD1_6
+#undef SERIALIZABLE
+#endif
+
+// CompactFramework / Windows Phone 7
+// By default does not support System.Linq.Expressions.
+// AppDomain object does not support enumerating all assemblies in the app domain.
+#if PocketPC || WINDOWS_PHONE
+#undef EXPRESSIONS
+#undef COMPILED_EXPRESSIONS
+#undef APPDOMAIN_GETASSEMBLIES
+#undef UNBOUND_GENERICS_GETCONSTRUCTORS
+#endif
+
+// PocketPC has a bizarre limitation on enumerating parameters on unbound generic methods.
+// We need to use a slower workaround in that case.
+#if PocketPC
+#undef GETPARAMETERS_OPEN_GENERICS
+#undef RESOLVE_OPEN_GENERICS
+#undef READER_WRITER_LOCK_SLIM
+#endif
+
+#if SILVERLIGHT
+#undef APPDOMAIN_GETASSEMBLIES
+#endif
+
+#if NETFX_CORE
+#undef APPDOMAIN_GETASSEMBLIES
+#undef RESOLVE_OPEN_GENERICS
+#endif
+
+#if COMPILED_EXPRESSIONS
+#define USE_OBJECT_CONSTRUCTOR
+#endif
+
+#endregion
+#if SERIALIZABLE
+using System.Runtime.Serialization;
+#endif
+
+namespace TinyIoC
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Linq;
+ using System.Reflection;
+
+#if EXPRESSIONS
+ using System.Linq.Expressions;
+ using System.Threading;
+
+#endif
+
+#if NETFX_CORE
+ using System.Threading.Tasks;
+ using Windows.Storage.Search;
+ using Windows.Storage;
+ using Windows.UI.Xaml.Shapes;
+#endif
+
+ #region SafeDictionary
+#if READER_WRITER_LOCK_SLIM
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ class SafeDictionary : IDisposable
+ {
+ private readonly ReaderWriterLockSlim _padlock = new ReaderWriterLockSlim();
+ private readonly Dictionary _Dictionary = new Dictionary();
+
+ public TValue this[TKey key]
+ {
+ set
+ {
+ _padlock.EnterWriteLock();
+
+ try
+ {
+ TValue current;
+ if (_Dictionary.TryGetValue(key, out current))
+ {
+ var disposable = current as IDisposable;
+
+ if (disposable != null)
+ disposable.Dispose();
+ }
+
+ _Dictionary[key] = value;
+ }
+ finally
+ {
+ _padlock.ExitWriteLock();
+ }
+ }
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ _padlock.EnterReadLock();
+ try
+ {
+ return _Dictionary.TryGetValue(key, out value);
+ }
+ finally
+ {
+ _padlock.ExitReadLock();
+ }
+ }
+
+ public bool Remove(TKey key)
+ {
+ _padlock.EnterWriteLock();
+ try
+ {
+ return _Dictionary.Remove(key);
+ }
+ finally
+ {
+ _padlock.ExitWriteLock();
+ }
+ }
+
+ public void Clear()
+ {
+ _padlock.EnterWriteLock();
+ try
+ {
+ _Dictionary.Clear();
+ }
+ finally
+ {
+ _padlock.ExitWriteLock();
+ }
+ }
+
+ public IEnumerable Keys
+ {
+ get
+ {
+ _padlock.EnterReadLock();
+ try
+ {
+ return new List(_Dictionary.Keys);
+ }
+ finally
+ {
+ _padlock.ExitReadLock();
+ }
+ }
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ _padlock.EnterWriteLock();
+
+ try
+ {
+ var disposableItems = from item in _Dictionary.Values
+ where item is IDisposable
+ select item as IDisposable;
+
+ foreach (var item in disposableItems)
+ {
+ item.Dispose();
+ }
+ }
+ finally
+ {
+ _padlock.ExitWriteLock();
+ }
+
+ GC.SuppressFinalize(this);
+ }
+
+ #endregion
+ }
+#else
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ class SafeDictionary : IDisposable
+ {
+ private readonly object _Padlock = new object();
+ private readonly Dictionary _Dictionary = new Dictionary();
+
+ public TValue this[TKey key]
+ {
+ set
+ {
+ lock (_Padlock)
+ {
+ TValue current;
+ if (_Dictionary.TryGetValue(key, out current))
+ {
+ var disposable = current as IDisposable;
+
+ if (disposable != null)
+ disposable.Dispose();
+ }
+
+ _Dictionary[key] = value;
+ }
+ }
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ lock (_Padlock)
+ {
+ return _Dictionary.TryGetValue(key, out value);
+ }
+ }
+
+ public bool Remove(TKey key)
+ {
+ lock (_Padlock)
+ {
+ return _Dictionary.Remove(key);
+ }
+ }
+
+ public void Clear()
+ {
+ lock (_Padlock)
+ {
+ _Dictionary.Clear();
+ }
+ }
+
+ public IEnumerable Keys
+ {
+ get
+ {
+ return _Dictionary.Keys;
+ }
+ }
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ lock (_Padlock)
+ {
+ var disposableItems = from item in _Dictionary.Values
+ where item is IDisposable
+ select item as IDisposable;
+
+ foreach (var item in disposableItems)
+ {
+ item.Dispose();
+ }
+ }
+
+ GC.SuppressFinalize(this);
+ }
+
+ #endregion
+ }
+#endif
+ #endregion
+
+ #region Extensions
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ static class AssemblyExtensions
+ {
+ public static Type[] SafeGetTypes(this Assembly assembly)
+ {
+ Type[] assemblies;
+
+ try
+ {
+#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2
+ assemblies = assembly.ExportedTypes.ToArray();
+#else
+ assemblies = assembly.GetTypes();
+#endif
+ }
+ catch (System.IO.FileNotFoundException)
+ {
+ assemblies = new Type[] { };
+ }
+ catch (NotSupportedException)
+ {
+ assemblies = new Type[] { };
+ }
+#if !NETFX_CORE
+ catch (ReflectionTypeLoadException e)
+ {
+ assemblies = e.Types.Where(t => t != null).ToArray();
+ }
+#endif
+ return assemblies;
+ }
+ }
+
+#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2
+ [Flags]
+ public enum BindingFlags {
+ Default = 0,
+ IgnoreCase = 1,
+ DeclaredOnly = 2,
+ Instance = 4,
+ Static = 8,
+ Public = 16,
+ NonPublic = 32,
+ FlattenHierarchy = 64,
+ InvokeMethod = 256,
+ CreateInstance = 512,
+ GetField = 1024,
+ SetField = 2048,
+ GetProperty = 4096,
+ SetProperty = 8192,
+ PutDispProperty = 16384,
+ ExactBinding = 65536,
+ PutRefDispProperty = 32768,
+ SuppressChangeType = 131072,
+ OptionalParamBinding = 262144,
+ IgnoreReturn = 16777216
+ }
+#endif
+
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ static class TypeExtensions
+ {
+ private static SafeDictionary _genericMethodCache;
+
+ static TypeExtensions()
+ {
+ _genericMethodCache = new SafeDictionary();
+ }
+
+#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2
+ private static BindingFlags DefaultFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
+
+ public static ConstructorInfo[] GetConstructors(this Type type)
+ {
+ return type.GetConstructors(DefaultFlags);
+ }
+
+ public static ConstructorInfo[] GetConstructors(this Type type, BindingFlags bindingFlags)
+ {
+ return type.GetConstructors(bindingFlags, null);
+ }
+
+ private static ConstructorInfo[] GetConstructors(this Type type, BindingFlags bindingFlags, IList parameterTypes)
+ {
+ return type.GetTypeInfo().DeclaredConstructors.Where(
+ c =>
+ {
+ if (!TestAccessibility(c, bindingFlags))
+ {
+ return false;
+ }
+
+ if (parameterTypes != null && !c.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes))
+ {
+ return false;
+ }
+
+ return true;
+ }).ToArray();
+ }
+
+ public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) {
+ return propertyInfo.GetGetMethod(false);
+ }
+
+ public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo, bool nonPublic) {
+ MethodInfo getMethod = propertyInfo.GetMethod;
+ if (getMethod != null && (getMethod.IsPublic || nonPublic)) {
+ return getMethod;
+ }
+
+ return null;
+ }
+
+ public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) {
+ return propertyInfo.GetSetMethod(false);
+ }
+
+ public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo, bool nonPublic) {
+ MethodInfo setMethod = propertyInfo.SetMethod;
+ if (setMethod != null && (setMethod.IsPublic || nonPublic)) {
+ return setMethod;
+ }
+
+ return null;
+ }
+
+ public static Type[] GetGenericArguments(this Type type)
+ {
+ return type.GetTypeInfo().GenericTypeArguments;
+ }
+
+ public static IEnumerable GetProperties(this Type type)
+ {
+ TypeInfo t = type.GetTypeInfo();
+ IList properties = new List();
+ while (t != null)
+ {
+ foreach (PropertyInfo member in t.DeclaredProperties)
+ {
+ if (!properties.Any(p => p.Name == member.Name))
+ {
+ properties.Add(member);
+ }
+ }
+ t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null;
+ }
+
+ return properties;
+ }
+
+ public static IEnumerable GetInterfaces(this Type type)
+ {
+ return type.GetTypeInfo().ImplementedInterfaces;
+ }
+
+ public static MethodInfo GetMethod(this Type type, string name, IList parameterTypes)
+ {
+ return type.GetMethod(name, DefaultFlags, null, parameterTypes, null);
+ }
+
+ public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingFlags, object placeHolder1, IList parameterTypes, object placeHolder2)
+ {
+ return type.GetTypeInfo().DeclaredMethods.Where(
+ m =>
+ {
+ if (name != null && m.Name != name)
+ {
+ return false;
+ }
+
+ if (!TestAccessibility(m, bindingFlags))
+ {
+ return false;
+ }
+
+ return m.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes);
+ }).SingleOrDefault();
+ }
+
+ public static IEnumerable GetMethods(this Type type, BindingFlags bindingFlags)
+ {
+ return type.GetTypeInfo().DeclaredMethods;
+ }
+
+ public static bool IsAssignableFrom(this Type type, Type c)
+ {
+ return type.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo());
+ }
+
+ private static bool TestAccessibility(MethodBase member, BindingFlags bindingFlags)
+ {
+ bool visibility = (member.IsPublic && bindingFlags.HasFlag(BindingFlags.Public)) ||
+ (!member.IsPublic && bindingFlags.HasFlag(BindingFlags.NonPublic));
+
+ bool instance = (member.IsStatic && bindingFlags.HasFlag(BindingFlags.Static)) ||
+ (!member.IsStatic && bindingFlags.HasFlag(BindingFlags.Instance));
+
+ return visibility && instance;
+ }
+#endif
+
+ ///
+ /// Gets a generic method from a type given the method name, binding flags, generic types and parameter types
+ ///
+ /// Source type
+ /// Binding flags
+ /// Name of the method
+ /// Generic types to use to make the method generic
+ /// Method parameters
+ /// MethodInfo or null if no matches found
+ ///
+ ///
+ public static MethodInfo GetGenericMethod(this Type sourceType, BindingFlags bindingFlags, string methodName, Type[] genericTypes, Type[] parameterTypes)
+ {
+ MethodInfo method;
+ var cacheKey = new GenericMethodCacheKey(sourceType, methodName, genericTypes, parameterTypes);
+
+ // Shouldn't need any additional locking
+ // we don't care if we do the method info generation
+ // more than once before it gets cached.
+ if (!_genericMethodCache.TryGetValue(cacheKey, out method))
+ {
+ method = GetMethod(sourceType, bindingFlags, methodName, genericTypes, parameterTypes);
+ _genericMethodCache[cacheKey] = method;
+ }
+
+ return method;
+ }
+ //#endif
+
+#if NETFX_CORE
+ private static MethodInfo GetMethod(Type sourceType, BindingFlags flags, string methodName, Type[] genericTypes, Type[] parameterTypes)
+ {
+ var methods =
+ sourceType.GetMethods(flags).Where(
+ mi => string.Equals(methodName, mi.Name, StringComparison.Ordinal)).Where(
+ mi => mi.ContainsGenericParameters).Where(mi => mi.GetGenericArguments().Length == genericTypes.Length).
+ Where(mi => mi.GetParameters().Length == parameterTypes.Length).Select(
+ mi => mi.MakeGenericMethod(genericTypes)).Where(
+ mi => mi.GetParameters().Select(pi => pi.ParameterType).SequenceEqual(parameterTypes)).ToList();
+
+ if (methods.Count > 1)
+ {
+ throw new AmbiguousMatchException();
+ }
+
+ return methods.FirstOrDefault();
+ }
+#else
+ private static MethodInfo GetMethod(Type sourceType, BindingFlags bindingFlags, string methodName, Type[] genericTypes, Type[] parameterTypes)
+ {
+#if GETPARAMETERS_OPEN_GENERICS
+ var methods =
+ sourceType.GetMethods(bindingFlags).Where(
+ mi => string.Equals(methodName, mi.Name, StringComparison.Ordinal)).Where(
+ mi => mi.ContainsGenericParameters).Where(mi => mi.GetGenericArguments().Length == genericTypes.Length).
+ Where(mi => mi.GetParameters().Length == parameterTypes.Length).Select(
+ mi => mi.MakeGenericMethod(genericTypes)).Where(
+ mi => mi.GetParameters().Select(pi => pi.ParameterType).SequenceEqual(parameterTypes)).ToList();
+#else
+ var validMethods = from method in sourceType.GetMethods(bindingFlags)
+ where method.Name == methodName
+ where method.IsGenericMethod
+ where method.GetGenericArguments().Length == genericTypes.Length
+ let genericMethod = method.MakeGenericMethod(genericTypes)
+ where genericMethod.GetParameters().Count() == parameterTypes.Length
+ where genericMethod.GetParameters().Select(pi => pi.ParameterType).SequenceEqual(parameterTypes)
+ select genericMethod;
+
+ var methods = validMethods.ToList();
+#endif
+ if (methods.Count > 1)
+ {
+ throw new AmbiguousMatchException();
+ }
+
+ return methods.FirstOrDefault();
+ }
+#endif
+
+ private sealed class GenericMethodCacheKey
+ {
+ private readonly Type _sourceType;
+
+ private readonly string _methodName;
+
+ private readonly Type[] _genericTypes;
+
+ private readonly Type[] _parameterTypes;
+
+ private readonly int _hashCode;
+
+ public GenericMethodCacheKey(Type sourceType, string methodName, Type[] genericTypes, Type[] parameterTypes)
+ {
+ _sourceType = sourceType;
+ _methodName = methodName;
+ _genericTypes = genericTypes;
+ _parameterTypes = parameterTypes;
+ _hashCode = GenerateHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ var cacheKey = obj as GenericMethodCacheKey;
+ if (cacheKey == null)
+ return false;
+
+ if (_sourceType != cacheKey._sourceType)
+ return false;
+
+ if (!String.Equals(_methodName, cacheKey._methodName, StringComparison.Ordinal))
+ return false;
+
+ if (_genericTypes.Length != cacheKey._genericTypes.Length)
+ return false;
+
+ if (_parameterTypes.Length != cacheKey._parameterTypes.Length)
+ return false;
+
+ for (int i = 0; i < _genericTypes.Length; ++i)
+ {
+ if (_genericTypes[i] != cacheKey._genericTypes[i])
+ return false;
+ }
+
+ for (int i = 0; i < _parameterTypes.Length; ++i)
+ {
+ if (_parameterTypes[i] != cacheKey._parameterTypes[i])
+ return false;
+ }
+
+ return true;
+ }
+
+ public override int GetHashCode()
+ {
+ return _hashCode;
+ }
+
+ private int GenerateHashCode()
+ {
+ unchecked
+ {
+ var result = _sourceType.GetHashCode();
+
+ result = (result * 397) ^ _methodName.GetHashCode();
+
+ for (int i = 0; i < _genericTypes.Length; ++i)
+ {
+ result = (result * 397) ^ _genericTypes[i].GetHashCode();
+ }
+
+ for (int i = 0; i < _parameterTypes.Length; ++i)
+ {
+ result = (result * 397) ^ _parameterTypes[i].GetHashCode();
+ }
+
+ return result;
+ }
+ }
+ }
+
+ }
+
+ // @mbrit - 2012-05-22 - shim for ForEach call on List...
+#if NETFX_CORE
+ internal static class ListExtender
+ {
+ internal static void ForEach(this List list, Action callback)
+ {
+ foreach (T obj in list)
+ callback(obj);
+ }
+ }
+#endif
+
+ #endregion
+
+ #region TinyIoC Exception Types
+#if SERIALIZABLE
+ [Serializable]
+#endif
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ class TinyIoCResolutionException : Exception
+ {
+ private const string ERROR_TEXT = "Unable to resolve type: {0}";
+
+ public TinyIoCResolutionException(Type type)
+ : base(String.Format(ERROR_TEXT, type.FullName))
+ {
+ }
+
+ public TinyIoCResolutionException(Type type, Exception innerException)
+ : base(String.Format(ERROR_TEXT, type.FullName), innerException)
+ {
+ }
+#if SERIALIZABLE
+ protected TinyIoCResolutionException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+ }
+#if SERIALIZABLE
+ [Serializable]
+#endif
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ class TinyIoCRegistrationTypeException : Exception
+ {
+ private const string REGISTER_ERROR_TEXT = "Cannot register type {0} - abstract classes or interfaces are not valid implementation types for {1}.";
+
+ public TinyIoCRegistrationTypeException(Type type, string factory)
+ : base(String.Format(REGISTER_ERROR_TEXT, type.FullName, factory))
+ {
+ }
+
+ public TinyIoCRegistrationTypeException(Type type, string factory, Exception innerException)
+ : base(String.Format(REGISTER_ERROR_TEXT, type.FullName, factory), innerException)
+ {
+ }
+#if SERIALIZABLE
+ protected TinyIoCRegistrationTypeException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+ }
+#if SERIALIZABLE
+ [Serializable]
+#endif
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ class TinyIoCRegistrationException : Exception
+ {
+ private const string CONVERT_ERROR_TEXT = "Cannot convert current registration of {0} to {1}";
+ private const string GENERIC_CONSTRAINT_ERROR_TEXT = "Type {1} is not valid for a registration of type {0}";
+
+ public TinyIoCRegistrationException(Type type, string method)
+ : base(String.Format(CONVERT_ERROR_TEXT, type.FullName, method))
+ {
+ }
+
+ public TinyIoCRegistrationException(Type type, string method, Exception innerException)
+ : base(String.Format(CONVERT_ERROR_TEXT, type.FullName, method), innerException)
+ {
+ }
+
+ public TinyIoCRegistrationException(Type registerType, Type implementationType)
+ : base(String.Format(GENERIC_CONSTRAINT_ERROR_TEXT, registerType.FullName, implementationType.FullName))
+ {
+ }
+
+ public TinyIoCRegistrationException(Type registerType, Type implementationType, Exception innerException)
+ : base(String.Format(GENERIC_CONSTRAINT_ERROR_TEXT, registerType.FullName, implementationType.FullName), innerException)
+ {
+ }
+#if SERIALIZABLE
+ protected TinyIoCRegistrationException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+ }
+#if SERIALIZABLE
+ [Serializable]
+#endif
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ class TinyIoCWeakReferenceException : Exception
+ {
+ private const string ERROR_TEXT = "Unable to instantiate {0} - referenced object has been reclaimed";
+
+ public TinyIoCWeakReferenceException(Type type)
+ : base(String.Format(ERROR_TEXT, type.FullName))
+ {
+ }
+
+ public TinyIoCWeakReferenceException(Type type, Exception innerException)
+ : base(String.Format(ERROR_TEXT, type.FullName), innerException)
+ {
+ }
+#if SERIALIZABLE
+ protected TinyIoCWeakReferenceException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+ }
+#if SERIALIZABLE
+ [Serializable]
+#endif
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ class TinyIoCConstructorResolutionException : Exception
+ {
+ private const string ERROR_TEXT = "Unable to resolve constructor for {0} using provided Expression.";
+
+ public TinyIoCConstructorResolutionException(Type type)
+ : base(String.Format(ERROR_TEXT, type.FullName))
+ {
+ }
+
+ public TinyIoCConstructorResolutionException(Type type, Exception innerException)
+ : base(String.Format(ERROR_TEXT, type.FullName), innerException)
+ {
+ }
+
+ public TinyIoCConstructorResolutionException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ public TinyIoCConstructorResolutionException(string message)
+ : base(message)
+ {
+ }
+#if SERIALIZABLE
+ protected TinyIoCConstructorResolutionException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+ }
+#if SERIALIZABLE
+ [Serializable]
+#endif
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ class TinyIoCAutoRegistrationException : Exception
+ {
+ private const string ERROR_TEXT = "Duplicate implementation of type {0} found ({1}).";
+
+ public TinyIoCAutoRegistrationException(Type registerType, IEnumerable types)
+ : base(String.Format(ERROR_TEXT, registerType, GetTypesString(types)))
+ {
+ }
+
+ public TinyIoCAutoRegistrationException(Type registerType, IEnumerable types, Exception innerException)
+ : base(String.Format(ERROR_TEXT, registerType, GetTypesString(types)), innerException)
+ {
+ }
+#if SERIALIZABLE
+ protected TinyIoCAutoRegistrationException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+
+ private static string GetTypesString(IEnumerable types)
+ {
+ var typeNames = from type in types
+ select type.FullName;
+
+ return string.Join(",", typeNames.ToArray());
+ }
+ }
+ #endregion
+
+ #region Public Setup / Settings Classes
+ ///
+ /// Name/Value pairs for specifying "user" parameters when resolving
+ ///
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ sealed class NamedParameterOverloads : Dictionary
+ {
+ public static NamedParameterOverloads FromIDictionary(IDictionary data)
+ {
+ return data as NamedParameterOverloads ?? new NamedParameterOverloads(data);
+ }
+
+ public NamedParameterOverloads()
+ {
+ }
+
+ public NamedParameterOverloads(IDictionary data)
+ : base(data)
+ {
+ }
+
+ private static readonly NamedParameterOverloads _Default = new NamedParameterOverloads();
+
+ public static NamedParameterOverloads Default
+ {
+ get
+ {
+ return _Default;
+ }
+ }
+ }
+
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ enum UnregisteredResolutionActions
+ {
+ ///
+ /// Attempt to resolve type, even if the type isn't registered.
+ ///
+ /// Registered types/options will always take precedence.
+ ///
+ AttemptResolve,
+
+ ///
+ /// Fail resolution if type not explicitly registered
+ ///
+ Fail,
+
+ ///
+ /// Attempt to resolve unregistered type if requested type is generic
+ /// and no registration exists for the specific generic parameters used.
+ ///
+ /// Registered types/options will always take precedence.
+ ///
+ GenericsOnly
+ }
+
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ enum NamedResolutionFailureActions
+ {
+ AttemptUnnamedResolution,
+ Fail
+ }
+
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ enum DuplicateImplementationActions
+ {
+ RegisterSingle,
+ RegisterMultiple,
+ Fail
+ }
+
+ ///
+ /// Resolution settings
+ ///
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ sealed class ResolveOptions
+ {
+ private static readonly ResolveOptions _Default = new ResolveOptions();
+ private static readonly ResolveOptions _FailUnregisteredAndNameNotFound = new ResolveOptions() { NamedResolutionFailureAction = NamedResolutionFailureActions.Fail, UnregisteredResolutionAction = UnregisteredResolutionActions.Fail };
+ private static readonly ResolveOptions _FailUnregisteredOnly = new ResolveOptions() { NamedResolutionFailureAction = NamedResolutionFailureActions.AttemptUnnamedResolution, UnregisteredResolutionAction = UnregisteredResolutionActions.Fail };
+ private static readonly ResolveOptions _FailNameNotFoundOnly = new ResolveOptions() { NamedResolutionFailureAction = NamedResolutionFailureActions.Fail, UnregisteredResolutionAction = UnregisteredResolutionActions.AttemptResolve };
+
+ private UnregisteredResolutionActions _UnregisteredResolutionAction = UnregisteredResolutionActions.AttemptResolve;
+ public UnregisteredResolutionActions UnregisteredResolutionAction
+ {
+ get { return _UnregisteredResolutionAction; }
+ set { _UnregisteredResolutionAction = value; }
+ }
+
+ private NamedResolutionFailureActions _NamedResolutionFailureAction = NamedResolutionFailureActions.Fail;
+ public NamedResolutionFailureActions NamedResolutionFailureAction
+ {
+ get { return _NamedResolutionFailureAction; }
+ set { _NamedResolutionFailureAction = value; }
+ }
+
+ ///
+ /// Gets the default options (attempt resolution of unregistered types, fail on named resolution if name not found)
+ ///
+ public static ResolveOptions Default
+ {
+ get
+ {
+ return _Default;
+ }
+ }
+
+ ///
+ /// Preconfigured option for attempting resolution of unregistered types and failing on named resolution if name not found
+ ///
+ public static ResolveOptions FailNameNotFoundOnly
+ {
+ get
+ {
+ return _FailNameNotFoundOnly;
+ }
+ }
+
+ ///
+ /// Preconfigured option for failing on resolving unregistered types and on named resolution if name not found
+ ///
+ public static ResolveOptions FailUnregisteredAndNameNotFound
+ {
+ get
+ {
+ return _FailUnregisteredAndNameNotFound;
+ }
+ }
+
+ ///
+ /// Preconfigured option for failing on resolving unregistered types, but attempting unnamed resolution if name not found
+ ///
+ public static ResolveOptions FailUnregisteredOnly
+ {
+ get
+ {
+ return _FailUnregisteredOnly;
+ }
+ }
+ }
+ #endregion
+
+#if TINYIOC_INTERNAL
+ internal
+#else
+ public
+#endif
+ sealed partial class TinyIoCContainer : IDisposable
+ {
+ #region Fake NETFX_CORE Classes
+#if NETFX_CORE
+ private sealed class MethodAccessException : Exception
+ {
+ }
+
+ private sealed class AppDomain
+ {
+ public static AppDomain CurrentDomain { get; private set; }
+
+ static AppDomain()
+ {
+ CurrentDomain = new AppDomain();
+ }
+
+ // @mbrit - 2012-05-30 - in WinRT, this should be done async...
+ public async Task> GetAssembliesAsync()
+ {
+ var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
+
+ List assemblies = new List();
+
+ var files = await folder.GetFilesAsync();
+
+ foreach (StorageFile file in files)
+ {
+ if (file.FileType == ".dll" || file.FileType == ".exe")
+ {
+ AssemblyName name = new AssemblyName() { Name = System.IO.Path.GetFileNameWithoutExtension(file.Name) };
+ try
+ {
+ var asm = Assembly.Load(name);
+ assemblies.Add(asm);
+ }
+ catch
+ {
+ // ignore exceptions here...
+ }
+ }
+ }
+
+ return assemblies;
+ }
+ }
+#endif
+ #endregion
+
+ #region "Fluent" API
+ ///
+ /// Registration options for "fluent" API
+ ///
+ public sealed class RegisterOptions
+ {
+ private TinyIoCContainer _Container;
+ private TypeRegistration _Registration;
+
+ public RegisterOptions(TinyIoCContainer container, TypeRegistration registration)
+ {
+ _Container = container;
+ _Registration = registration;
+ }
+
+ ///
+ /// Make registration a singleton (single instance) if possible
+ ///
+ /// RegisterOptions
+ ///
+ public RegisterOptions AsSingleton()
+ {
+ var currentFactory = _Container.GetCurrentFactory(_Registration);
+
+ if (currentFactory == null)
+ throw new TinyIoCRegistrationException(_Registration.Type, "singleton");
+
+ return _Container.AddUpdateRegistration(_Registration, currentFactory.SingletonVariant);
+ }
+
+ ///
+ /// Make registration multi-instance if possible
+ ///
+ /// RegisterOptions
+ ///
+ public RegisterOptions AsMultiInstance()
+ {
+ var currentFactory = _Container.GetCurrentFactory(_Registration);
+
+ if (currentFactory == null)
+ throw new TinyIoCRegistrationException(_Registration.Type, "multi-instance");
+
+ return _Container.AddUpdateRegistration(_Registration, currentFactory.MultiInstanceVariant);
+ }
+
+ ///
+ /// Make registration hold a weak reference if possible
+ ///
+ /// RegisterOptions
+ ///
+ public RegisterOptions WithWeakReference()
+ {
+ var currentFactory = _Container.GetCurrentFactory(_Registration);
+
+ if (currentFactory == null)
+ throw new TinyIoCRegistrationException(_Registration.Type, "weak reference");
+
+ return _Container.AddUpdateRegistration(_Registration, currentFactory.WeakReferenceVariant);
+ }
+
+ ///
+ /// Make registration hold a strong reference if possible
+ ///
+ /// RegisterOptions
+ ///
+ public RegisterOptions WithStrongReference()
+ {
+ var currentFactory = _Container.GetCurrentFactory(_Registration);
+
+ if (currentFactory == null)
+ throw new TinyIoCRegistrationException(_Registration.Type, "strong reference");
+
+ return _Container.AddUpdateRegistration(_Registration, currentFactory.StrongReferenceVariant);
+ }
+
+#if EXPRESSIONS
+ public RegisterOptions UsingConstructor(Expression> constructor)
+ {
+ if (!IsValidAssignment(_Registration.Type, typeof(RegisterType)))
+ throw new TinyIoCConstructorResolutionException(typeof(RegisterType));
+
+ var lambda = constructor as LambdaExpression;
+ if (lambda == null)
+ throw new TinyIoCConstructorResolutionException(typeof(RegisterType));
+
+ var newExpression = lambda.Body as NewExpression;
+ if (newExpression == null)
+ throw new TinyIoCConstructorResolutionException(typeof(RegisterType));
+
+ var constructorInfo = newExpression.Constructor;
+ if (constructorInfo == null)
+ throw new TinyIoCConstructorResolutionException(typeof(RegisterType));
+
+ var currentFactory = _Container.GetCurrentFactory(_Registration);
+ if (currentFactory == null)
+ throw new TinyIoCConstructorResolutionException(typeof(RegisterType));
+
+ currentFactory.SetConstructor(constructorInfo);
+
+ return this;
+ }
+#endif
+ ///
+ /// Switches to a custom lifetime manager factory if possible.
+ ///
+ /// Usually used for RegisterOptions "To*" extension methods such as the ASP.Net per-request one.
+ ///
+ /// RegisterOptions instance
+ /// Custom lifetime manager
+ /// Error string to display if switch fails
+ /// RegisterOptions
+ public static RegisterOptions ToCustomLifetimeManager(RegisterOptions instance, ITinyIoCObjectLifetimeProvider lifetimeProvider, string errorString)
+ {
+ if (instance == null)
+ throw new ArgumentNullException("instance", "instance is null.");
+
+ if (lifetimeProvider == null)
+ throw new ArgumentNullException("lifetimeProvider", "lifetimeProvider is null.");
+
+ if (string.IsNullOrEmpty(errorString))
+ throw new ArgumentException("errorString is null or empty.", "errorString");
+
+ var currentFactory = instance._Container.GetCurrentFactory(instance._Registration);
+
+ if (currentFactory == null)
+ throw new TinyIoCRegistrationException(instance._Registration.Type, errorString);
+
+ return instance._Container.AddUpdateRegistration(instance._Registration, currentFactory.GetCustomObjectLifetimeVariant(lifetimeProvider, errorString));
+ }
+ }
+
+ ///
+ /// Registration options for "fluent" API when registering multiple implementations
+ ///
+ public sealed class MultiRegisterOptions
+ {
+ private IEnumerable _RegisterOptions;
+
+ ///
+ /// Initializes a new instance of the MultiRegisterOptions class.
+ ///
+ /// Registration options
+ public MultiRegisterOptions(IEnumerable registerOptions)
+ {
+ _RegisterOptions = registerOptions;
+ }
+
+ ///
+ /// Make registration a singleton (single instance) if possible
+ ///
+ /// RegisterOptions
+ ///
+ public MultiRegisterOptions AsSingleton()
+ {
+ _RegisterOptions = ExecuteOnAllRegisterOptions(ro => ro.AsSingleton());
+ return this;
+ }
+
+ ///
+ /// Make registration multi-instance if possible
+ ///
+ /// MultiRegisterOptions
+ ///
+ public MultiRegisterOptions AsMultiInstance()
+ {
+ _RegisterOptions = ExecuteOnAllRegisterOptions(ro => ro.AsMultiInstance());
+ return this;
+ }
+
+ ///
+ /// Switches to a custom lifetime manager factory if possible.
+ ///
+ /// Usually used for RegisterOptions "To*" extension methods such as the ASP.Net per-request one.
+ ///
+ /// MultiRegisterOptions instance
+ /// Custom lifetime manager
+ /// Error string to display if switch fails
+ /// MultiRegisterOptions
+ public static MultiRegisterOptions ToCustomLifetimeManager(
+ MultiRegisterOptions instance,
+ ITinyIoCObjectLifetimeProvider lifetimeProvider,
+ string errorString)
+ {
+ if (instance == null)
+ throw new ArgumentNullException("instance", "instance is null.");
+
+ if (lifetimeProvider == null)
+ throw new ArgumentNullException("lifetimeProvider", "lifetimeProvider is null.");
+
+ if (string.IsNullOrEmpty(errorString))
+ throw new ArgumentException("errorString is null or empty.", "errorString");
+
+ instance._RegisterOptions = instance.ExecuteOnAllRegisterOptions(ro => RegisterOptions.ToCustomLifetimeManager(ro, lifetimeProvider, errorString));
+
+ return instance;
+ }
+
+ private IEnumerable ExecuteOnAllRegisterOptions(Func action)
+ {
+ var newRegisterOptions = new List();
+
+ foreach (var registerOption in _RegisterOptions)
+ {
+ newRegisterOptions.Add(action(registerOption));
+ }
+
+ return newRegisterOptions;
+ }
+ }
+ #endregion
+
+ #region Public API
+ #region Child Containers
+ public TinyIoCContainer GetChildContainer()
+ {
+ return new TinyIoCContainer(this);
+ }
+ #endregion
+
+ #region Registration
+ ///
+ /// Attempt to automatically register all non-generic classes and interfaces in the current app domain.
+ ///
+ /// If more than one class implements an interface then only one implementation will be registered
+ /// although no error will be thrown.
+ ///
+ public void AutoRegister()
+ {
+#if APPDOMAIN_GETASSEMBLIES
+ AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), DuplicateImplementationActions.RegisterSingle, null);
+#else
+ AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, DuplicateImplementationActions.RegisterSingle, null);
+#endif
+ }
+
+ ///
+ /// Attempt to automatically register all non-generic classes and interfaces in the current app domain.
+ /// Types will only be registered if they pass the supplied registration predicate.
+ ///
+ /// If more than one class implements an interface then only one implementation will be registered
+ /// although no error will be thrown.
+ ///
+ /// Predicate to determine if a particular type should be registered
+ public void AutoRegister(Func registrationPredicate)
+ {
+#if APPDOMAIN_GETASSEMBLIES
+ AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), DuplicateImplementationActions.RegisterSingle, registrationPredicate);
+#else
+ AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, DuplicateImplementationActions.RegisterSingle, registrationPredicate);
+#endif
+ }
+
+ ///
+ /// Attempt to automatically register all non-generic classes and interfaces in the current app domain.
+ ///
+ /// What action to take when encountering duplicate implementations of an interface/base class.
+ ///
+ public void AutoRegister(DuplicateImplementationActions duplicateAction)
+ {
+#if APPDOMAIN_GETASSEMBLIES
+ AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), duplicateAction, null);
+#else
+ AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, duplicateAction, null);
+#endif
+ }
+
+ ///
+ /// Attempt to automatically register all non-generic classes and interfaces in the current app domain.
+ /// Types will only be registered if they pass the supplied registration predicate.
+ ///
+ /// What action to take when encountering duplicate implementations of an interface/base class.
+ /// Predicate to determine if a particular type should be registered
+ ///
+ public void AutoRegister(DuplicateImplementationActions duplicateAction, Func registrationPredicate)
+ {
+#if APPDOMAIN_GETASSEMBLIES
+ AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), duplicateAction, registrationPredicate);
+#else
+ AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, duplicateAction, registrationPredicate);
+#endif
+ }
+
+ ///
+ /// Attempt to automatically register all non-generic classes and interfaces in the specified assemblies
+ ///
+ /// If more than one class implements an interface then only one implementation will be registered
+ /// although no error will be thrown.
+ ///
+ /// Assemblies to process
+ public void AutoRegister(IEnumerable assemblies)
+ {
+ AutoRegisterInternal(assemblies, DuplicateImplementationActions.RegisterSingle, null);
+ }
+
+ ///
+ /// Attempt to automatically register all non-generic classes and interfaces in the specified assemblies
+ /// Types will only be registered if they pass the supplied registration predicate.
+ ///
+ /// If more than one class implements an interface then only one implementation will be registered
+ /// although no error will be thrown.
+ ///
+ /// Assemblies to process
+ /// Predicate to determine if a particular type should be registered
+ public void AutoRegister(IEnumerable assemblies, Func registrationPredicate)
+ {
+ AutoRegisterInternal(assemblies, DuplicateImplementationActions.RegisterSingle, registrationPredicate);
+ }
+
+ ///
+ /// Attempt to automatically register all non-generic classes and interfaces in the specified assemblies
+ ///
+ /// Assemblies to process
+ /// What action to take when encountering duplicate implementations of an interface/base class.
+ ///
+ public void AutoRegister(IEnumerable assemblies, DuplicateImplementationActions duplicateAction)
+ {
+ AutoRegisterInternal(assemblies, duplicateAction, null);
+ }
+
+ ///
+ /// Attempt to automatically register all non-generic classes and interfaces in the specified assemblies
+ /// Types will only be registered if they pass the supplied registration predicate.
+ ///
+ /// Assemblies to process
+ /// What action to take when encountering duplicate implementations of an interface/base class.
+ /// Predicate to determine if a particular type should be registered
+ ///
+ public void AutoRegister(IEnumerable assemblies, DuplicateImplementationActions duplicateAction, Func registrationPredicate)
+ {
+ AutoRegisterInternal(assemblies, duplicateAction, registrationPredicate);
+ }
+
+ ///
+ /// Creates/replaces a container class registration with default options.
+ ///
+ /// Type to register
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType)
+ {
+ return RegisterInternal(registerType, string.Empty, GetDefaultObjectFactory(registerType, registerType));
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with default options.
+ ///
+ /// Type to register
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, string name)
+ {
+ return RegisterInternal(registerType, name, GetDefaultObjectFactory(registerType, registerType));
+
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a given implementation and default options.
+ ///
+ /// Type to register
+ /// Type to instantiate that implements RegisterType
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, Type registerImplementation)
+ {
+ return this.RegisterInternal(registerType, string.Empty, GetDefaultObjectFactory(registerType, registerImplementation));
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with a given implementation and default options.
+ ///
+ /// Type to register
+ /// Type to instantiate that implements RegisterType
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, Type registerImplementation, string name)
+ {
+ return this.RegisterInternal(registerType, name, GetDefaultObjectFactory(registerType, registerImplementation));
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a specific, strong referenced, instance.
+ ///
+ /// Type to register
+ /// Instance of RegisterType to register
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, object instance)
+ {
+ return RegisterInternal(registerType, string.Empty, new InstanceFactory(registerType, registerType, instance));
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with a specific, strong referenced, instance.
+ ///
+ /// Type to register
+ /// Instance of RegisterType to register
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, object instance, string name)
+ {
+ return RegisterInternal(registerType, name, new InstanceFactory(registerType, registerType, instance));
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a specific, strong referenced, instance.
+ ///
+ /// Type to register
+ /// Type of instance to register that implements RegisterType
+ /// Instance of RegisterImplementation to register
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, Type registerImplementation, object instance)
+ {
+ return RegisterInternal(registerType, string.Empty, new InstanceFactory(registerType, registerImplementation, instance));
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with a specific, strong referenced, instance.
+ ///
+ /// Type to register
+ /// Type of instance to register that implements RegisterType
+ /// Instance of RegisterImplementation to register
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, Type registerImplementation, object instance, string name)
+ {
+ return RegisterInternal(registerType, name, new InstanceFactory(registerType, registerImplementation, instance));
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a user specified factory
+ ///
+ /// Type to register
+ /// Factory/lambda that returns an instance of RegisterType
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, Func factory)
+ {
+ return RegisterInternal(registerType, string.Empty, new DelegateFactory(registerType, factory));
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a user specified factory
+ ///
+ /// Type to register
+ /// Factory/lambda that returns an instance of RegisterType
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Type registerType, Func factory, string name)
+ {
+ return RegisterInternal(registerType, name, new DelegateFactory(registerType, factory));
+ }
+
+ ///
+ /// Creates/replaces a container class registration with default options.
+ ///
+ /// Type to register
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register()
+ where RegisterType : class
+ {
+ return this.Register(typeof(RegisterType));
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with default options.
+ ///
+ /// Type to register
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(string name)
+ where RegisterType : class
+ {
+ return this.Register(typeof(RegisterType), name);
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a given implementation and default options.
+ ///
+ /// Type to register
+ /// Type to instantiate that implements RegisterType
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register()
+ where RegisterType : class
+ where RegisterImplementation : class, RegisterType
+ {
+ return this.Register(typeof(RegisterType), typeof(RegisterImplementation));
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with a given implementation and default options.
+ ///
+ /// Type to register
+ /// Type to instantiate that implements RegisterType
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(string name)
+ where RegisterType : class
+ where RegisterImplementation : class, RegisterType
+ {
+ return this.Register(typeof(RegisterType), typeof(RegisterImplementation), name);
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a specific, strong referenced, instance.
+ ///
+ /// Type to register
+ /// Instance of RegisterType to register
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(RegisterType instance)
+ where RegisterType : class
+ {
+ return this.Register(typeof(RegisterType), instance);
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with a specific, strong referenced, instance.
+ ///
+ /// Type to register
+ /// Instance of RegisterType to register
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(RegisterType instance, string name)
+ where RegisterType : class
+ {
+ return this.Register(typeof(RegisterType), instance, name);
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a specific, strong referenced, instance.
+ ///
+ /// Type to register
+ /// Type of instance to register that implements RegisterType
+ /// Instance of RegisterImplementation to register
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(RegisterImplementation instance)
+ where RegisterType : class
+ where RegisterImplementation : class, RegisterType
+ {
+ return this.Register(typeof(RegisterType), typeof(RegisterImplementation), instance);
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with a specific, strong referenced, instance.
+ ///
+ /// Type to register
+ /// Type of instance to register that implements RegisterType
+ /// Instance of RegisterImplementation to register
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(RegisterImplementation instance, string name)
+ where RegisterType : class
+ where RegisterImplementation : class, RegisterType
+ {
+ return this.Register(typeof(RegisterType), typeof(RegisterImplementation), instance, name);
+ }
+
+ ///
+ /// Creates/replaces a container class registration with a user specified factory
+ ///
+ /// Type to register
+ /// Factory/lambda that returns an instance of RegisterType
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Func factory)
+ where RegisterType : class
+ {
+ if (factory == null)
+ {
+ throw new ArgumentNullException("factory");
+ }
+
+ return this.Register(typeof(RegisterType), (c, o) => factory(c, o));
+ }
+
+ ///
+ /// Creates/replaces a named container class registration with a user specified factory
+ ///
+ /// Type to register
+ /// Factory/lambda that returns an instance of RegisterType
+ /// Name of registration
+ /// RegisterOptions for fluent API
+ public RegisterOptions Register(Func factory, string name)
+ where RegisterType : class
+ {
+ if (factory == null)
+ {
+ throw new ArgumentNullException("factory");
+ }
+
+ return this.Register(typeof(RegisterType), (c, o) => factory(c, o), name);
+ }
+
+ ///
+ /// Register multiple implementations of a type.
+ ///
+ /// Internally this registers each implementation using the full name of the class as its registration name.
+ ///
+ /// Type that each implementation implements
+ /// Types that implement RegisterType
+ /// MultiRegisterOptions for the fluent API
+ public MultiRegisterOptions RegisterMultiple(IEnumerable implementationTypes)
+ {
+ return RegisterMultiple(typeof(RegisterType), implementationTypes);
+ }
+
+ ///
+ /// Register multiple implementations of a type.
+ ///
+ /// Internally this registers each implementation using the full name of the class as its registration name.
+ ///
+ /// Type that each implementation implements
+ /// Types that implement RegisterType
+ /// MultiRegisterOptions for the fluent API
+ public MultiRegisterOptions RegisterMultiple(Type registrationType, IEnumerable implementationTypes)
+ {
+ if (implementationTypes == null)
+ throw new ArgumentNullException("types", "types is null.");
+
+ foreach (var type in implementationTypes)
+ //#if NETFX_CORE
+ // if (!registrationType.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))
+ //#else
+ if (!registrationType.IsAssignableFrom(type))
+ //#endif
+ throw new ArgumentException(String.Format("types: The type {0} is not assignable from {1}", registrationType.FullName, type.FullName));
+
+ if (implementationTypes.Count() != implementationTypes.Distinct().Count())
+ {
+ var queryForDuplicatedTypes = from i in implementationTypes
+ group i by i
+ into j
+ where j.Count() > 1
+ select j.Key.FullName;
+
+ var fullNamesOfDuplicatedTypes = string.Join(",\n", queryForDuplicatedTypes.ToArray());
+ var multipleRegMessage = string.Format("types: The same implementation type cannot be specified multiple times for {0}\n\n{1}", registrationType.FullName, fullNamesOfDuplicatedTypes);
+ throw new ArgumentException(multipleRegMessage);
+ }
+
+ var registerOptions = new List();
+
+ foreach (var type in implementationTypes)
+ {
+ registerOptions.Add(Register(registrationType, type, type.FullName));
+ }
+
+ return new MultiRegisterOptions(registerOptions);
+ }
+ #endregion
+
+ #region Unregistration
+
+ ///
+ /// Remove a container class registration.
+ ///
+ /// Type to unregister
+ /// true if the registration is successfully found and removed; otherwise, false.
+ public bool Unregister()
+ {
+ return Unregister(typeof(RegisterType), string.Empty);
+ }
+
+ ///
+ /// Remove a named container class registration.
+ ///
+ /// Type to unregister
+ /// Name of registration
+ /// true if the registration is successfully found and removed; otherwise, false.
+ public bool Unregister(string name)
+ {
+ return Unregister(typeof(RegisterType), name);
+ }
+
+ ///
+ /// Remove a container class registration.
+ ///
+ /// Type to unregister
+ /// true if the registration is successfully found and removed; otherwise, false.
+ public bool Unregister(Type registerType)
+ {
+ return Unregister(registerType, string.Empty);
+ }
+
+ ///
+ /// Remove a named container class registration.
+ ///
+ /// Type to unregister
+ /// Name of registration
+ /// true if the registration is successfully found and removed; otherwise, false.
+ public bool Unregister(Type registerType, string name)
+ {
+ var typeRegistration = new TypeRegistration(registerType, name);
+
+ return RemoveRegistration(typeRegistration);
+ }
+
+ #endregion
+
+ #region Resolution
+ ///
+ /// Attempts to resolve a type using default options.
+ ///
+ /// Type to resolve
+ /// Instance of type
+ /// Unable to resolve the type.
+ public object Resolve(Type resolveType)
+ {
+ return ResolveInternal(new TypeRegistration(resolveType), NamedParameterOverloads.Default, ResolveOptions.Default);
+ }
+
+ ///
+ /// Attempts to resolve a type using specified options.
+ ///
+ /// Type to resolve
+ /// Resolution options
+ /// Instance of type
+ /// Unable to resolve the type.
+ public object Resolve(Type resolveType, ResolveOptions options)
+ {
+ return ResolveInternal(new TypeRegistration(resolveType), NamedParameterOverloads.Default, options);
+ }
+
+ ///
+ /// Attempts to resolve a type using default options and the supplied name.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Instance of type
+ /// Unable to resolve the type.
+ public object Resolve(Type resolveType, string name)
+ {
+ return ResolveInternal(new TypeRegistration(resolveType, name), NamedParameterOverloads.Default, ResolveOptions.Default);
+ }
+
+ ///
+ /// Attempts to resolve a type using supplied options and name.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Resolution options
+ /// Instance of type
+ /// Unable to resolve the type.
+ public object Resolve(Type resolveType, string name, ResolveOptions options)
+ {
+ return ResolveInternal(new TypeRegistration(resolveType, name), NamedParameterOverloads.Default, options);
+ }
+
+ ///
+ /// Attempts to resolve a type using default options and the supplied constructor parameters.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Instance of type
+ /// Unable to resolve the type.
+ public object Resolve(Type resolveType, NamedParameterOverloads parameters)
+ {
+ return ResolveInternal(new TypeRegistration(resolveType), parameters, ResolveOptions.Default);
+ }
+
+ ///
+ /// Attempts to resolve a type using specified options and the supplied constructor parameters.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Resolution options
+ /// Instance of type
+ /// Unable to resolve the type.
+ public object Resolve(Type resolveType, NamedParameterOverloads parameters, ResolveOptions options)
+ {
+ return ResolveInternal(new TypeRegistration(resolveType), parameters, options);
+ }
+
+ ///
+ /// Attempts to resolve a type using default options and the supplied constructor parameters and name.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Name of registration
+ /// Instance of type
+ /// Unable to resolve the type.
+ public object Resolve(Type resolveType, string name, NamedParameterOverloads parameters)
+ {
+ return ResolveInternal(new TypeRegistration(resolveType, name), parameters, ResolveOptions.Default);
+ }
+
+ ///
+ /// Attempts to resolve a named type using specified options and the supplied constructor parameters.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User specified constructor parameters
+ /// Resolution options
+ /// Instance of type
+ /// Unable to resolve the type.
+ public object Resolve(Type resolveType, string name, NamedParameterOverloads parameters, ResolveOptions options)
+ {
+ return ResolveInternal(new TypeRegistration(resolveType, name), parameters, options);
+ }
+
+ ///
+ /// Attempts to resolve a type using default options.
+ ///
+ /// Type to resolve
+ /// Instance of type
+ /// Unable to resolve the type.
+ public ResolveType Resolve()
+ where ResolveType : class
+ {
+ return (ResolveType)Resolve(typeof(ResolveType));
+ }
+
+ ///
+ /// Attempts to resolve a type using specified options.
+ ///
+ /// Type to resolve
+ /// Resolution options
+ /// Instance of type
+ /// Unable to resolve the type.
+ public ResolveType Resolve(ResolveOptions options)
+ where ResolveType : class
+ {
+ return (ResolveType)Resolve(typeof(ResolveType), options);
+ }
+
+ ///
+ /// Attempts to resolve a type using default options and the supplied name.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Instance of type
+ /// Unable to resolve the type.
+ public ResolveType Resolve(string name)
+ where ResolveType : class
+ {
+ return (ResolveType)Resolve(typeof(ResolveType), name);
+ }
+
+ ///
+ /// Attempts to resolve a type using supplied options and name.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Resolution options
+ /// Instance of type
+ /// Unable to resolve the type.
+ public ResolveType Resolve(string name, ResolveOptions options)
+ where ResolveType : class
+ {
+ return (ResolveType)Resolve(typeof(ResolveType), name, options);
+ }
+
+ ///
+ /// Attempts to resolve a type using default options and the supplied constructor parameters.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Instance of type
+ /// Unable to resolve the type.
+ public ResolveType Resolve(NamedParameterOverloads parameters)
+ where ResolveType : class
+ {
+ return (ResolveType)Resolve(typeof(ResolveType), parameters);
+ }
+
+ ///
+ /// Attempts to resolve a type using specified options and the supplied constructor parameters.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Resolution options
+ /// Instance of type
+ /// Unable to resolve the type.
+ public ResolveType Resolve(NamedParameterOverloads parameters, ResolveOptions options)
+ where ResolveType : class
+ {
+ return (ResolveType)Resolve(typeof(ResolveType), parameters, options);
+ }
+
+ ///
+ /// Attempts to resolve a type using default options and the supplied constructor parameters and name.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Name of registration
+ /// Instance of type
+ /// Unable to resolve the type.
+ public ResolveType Resolve(string name, NamedParameterOverloads parameters)
+ where ResolveType : class
+ {
+ return (ResolveType)Resolve(typeof(ResolveType), name, parameters);
+ }
+
+ ///
+ /// Attempts to resolve a named type using specified options and the supplied constructor parameters.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User specified constructor parameters
+ /// Resolution options
+ /// Instance of type
+ /// Unable to resolve the type.
+ public ResolveType Resolve(string name, NamedParameterOverloads parameters, ResolveOptions options)
+ where ResolveType : class
+ {
+ return (ResolveType)Resolve(typeof(ResolveType), name, parameters, options);
+ }
+
+ ///
+ /// Attempts to predict whether a given type can be resolved with default options.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(Type resolveType)
+ {
+ return CanResolveInternal(new TypeRegistration(resolveType), NamedParameterOverloads.Default, ResolveOptions.Default);
+ }
+
+ ///
+ /// Attempts to predict whether a given named type can be resolved with default options.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Bool indicating whether the type can be resolved
+ private bool CanResolve(Type resolveType, string name)
+ {
+ return CanResolveInternal(new TypeRegistration(resolveType, name), NamedParameterOverloads.Default, ResolveOptions.Default);
+ }
+
+ ///
+ /// Attempts to predict whether a given type can be resolved with the specified options.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Resolution options
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(Type resolveType, ResolveOptions options)
+ {
+ return CanResolveInternal(new TypeRegistration(resolveType), NamedParameterOverloads.Default, options);
+ }
+
+ ///
+ /// Attempts to predict whether a given named type can be resolved with the specified options.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Resolution options
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(Type resolveType, string name, ResolveOptions options)
+ {
+ return CanResolveInternal(new TypeRegistration(resolveType, name), NamedParameterOverloads.Default, options);
+ }
+
+ ///
+ /// Attempts to predict whether a given type can be resolved with the supplied constructor parameters and default options.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// User supplied named parameter overloads
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(Type resolveType, NamedParameterOverloads parameters)
+ {
+ return CanResolveInternal(new TypeRegistration(resolveType), parameters, ResolveOptions.Default);
+ }
+
+ ///
+ /// Attempts to predict whether a given named type can be resolved with the supplied constructor parameters and default options.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User supplied named parameter overloads
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(Type resolveType, string name, NamedParameterOverloads parameters)
+ {
+ return CanResolveInternal(new TypeRegistration(resolveType, name), parameters, ResolveOptions.Default);
+ }
+
+ ///
+ /// Attempts to predict whether a given type can be resolved with the supplied constructor parameters options.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// User supplied named parameter overloads
+ /// Resolution options
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(Type resolveType, NamedParameterOverloads parameters, ResolveOptions options)
+ {
+ return CanResolveInternal(new TypeRegistration(resolveType), parameters, options);
+ }
+
+ ///
+ /// Attempts to predict whether a given named type can be resolved with the supplied constructor parameters options.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User supplied named parameter overloads
+ /// Resolution options
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(Type resolveType, string name, NamedParameterOverloads parameters, ResolveOptions options)
+ {
+ return CanResolveInternal(new TypeRegistration(resolveType, name), parameters, options);
+ }
+
+ ///
+ /// Attempts to predict whether a given type can be resolved with default options.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve()
+ where ResolveType : class
+ {
+ return CanResolve(typeof(ResolveType));
+ }
+
+ ///
+ /// Attempts to predict whether a given named type can be resolved with default options.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(string name)
+ where ResolveType : class
+ {
+ return CanResolve(typeof(ResolveType), name);
+ }
+
+ ///
+ /// Attempts to predict whether a given type can be resolved with the specified options.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Resolution options
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(ResolveOptions options)
+ where ResolveType : class
+ {
+ return CanResolve(typeof(ResolveType), options);
+ }
+
+ ///
+ /// Attempts to predict whether a given named type can be resolved with the specified options.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Resolution options
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(string name, ResolveOptions options)
+ where ResolveType : class
+ {
+ return CanResolve(typeof(ResolveType), name, options);
+ }
+
+ ///
+ /// Attempts to predict whether a given type can be resolved with the supplied constructor parameters and default options.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// User supplied named parameter overloads
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(NamedParameterOverloads parameters)
+ where ResolveType : class
+ {
+ return CanResolve(typeof(ResolveType), parameters);
+ }
+
+ ///
+ /// Attempts to predict whether a given named type can be resolved with the supplied constructor parameters and default options.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User supplied named parameter overloads
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(string name, NamedParameterOverloads parameters)
+ where ResolveType : class
+ {
+ return CanResolve(typeof(ResolveType), name, parameters);
+ }
+
+ ///
+ /// Attempts to predict whether a given type can be resolved with the supplied constructor parameters options.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// User supplied named parameter overloads
+ /// Resolution options
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(NamedParameterOverloads parameters, ResolveOptions options)
+ where ResolveType : class
+ {
+ return CanResolve(typeof(ResolveType), parameters, options);
+ }
+
+ ///
+ /// Attempts to predict whether a given named type can be resolved with the supplied constructor parameters options.
+ ///
+ /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists).
+ /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail.
+ ///
+ /// Note: Resolution may still fail if user defined factory registrations fail to construct objects when called.
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User supplied named parameter overloads
+ /// Resolution options
+ /// Bool indicating whether the type can be resolved
+ public bool CanResolve(string name, NamedParameterOverloads parameters, ResolveOptions options)
+ where ResolveType : class
+ {
+ return CanResolve(typeof(ResolveType), name, parameters, options);
+ }
+
+ ///
+ /// Attempts to resolve a type using the default options
+ ///
+ /// Type to resolve
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(Type resolveType, out object resolvedType)
+ {
+ try
+ {
+ resolvedType = Resolve(resolveType);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the given options
+ ///
+ /// Type to resolve
+ /// Resolution options
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(Type resolveType, ResolveOptions options, out object resolvedType)
+ {
+ try
+ {
+ resolvedType = Resolve(resolveType, options);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the default options and given name
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(Type resolveType, string name, out object resolvedType)
+ {
+ try
+ {
+ resolvedType = Resolve(resolveType, name);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the given options and name
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Resolution options
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(Type resolveType, string name, ResolveOptions options, out object resolvedType)
+ {
+ try
+ {
+ resolvedType = Resolve(resolveType, name, options);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the default options and supplied constructor parameters
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(Type resolveType, NamedParameterOverloads parameters, out object resolvedType)
+ {
+ try
+ {
+ resolvedType = Resolve(resolveType, parameters);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the default options and supplied name and constructor parameters
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User specified constructor parameters
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(Type resolveType, string name, NamedParameterOverloads parameters, out object resolvedType)
+ {
+ try
+ {
+ resolvedType = Resolve(resolveType, name, parameters);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the supplied options and constructor parameters
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Resolution options
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(Type resolveType, NamedParameterOverloads parameters, ResolveOptions options, out object resolvedType)
+ {
+ try
+ {
+ resolvedType = Resolve(resolveType, parameters, options);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the supplied name, options and constructor parameters
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User specified constructor parameters
+ /// Resolution options
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(Type resolveType, string name, NamedParameterOverloads parameters, ResolveOptions options, out object resolvedType)
+ {
+ try
+ {
+ resolvedType = Resolve(resolveType, name, parameters, options);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the default options
+ ///
+ /// Type to resolve
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(out ResolveType resolvedType)
+ where ResolveType : class
+ {
+ try
+ {
+ resolvedType = Resolve();
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = default(ResolveType);
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the given options
+ ///
+ /// Type to resolve
+ /// Resolution options
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(ResolveOptions options, out ResolveType resolvedType)
+ where ResolveType : class
+ {
+ try
+ {
+ resolvedType = Resolve(options);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = default(ResolveType);
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the default options and given name
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(string name, out ResolveType resolvedType)
+ where ResolveType : class
+ {
+ try
+ {
+ resolvedType = Resolve(name);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = default(ResolveType);
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the given options and name
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// Resolution options
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(string name, ResolveOptions options, out ResolveType resolvedType)
+ where ResolveType : class
+ {
+ try
+ {
+ resolvedType = Resolve(name, options);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = default(ResolveType);
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the default options and supplied constructor parameters
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(NamedParameterOverloads parameters, out ResolveType resolvedType)
+ where ResolveType : class
+ {
+ try
+ {
+ resolvedType = Resolve(parameters);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = default(ResolveType);
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the default options and supplied name and constructor parameters
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User specified constructor parameters
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(string name, NamedParameterOverloads parameters, out ResolveType resolvedType)
+ where ResolveType : class
+ {
+ try
+ {
+ resolvedType = Resolve(name, parameters);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = default(ResolveType);
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the supplied options and constructor parameters
+ ///
+ /// Type to resolve
+ /// User specified constructor parameters
+ /// Resolution options
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(NamedParameterOverloads parameters, ResolveOptions options, out ResolveType resolvedType)
+ where ResolveType : class
+ {
+ try
+ {
+ resolvedType = Resolve(parameters, options);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = default(ResolveType);
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to resolve a type using the supplied name, options and constructor parameters
+ ///
+ /// Type to resolve
+ /// Name of registration
+ /// User specified constructor parameters
+ /// Resolution options
+ /// Resolved type or default if resolve fails
+ /// True if resolved successfully, false otherwise
+ public bool TryResolve(string name, NamedParameterOverloads parameters, ResolveOptions options, out ResolveType resolvedType)
+ where ResolveType : class
+ {
+ try
+ {
+ resolvedType = Resolve(name, parameters, options);
+ return true;
+ }
+ catch (TinyIoCResolutionException)
+ {
+ resolvedType = default(ResolveType);
+ return false;
+ }
+ }
+
+ ///
+ /// Returns all registrations of a type
+ ///
+ /// Type to resolveAll
+ /// Whether to include un-named (default) registrations
+ /// IEnumerable
+ public IEnumerable
+
+ MSBuild:UpdateDesignTimeXaml
+
+
+ MSBuild:UpdateDesignTimeXaml
+
ResXFileCodeGenerator
Resources.Designer.cs
diff --git a/Borepin/Borepin/Page/DashboardPage.xaml b/Borepin/Borepin/Page/DashboardPage.xaml
new file mode 100644
index 0000000..f9e5f80
--- /dev/null
+++ b/Borepin/Borepin/Page/DashboardPage.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Borepin/Borepin/Page/DashboardPage.xaml.cs b/Borepin/Borepin/Page/DashboardPage.xaml.cs
new file mode 100644
index 0000000..2a48fbd
--- /dev/null
+++ b/Borepin/Borepin/Page/DashboardPage.xaml.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Xamarin.Forms;
+using Xamarin.Forms.Xaml;
+
+namespace Borepin.Page
+{
+ [XamlCompilation(XamlCompilationOptions.Compile)]
+ public partial class DashboardPage : ContentPage
+ {
+ public DashboardPage()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Borepin/Borepin/Page/LoginPage.xaml b/Borepin/Borepin/Page/LoginPage.xaml
new file mode 100644
index 0000000..e46e166
--- /dev/null
+++ b/Borepin/Borepin/Page/LoginPage.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Borepin/Borepin/Page/LoginPage.xaml.cs b/Borepin/Borepin/Page/LoginPage.xaml.cs
new file mode 100644
index 0000000..cad5e10
--- /dev/null
+++ b/Borepin/Borepin/Page/LoginPage.xaml.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Xamarin.Forms;
+using Xamarin.Forms.Xaml;
+
+namespace Borepin.Page
+{
+ [XamlCompilation(XamlCompilationOptions.Compile)]
+ public partial class LoginPage : ContentPage
+ {
+ public LoginPage()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Borepin/Borepin/PageModel/DashboardPageModel.cs b/Borepin/Borepin/PageModel/DashboardPageModel.cs
new file mode 100644
index 0000000..b93f544
--- /dev/null
+++ b/Borepin/Borepin/PageModel/DashboardPageModel.cs
@@ -0,0 +1,12 @@
+using Borepin.Base;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Borepin.PageModel
+{
+ public class DashboardPageModel : PageModelBase
+ {
+
+ }
+}
diff --git a/Borepin/Borepin/PageModel/LoginPageModel.cs b/Borepin/Borepin/PageModel/LoginPageModel.cs
new file mode 100644
index 0000000..bb23a00
--- /dev/null
+++ b/Borepin/Borepin/PageModel/LoginPageModel.cs
@@ -0,0 +1,34 @@
+using Borepin.Base;
+using Borepin.Page;
+using Borepin.Service.Navigation;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Input;
+using Xamarin.Forms;
+
+namespace Borepin.PageModel
+{
+ public class LoginPageModel : PageModelBase
+ {
+ private ICommand _signInCommand;
+ private INavigationService _NaviagtionService;
+
+ public ICommand SignInCommand
+ {
+ get => _signInCommand;
+ set => SetProperty(ref _signInCommand, value);
+ }
+
+ public LoginPageModel(INavigationService navigationService)
+ {
+ _NaviagtionService = navigationService;
+ SignInCommand = new Command(OnSignInAction);
+ }
+
+ private void OnSignInAction(object obj)
+ {
+ _NaviagtionService.NaviagteToAsync();
+ }
+ }
+}
diff --git a/Borepin/Borepin/Service/Navigation/INavigationService.cs b/Borepin/Borepin/Service/Navigation/INavigationService.cs
new file mode 100644
index 0000000..dc76a88
--- /dev/null
+++ b/Borepin/Borepin/Service/Navigation/INavigationService.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Borepin.Service.Navigation
+{
+ public interface INavigationService
+ {
+ ///
+ /// Navigatoin method to push onto the Navigaiton Stack
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task NaviagteToAsync(object navigationData = null, bool setRoot = false);
+
+ ///
+ /// Nagivation method to pop of Navigation Stack
+ ///
+ ///
+ Task GoBackAsync();
+
+ }
+}
diff --git a/Borepin/Borepin/Service/Navigation/NavigationService.cs b/Borepin/Borepin/Service/Navigation/NavigationService.cs
new file mode 100644
index 0000000..36f0b6a
--- /dev/null
+++ b/Borepin/Borepin/Service/Navigation/NavigationService.cs
@@ -0,0 +1,43 @@
+using Borepin.Base;
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using Xamarin.Forms;
+
+namespace Borepin.Service.Navigation
+{
+ public class NavigationService : INavigationService
+ {
+ public Task GoBackAsync()
+ {
+ return App.Current.MainPage.Navigation.PopAsync();
+ }
+
+ public async Task NaviagteToAsync(object navigationData = null, bool setRoot = false)
+ {
+ Xamarin.Forms.Page page = PageModelLocator.CreatePage(typeof(TPageModelBase));
+ if(setRoot)
+ {
+ App.Current.MainPage = new NavigationPage(page);
+ }
+ else
+ {
+ if(App.Current.MainPage is NavigationPage navPage)
+ {
+ await navPage.PushAsync(page);
+ }
+ else
+ {
+ App.Current.MainPage = new NavigationPage(page);
+ }
+ }
+
+ if(page.BindingContext is PageModelBase pmBase)
+ {
+ await pmBase.InitializeAsync(navigationData);
+ }
+ }
+ }
+}