From 284731eda0a215b4741679a3f0fa619f4827ece5 Mon Sep 17 00:00:00 2001 From: Mauro Da Silva Date: Thu, 29 Jan 2015 07:20:08 +0200 Subject: [PATCH 1/2] Added support for Windows Phone 8.1 and Windows 8.1 --- src/TinyIoC.Tests/TinyIoCTests.cs | 16 +- src/TinyIoC.Tests/TypeExtensionsTests.cs | 59 ++- src/TinyIoC/TinyIoC.cs | 439 ++++++++++++----------- 3 files changed, 305 insertions(+), 209 deletions(-) diff --git a/src/TinyIoC.Tests/TinyIoCTests.cs b/src/TinyIoC.Tests/TinyIoCTests.cs index 52970eb..14ef61d 100644 --- a/src/TinyIoC.Tests/TinyIoCTests.cs +++ b/src/TinyIoC.Tests/TinyIoCTests.cs @@ -1473,11 +1473,15 @@ public void AutoRegister_TinyIoCAssembly_CannotResolveInternalTinyIoCClass() } [TestMethod] - [ExpectedException(typeof(TinyIoCAutoRegistrationException))] + //[ExpectedException(typeof(TinyIoCAutoRegistrationException))] public void AutoRegister_ThisAssemblySpecifiedDuplicateActionFail_ThrowsException() { var container = UtilityMethods.GetContainer(); - container.AutoRegister(new[] { this.GetType().Assembly }, DuplicateImplementationActions.Fail); +#if NETFX_CORE + AssertHelper.ThrowsException(() => container.AutoRegister(new[] { this.GetType().GetTypeInfo().Assembly }, DuplicateImplementationActions.Fail)); +#else + AssertHelper.ThrowsException(() => container.AutoRegister(new[] { this.GetType().Assembly }, DuplicateImplementationActions.Fail)); +#endif //Assert.IsTrue(false); } @@ -1485,14 +1489,22 @@ public void AutoRegister_ThisAssemblySpecifiedDuplicateActionFail_ThrowsExceptio public void AutoRegister_TinyIoCAssemblySpecifiedDuplicateActionFail_NoErrors() { var container = UtilityMethods.GetContainer(); +#if NETFX_CORE + container.AutoRegister(new[] { typeof(TinyIoCContainer).GetTypeInfo().Assembly }, DuplicateImplementationActions.Fail); +#else container.AutoRegister(new[] { typeof(TinyIoCContainer).Assembly }, DuplicateImplementationActions.Fail); +#endif } [TestMethod] public void AutoRegister_SpecifiedDuplicateActionRegisterMultiple_RegistersMultipleImplementations() { var container = UtilityMethods.GetContainer(); +#if NETFX_CORE + container.AutoRegister(new[] { typeof(TestClassDefaultCtor).GetTypeInfo().Assembly }, DuplicateImplementationActions.RegisterMultiple); +#else container.AutoRegister(new[] { typeof(TestClassDefaultCtor).Assembly }, DuplicateImplementationActions.RegisterMultiple); +#endif var results = container.ResolveAll(); diff --git a/src/TinyIoC.Tests/TypeExtensionsTests.cs b/src/TinyIoC.Tests/TypeExtensionsTests.cs index 260bcd6..5f36ab7 100644 --- a/src/TinyIoC.Tests/TypeExtensionsTests.cs +++ b/src/TinyIoC.Tests/TypeExtensionsTests.cs @@ -22,7 +22,7 @@ public class ClassImplementingITestInterface : ITestInterface public class AnotherClassImplementingITestInterface : ITestInterface { - + } public class ClassNotImplementingITestInterface @@ -37,12 +37,20 @@ public void GetGenericMethod_RegisterOneGenericParameterNoParameters_ReturnsCorr { var firstGenericParameter = typeof(ClassNotImplementingITestInterface); +#if NETFX_CORE + var method = typeof(TinyIoCContainer).GetGenericMethod( + "Register", + new Type[] { firstGenericParameter }, + new Type[] { } + ); +#else var method = typeof(TinyIoCContainer).GetGenericMethod( - BindingFlags.Public | BindingFlags.Instance, - "Register", - new Type[] {firstGenericParameter}, + BindingFlags.Public | BindingFlags.Instance, + "Register", + new Type[] { firstGenericParameter }, new Type[] { } ); +#endif Assert.IsInstanceOfType(method, typeof(MethodInfo)); Assert.IsTrue(method.IsGenericMethod); @@ -57,12 +65,20 @@ public void GetGenericMethod_RegisterTwoAcceptableGenericParameterNoParameters_R var firstGenericParameter = typeof(ITestInterface); var secondGenericParameter = typeof(ClassImplementingITestInterface); +#if NETFX_CORE var method = typeof(TinyIoCContainer).GetGenericMethod( + "Register", + new Type[] { firstGenericParameter, secondGenericParameter }, + new Type[] { } + ); +#else + var method = typeof(TinyIoCContainer).GetGenericMethod( BindingFlags.Public | BindingFlags.Instance, "Register", new Type[] { firstGenericParameter, secondGenericParameter }, new Type[] { } ); +#endif Assert.IsInstanceOfType(method, typeof(MethodInfo)); Assert.IsTrue(method.IsGenericMethod); @@ -80,6 +96,16 @@ public void GetGenericMethod_TwiceWithDifferentGenericParamters_ReturnsCorrectMe var methodTwoFirstGenericParameter = typeof(ITestInterface); var methodTwoSecondGenericParameter = typeof(AnotherClassImplementingITestInterface); +#if NETFX_CORE + var methodOne = typeof(TinyIoCContainer).GetGenericMethod( + "Register", + new Type[] { methodOneFirstGenericParameter, methodOneSecondGenericParameter }, + new Type[] { }); + var methodTwo = typeof(TinyIoCContainer).GetGenericMethod( + "Register", + new Type[] { methodTwoFirstGenericParameter, methodTwoSecondGenericParameter }, + new Type[] { }); +#else var methodOne = typeof(TinyIoCContainer).GetGenericMethod( BindingFlags.Public | BindingFlags.Instance, "Register", @@ -90,6 +116,7 @@ public void GetGenericMethod_TwiceWithDifferentGenericParamters_ReturnsCorrectMe "Register", new Type[] { methodTwoFirstGenericParameter, methodTwoSecondGenericParameter }, new Type[] { }); +#endif Assert.IsInstanceOfType(methodOne, typeof(MethodInfo)); Assert.IsTrue(methodOne.IsGenericMethod); @@ -110,12 +137,20 @@ public void GetGenericMethod_RegisterTwoUnacceptableGenericParameterNoParameters { try { +#if NETFX_CORE + var method = typeof(TinyIoCContainer).GetGenericMethod( + "Register", + new Type[] { typeof(ITestInterface), typeof(ClassNotImplementingITestInterface) }, + new Type[] { } + ); +#else var method = typeof(TinyIoCContainer).GetGenericMethod( BindingFlags.Public | BindingFlags.Instance, "Register", new Type[] { typeof(ITestInterface), typeof(ClassNotImplementingITestInterface) }, new Type[] { } ); +#endif Assert.Fail(); } @@ -131,12 +166,20 @@ public void GetGenericMethod_RegisterTwoAcceptableGenericParameterMethodParamete var secondGenericParameter = typeof(ClassImplementingITestInterface); var firstParameter = typeof(string); +#if NETFX_CORE + var method = typeof(TinyIoCContainer).GetGenericMethod( + "Register", + new Type[] { firstGenericParameter, secondGenericParameter }, + new Type[] { firstParameter } + ); +#else var method = typeof(TinyIoCContainer).GetGenericMethod( BindingFlags.Public | BindingFlags.Instance, "Register", new Type[] { firstGenericParameter, secondGenericParameter }, new Type[] { firstParameter } ); +#endif Assert.IsInstanceOfType(method, typeof(MethodInfo)); Assert.IsTrue(method.IsGenericMethod); @@ -154,12 +197,20 @@ public void GetGenericMethod_RegisterWithGenericTypeAsAMethodParameter_ReturnsCo var secondGenericParameter = typeof(ClassImplementingITestInterface); var firstParameter = typeof(ClassImplementingITestInterface); +#if NETFX_CORE + var method = typeof(TinyIoCContainer).GetGenericMethod( + "Register", + new Type[] { firstGenericParameter, secondGenericParameter }, + new Type[] { firstParameter } + ); +#else var method = typeof(TinyIoCContainer).GetGenericMethod( BindingFlags.Public | BindingFlags.Instance, "Register", new Type[] { firstGenericParameter, secondGenericParameter }, new Type[] { firstParameter } ); +#endif Assert.IsInstanceOfType(method, typeof(MethodInfo)); Assert.IsTrue(method.IsGenericMethod); diff --git a/src/TinyIoC/TinyIoC.cs b/src/TinyIoC/TinyIoC.cs index d38ad8d..f718d7e 100644 --- a/src/TinyIoC/TinyIoC.cs +++ b/src/TinyIoC/TinyIoC.cs @@ -1,4 +1,5 @@ -//=============================================================================== + +//=============================================================================== // TinyIoC // // An easy to use, hassle free, Inversion of Control Container for small projects @@ -29,10 +30,6 @@ #define RESOLVE_OPEN_GENERICS // Platform supports resolving open generics #define READER_WRITER_LOCK_SLIM // Platform supports ReaderWriterLockSlim -//// NETFX_CORE -//#if NETFX_CORE -//#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. @@ -80,10 +77,10 @@ namespace TinyIoC #endif #if NETFX_CORE - using System.Threading.Tasks; - using Windows.Storage.Search; + using System.Threading.Tasks; + using Windows.Storage.Search; using Windows.Storage; - using Windows.UI.Xaml.Shapes; + using Windows.UI.Xaml.Shapes; #endif #region SafeDictionary @@ -93,9 +90,9 @@ namespace TinyIoC #else public #endif - class SafeDictionary : IDisposable + class SafeDictionary : IDisposable { - private readonly ReaderWriterLockSlim _padlock = new ReaderWriterLockSlim(); + private readonly System.Threading.ReaderWriterLockSlim _padlock = new System.Threading.ReaderWriterLockSlim(); private readonly Dictionary _Dictionary = new Dictionary(); public TValue this[TKey key] @@ -268,7 +265,7 @@ public IEnumerable Keys return _Dictionary.Keys; } } - #region IDisposable Members + #region IDisposable Members public void Dispose() { @@ -287,7 +284,7 @@ where item is IDisposable GC.SuppressFinalize(this); } - #endregion + #endregion } #endif #endregion @@ -298,7 +295,7 @@ where item is IDisposable #else public #endif - static class AssemblyExtensions + static class AssemblyExtensions { public static Type[] SafeGetTypes(this Assembly assembly) { @@ -306,7 +303,11 @@ public static Type[] SafeGetTypes(this Assembly assembly) try { +#if NETFX_CORE + assemblies = assembly.DefinedTypes.Select(aa => aa.AsType()).ToArray(); +#else assemblies = assembly.GetTypes(); +#endif } catch (System.IO.FileNotFoundException) { @@ -331,7 +332,7 @@ public static Type[] SafeGetTypes(this Assembly assembly) #else public #endif - static class TypeExtensions + static class TypeExtensions { private static SafeDictionary _genericMethodCache; @@ -340,34 +341,6 @@ static TypeExtensions() _genericMethodCache = new SafeDictionary(); } -//#if NETFX_CORE -// /// -// /// Gets a generic method from a type given the method name, generic types and parameter types -// /// -// /// Source type -// /// 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, 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, methodName, genericTypes, parameterTypes); -// _genericMethodCache[cacheKey] = method; -// } - -// return method; -// } -//#else /// /// Gets a generic method from a type given the method name, binding flags, generic types and parameter types /// @@ -379,7 +352,11 @@ static TypeExtensions() /// MethodInfo or null if no matches found /// /// +#if NETFX_CORE + public static MethodInfo GetGenericMethod(this Type sourceType, string methodName, Type[] genericTypes, Type[] parameterTypes) +#else public static MethodInfo GetGenericMethod(this Type sourceType, BindingFlags bindingFlags, string methodName, Type[] genericTypes, Type[] parameterTypes) +#endif { MethodInfo method; var cacheKey = new GenericMethodCacheKey(sourceType, methodName, genericTypes, parameterTypes); @@ -389,19 +366,22 @@ public static MethodInfo GetGenericMethod(this Type sourceType, BindingFlags bin // more than once before it gets cached. if (!_genericMethodCache.TryGetValue(cacheKey, out method)) { +#if NETFX_CORE + method = GetMethod(sourceType, methodName, genericTypes, parameterTypes); +#else method = GetMethod(sourceType, bindingFlags, methodName, genericTypes, parameterTypes); +#endif _genericMethodCache[cacheKey] = method; } return method; } -//#endif #if NETFX_CORE - private static MethodInfo GetMethod(Type sourceType, BindingFlags flags, string methodName, Type[] genericTypes, Type[] parameterTypes) + private static MethodInfo GetMethod(Type sourceType, string methodName, Type[] genericTypes, Type[] parameterTypes) { var methods = - sourceType.GetMethods(flags).Where( + sourceType.GetTypeInfo().DeclaredMethods.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( @@ -529,18 +509,18 @@ private int GenerateHashCode() } } - } + } - // @mbrit - 2012-05-22 - shim for ForEach call on List... + // @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); - } - } + internal static class ListExtender + { + internal static void ForEach(this List list, Action callback) + { + foreach (T obj in list) + callback(obj); + } + } #endif #endregion @@ -551,7 +531,7 @@ internal static void ForEach(this List list, Action callback) #else public #endif - class TinyIoCResolutionException : Exception + class TinyIoCResolutionException : Exception { private const string ERROR_TEXT = "Unable to resolve type: {0}"; @@ -571,7 +551,7 @@ public TinyIoCResolutionException(Type type, Exception innerException) #else public #endif - class TinyIoCRegistrationTypeException : Exception + class TinyIoCRegistrationTypeException : Exception { private const string REGISTER_ERROR_TEXT = "Cannot register type {0} - abstract classes or interfaces are not valid implementation types for {1}."; @@ -591,7 +571,7 @@ public TinyIoCRegistrationTypeException(Type type, string factory, Exception inn #else public #endif - class TinyIoCRegistrationException : Exception + 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}"; @@ -622,7 +602,7 @@ public TinyIoCRegistrationException(Type registerType, Type implementationType, #else public #endif - class TinyIoCWeakReferenceException : Exception + class TinyIoCWeakReferenceException : Exception { private const string ERROR_TEXT = "Unable to instantiate {0} - referenced object has been reclaimed"; @@ -642,7 +622,7 @@ public TinyIoCWeakReferenceException(Type type, Exception innerException) #else public #endif - class TinyIoCConstructorResolutionException : Exception + class TinyIoCConstructorResolutionException : Exception { private const string ERROR_TEXT = "Unable to resolve constructor for {0} using provided Expression."; @@ -672,7 +652,7 @@ public TinyIoCConstructorResolutionException(string message) #else public #endif - class TinyIoCAutoRegistrationException : Exception + class TinyIoCAutoRegistrationException : Exception { private const string ERROR_TEXT = "Duplicate implementation of type {0} found ({1})."; @@ -705,7 +685,7 @@ private static string GetTypesString(IEnumerable types) #else public #endif - sealed class NamedParameterOverloads : Dictionary + sealed class NamedParameterOverloads : Dictionary { public static NamedParameterOverloads FromIDictionary(IDictionary data) { @@ -737,7 +717,7 @@ public static NamedParameterOverloads Default #else public #endif - enum UnregisteredResolutionActions + enum UnregisteredResolutionActions { /// /// Attempt to resolve type, even if the type isn't registered. @@ -765,7 +745,7 @@ enum UnregisteredResolutionActions #else public #endif - enum NamedResolutionFailureActions + enum NamedResolutionFailureActions { AttemptUnnamedResolution, Fail @@ -776,7 +756,7 @@ enum NamedResolutionFailureActions #else public #endif - enum DuplicateImplementationActions + enum DuplicateImplementationActions { RegisterSingle, RegisterMultiple, @@ -791,7 +771,7 @@ enum DuplicateImplementationActions #else public #endif - sealed class ResolveOptions + sealed class ResolveOptions { private static readonly ResolveOptions _Default = new ResolveOptions(); private static readonly ResolveOptions _FailUnregisteredAndNameNotFound = new ResolveOptions() { NamedResolutionFailureAction = NamedResolutionFailureActions.Fail, UnregisteredResolutionAction = UnregisteredResolutionActions.Fail }; @@ -863,7 +843,7 @@ public static ResolveOptions FailUnregisteredOnly #else public #endif - sealed partial class TinyIoCContainer : IDisposable + sealed partial class TinyIoCContainer : IDisposable { #region Fake NETFX_CORE Classes #if NETFX_CORE @@ -880,33 +860,33 @@ static AppDomain() CurrentDomain = new AppDomain(); } - // @mbrit - 2012-05-30 - in WinRT, this should be done async... + // @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(); + 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... - } + try + { + var asm = Assembly.Load(name); + assemblies.Add(asm); + } + catch + { + // ignore exceptions here... + } } } - return assemblies; + return assemblies; } } #endif @@ -931,7 +911,7 @@ public RegisterOptions(TinyIoCContainer container, TypeRegistration registration /// Make registration a singleton (single instance) if possible /// /// RegisterOptions - /// + /// public RegisterOptions AsSingleton() { var currentFactory = _Container.GetCurrentFactory(_Registration); @@ -946,7 +926,7 @@ public RegisterOptions AsSingleton() /// Make registration multi-instance if possible /// /// RegisterOptions - /// + /// public RegisterOptions AsMultiInstance() { var currentFactory = _Container.GetCurrentFactory(_Registration); @@ -961,7 +941,7 @@ public RegisterOptions AsMultiInstance() /// Make registration hold a weak reference if possible /// /// RegisterOptions - /// + /// public RegisterOptions WithWeakReference() { var currentFactory = _Container.GetCurrentFactory(_Registration); @@ -976,7 +956,7 @@ public RegisterOptions WithWeakReference() /// Make registration hold a strong reference if possible /// /// RegisterOptions - /// + /// public RegisterOptions WithStrongReference() { var currentFactory = _Container.GetCurrentFactory(_Registration); @@ -1060,7 +1040,6 @@ public MultiRegisterOptions(IEnumerable registerOptions) /// Make registration a singleton (single instance) if possible /// /// RegisterOptions - /// public MultiRegisterOptions AsSingleton() { _RegisterOptions = ExecuteOnAllRegisterOptions(ro => ro.AsSingleton()); @@ -1071,7 +1050,6 @@ public MultiRegisterOptions AsSingleton() /// Make registration multi-instance if possible /// /// MultiRegisterOptions - /// public MultiRegisterOptions AsMultiInstance() { _RegisterOptions = ExecuteOnAllRegisterOptions(ro => ro.AsMultiInstance()); @@ -1139,8 +1117,10 @@ public void AutoRegister() { #if APPDOMAIN_GETASSEMBLIES AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), DuplicateImplementationActions.RegisterSingle, null); +#elif NETFX_CORE + AutoRegisterInternal(new Assembly[] { this.GetType().GetTypeInfo().Assembly }, DuplicateImplementationActions.RegisterSingle, null); #else - AutoRegisterInternal(new Assembly[] {this.GetType().Assembly()}, true, null); + AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, DuplicateImplementationActions.RegisterSingle, null); #endif } @@ -1156,8 +1136,10 @@ public void AutoRegister(Func registrationPredicate) { #if APPDOMAIN_GETASSEMBLIES AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), DuplicateImplementationActions.RegisterSingle, registrationPredicate); +#elif NETFX_CORE + AutoRegisterInternal(new Assembly[] { this.GetType().GetTypeInfo().Assembly }, DuplicateImplementationActions.RegisterSingle, registrationPredicate); #else - AutoRegisterInternal(new Assembly[] { this.GetType().Assembly()}, true, registrationPredicate); + AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, DuplicateImplementationActions.RegisterSingle, registrationPredicate); #endif } @@ -1170,8 +1152,10 @@ public void AutoRegister(DuplicateImplementationActions duplicateAction) { #if APPDOMAIN_GETASSEMBLIES AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), duplicateAction, null); +#elif NETFX_CORE + AutoRegisterInternal(new Assembly[] { this.GetType().GetTypeInfo().Assembly }, duplicateAction, null); #else - AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, ignoreDuplicateImplementations, null); + AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, duplicateAction, null); #endif } @@ -1186,12 +1170,14 @@ public void AutoRegister(DuplicateImplementationActions duplicateAction, Func !IsIgnoredAssembly(a)), duplicateAction, registrationPredicate); +#elif NETFX_CORE + AutoRegisterInternal(new Assembly[] { this.GetType().GetTypeInfo().Assembly }, duplicateAction, registrationPredicate); #else - AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, ignoreDuplicateImplementations, registrationPredicate); + 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 @@ -1360,7 +1346,7 @@ public RegisterOptions Register(Type registerType, Func /// Creates/replaces a container class registration with default options. /// - /// Type to register + /// Type to register /// RegisterOptions for fluent API public RegisterOptions Register() where RegisterType : class @@ -1371,7 +1357,7 @@ public RegisterOptions Register() /// /// Creates/replaces a named container class registration with default options. /// - /// Type to register + /// Type to register /// Name of registration /// RegisterOptions for fluent API public RegisterOptions Register(string name) @@ -1523,12 +1509,12 @@ public MultiRegisterOptions RegisterMultiple(Type registrationType, IEnumerable< throw new ArgumentNullException("types", "types is null."); foreach (var type in implementationTypes) -//#if NETFX_CORE -// if (!registrationType.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) -//#else +#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)); +#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()) { @@ -2576,13 +2562,13 @@ private class MultiInstanceFactory : ObjectFactoryBase public MultiInstanceFactory(Type registerType, Type registerImplementation) { -//#if NETFX_CORE -// if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) -// throw new TinyIoCRegistrationTypeException(registerImplementation, "MultiInstanceFactory"); -//#else +#if NETFX_CORE + if (registerImplementation.GetTypeInfo().IsAbstract || registerImplementation.GetTypeInfo().IsInterface) + throw new TinyIoCRegistrationTypeException(registerImplementation, "MultiInstanceFactory"); +#else if (registerImplementation.IsAbstract() || registerImplementation.IsInterface()) throw new TinyIoCRegistrationTypeException(registerImplementation, "MultiInstanceFactory"); -//#endif +#endif if (!IsValidAssignment(registerType, registerImplementation)) throw new TinyIoCRegistrationTypeException(registerImplementation, "MultiInstanceFactory"); @@ -2649,7 +2635,7 @@ public override object GetObject(Type requestedType, TinyIoCContainer container, } } - public DelegateFactory( Type registerType, Func factory) + public DelegateFactory(Type registerType, Func factory) { if (factory == null) throw new ArgumentNullException("factory"); @@ -2906,11 +2892,11 @@ private class SingletonFactory : ObjectFactoryBase, IDisposable public SingletonFactory(Type registerType, Type registerImplementation) { -//#if NETFX_CORE -// if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) -//#else +#if NETFX_CORE + if (registerImplementation.GetTypeInfo().IsAbstract || registerImplementation.GetTypeInfo().IsInterface) +#else if (registerImplementation.IsAbstract() || registerImplementation.IsInterface()) -//#endif +#endif throw new TinyIoCRegistrationTypeException(registerImplementation, "SingletonFactory"); if (!IsValidAssignment(registerType, registerImplementation)) @@ -2969,7 +2955,7 @@ public override ObjectFactoryBase GetFactoryForChildContainer(Type type, TinyIoC public void Dispose() { - if (this._Current == null) + if (this._Current == null) return; var disposable = this._Current as IDisposable; @@ -2997,11 +2983,11 @@ public CustomObjectLifetimeFactory(Type registerType, Type registerImplementatio if (!IsValidAssignment(registerType, registerImplementation)) throw new TinyIoCRegistrationTypeException(registerImplementation, "SingletonFactory"); -//#if NETFX_CORE -// if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) -//#else +#if NETFX_CORE + if (registerImplementation.GetTypeInfo().IsAbstract || registerImplementation.GetTypeInfo().IsInterface) +#else if (registerImplementation.IsAbstract() || registerImplementation.IsInterface()) -//#endif +#endif throw new TinyIoCRegistrationTypeException(registerImplementation, errorMessage); this.registerType = registerType; @@ -3133,7 +3119,7 @@ public override int GetHashCode() } } private readonly SafeDictionary _RegisteredTypes; -#if USE_OBJECT_CONSTRUCTOR +#if USE_OBJECT_CONSTRUCTOR private delegate object ObjectConstructor(params object[] parameters); private static readonly SafeDictionary _ObjectConstructorCache = new SafeDictionary(); #endif @@ -3164,8 +3150,14 @@ private void AutoRegisterInternal(IEnumerable assemblies, DuplicateImp var types = assemblies.SelectMany(a => a.SafeGetTypes()).Where(t => !IsIgnoredType(t, registrationPredicate)).ToList(); var concreteTypes = types - .Where(type => type.IsClass() && (type.IsAbstract() == false) && (type != this.GetType() && (type.DeclaringType != this.GetType()) && (!type.IsGenericTypeDefinition()))) - .ToList(); + +#if NETFX_CORE +.Where(type => type.GetTypeInfo().IsClass && (type.GetTypeInfo().IsAbstract == false) && (type != this.GetType() && (type.GetTypeInfo().DeclaringType != this.GetType()) && (!type.GetTypeInfo().IsGenericTypeDefinition))) +#else +.Where(type => type.IsClass() && (type.IsAbstract() == false) && (type != this.GetType() && (type.DeclaringType != this.GetType()) && (!type.IsGenericTypeDefinition()))) +#endif + +.ToList(); foreach (var type in concreteTypes) { @@ -3180,14 +3172,22 @@ private void AutoRegisterInternal(IEnumerable assemblies, DuplicateImp } var abstractInterfaceTypes = from type in types +#if NETFX_CORE + where ((type.GetTypeInfo().IsInterface || type.GetTypeInfo().IsAbstract) && (type.DeclaringType != this.GetType()) && (!type.GetTypeInfo().IsGenericTypeDefinition)) +#else where ((type.IsInterface() || type.IsAbstract()) && (type.DeclaringType != this.GetType()) && (!type.IsGenericTypeDefinition())) +#endif select type; foreach (var type in abstractInterfaceTypes) { var localType = type; var implementations = from implementationType in concreteTypes +#if NETFX_CORE + where localType.GetTypeInfo().IsAssignableFrom(implementationType.GetTypeInfo()) +#else where localType.IsAssignableFrom(implementationType) +#endif select implementationType; if (implementations.Skip(1).Any()) @@ -3199,7 +3199,7 @@ where localType.IsAssignableFrom(implementationType) { RegisterMultiple(type, implementations); } - } + } var firstImplementation = implementations.FirstOrDefault(); if (firstImplementation != null) @@ -3247,16 +3247,24 @@ private bool IsIgnoredType(Type type, Func registrationPredicate) { t => t.FullName.StartsWith("System.", StringComparison.Ordinal), t => t.FullName.StartsWith("Microsoft.", StringComparison.Ordinal), +#if NETFX_CORE + t => t.GetTypeInfo().IsPrimitive, +#else t => t.IsPrimitive(), +#endif #if !UNBOUND_GENERICS_GETCONSTRUCTORS t => t.IsGenericTypeDefinition(), #endif +#if NETFX_CORE + t => (!t.GetTypeInfo().DeclaredConstructors.Any()) && !(t.GetTypeInfo().IsInterface || t.GetTypeInfo().IsAbstract), +#else t => (t.GetConstructors(BindingFlags.Instance | BindingFlags.Public).Length == 0) && !(t.IsInterface() || t.IsAbstract()), +#endif }; if (registrationPredicate != null) { - ignoreChecks.Add(t => !registrationPredicate(t)); + ignoreChecks.Add(t => !registrationPredicate(t)); } foreach (var check in ignoreChecks) @@ -3309,11 +3317,11 @@ private void RemoveRegistration(TypeRegistration typeRegistration) private ObjectFactoryBase GetDefaultObjectFactory(Type registerType, Type registerImplementation) { -//#if NETFX_CORE -// if (registerType.GetTypeInfo().IsInterface() || registerType.GetTypeInfo().IsAbstract()) -//#else +#if NETFX_CORE + if (registerType.GetTypeInfo().IsInterface || registerType.GetTypeInfo().IsAbstract) +#else if (registerType.IsInterface() || registerType.IsAbstract()) -//#endif +#endif return new SingletonFactory(registerType, registerImplementation); return new MultiInstanceFactory(registerType, registerImplementation); @@ -3383,7 +3391,11 @@ private bool CanResolveInternal(TypeRegistration registration, NamedParameterOve // Attempt unregistered construction if possible and requested // If we cant', bubble if we have a parent +#if NETFX_CORE + if ((options.UnregisteredResolutionAction == UnregisteredResolutionActions.AttemptResolve) || (checkType.GetTypeInfo().IsGenericType && options.UnregisteredResolutionAction == UnregisteredResolutionActions.GenericsOnly)) +#else if ((options.UnregisteredResolutionAction == UnregisteredResolutionActions.AttemptResolve) || (checkType.IsGenericType() && options.UnregisteredResolutionAction == UnregisteredResolutionActions.GenericsOnly)) +#endif return (GetBestConstructor(checkType, parameters, options) != null) ? true : (_Parent != null) ? _Parent.CanResolveInternal(registration, parameters, options) : false; // Bubble resolution up the container tree if we have a parent @@ -3395,7 +3407,11 @@ private bool CanResolveInternal(TypeRegistration registration, NamedParameterOve private bool IsIEnumerableRequest(Type type) { +#if NETFX_CORE + if (!type.GetTypeInfo().IsGenericType) +#else if (!type.IsGenericType()) +#endif return false; Type genericType = type.GetGenericTypeDefinition(); @@ -3408,7 +3424,11 @@ private bool IsIEnumerableRequest(Type type) private bool IsAutomaticLazyFactoryRequest(Type type) { +#if NETFX_CORE + if (!type.GetTypeInfo().IsGenericType) +#else if (!type.IsGenericType()) +#endif return false; Type genericType = type.GetGenericTypeDefinition(); @@ -3418,19 +3438,19 @@ private bool IsAutomaticLazyFactoryRequest(Type type) return true; // 2 parameter func with string as first parameter (name) -//#if NETFX_CORE -// if ((genericType == typeof(Func<,>) && type.GetTypeInfo().GenericTypeArguments[0] == typeof(string))) -//#else +#if NETFX_CORE + if ((genericType == typeof(Func<,>) && type.GetTypeInfo().GenericTypeArguments[0] == typeof(string))) +#else if ((genericType == typeof(Func<,>) && type.GetGenericArguments()[0] == typeof(string))) -//#endif +#endif return true; // 3 parameter func with string as first parameter (name) and IDictionary as second (parameters) -//#if NETFX_CORE -// if ((genericType == typeof(Func<,,>) && type.GetTypeInfo().GenericTypeArguments[0] == typeof(string) && type.GetTypeInfo().GenericTypeArguments[1] == typeof(IDictionary))) -//#else +#if NETFX_CORE + if ((genericType == typeof(Func<,,>) && type.GetTypeInfo().GenericTypeArguments[0] == typeof(string) && type.GetTypeInfo().GenericTypeArguments[1] == typeof(IDictionary))) +#else if ((genericType == typeof(Func<,,>) && type.GetGenericArguments()[0] == typeof(string) && type.GetGenericArguments()[1] == typeof(IDictionary))) -//#endif +#endif return true; return false; @@ -3547,9 +3567,18 @@ private object ResolveInternal(TypeRegistration registration, NamedParameterOver return GetIEnumerableRequest(registration.Type); // Attempt unregistered construction if possible and requested + +#if NETFX_CORE + if ((options.UnregisteredResolutionAction == UnregisteredResolutionActions.AttemptResolve) || (registration.Type.GetTypeInfo().IsGenericType && options.UnregisteredResolutionAction == UnregisteredResolutionActions.GenericsOnly)) +#else if ((options.UnregisteredResolutionAction == UnregisteredResolutionActions.AttemptResolve) || (registration.Type.IsGenericType() && options.UnregisteredResolutionAction == UnregisteredResolutionActions.GenericsOnly)) +#endif { +#if NETFX_CORE + if (!registration.Type.GetTypeInfo().IsAbstract && !registration.Type.GetTypeInfo().IsInterface) +#else if (!registration.Type.IsAbstract() && !registration.Type.IsInterface()) +#endif return ConstructType(null, registration.Type, parameters, options); } @@ -3560,26 +3589,30 @@ private object ResolveInternal(TypeRegistration registration, NamedParameterOver #if EXPRESSIONS private object GetLazyAutomaticFactoryRequest(Type type) { +#if NETFX_CORE + if (!type.GetTypeInfo().IsGenericType) +#else if (!type.IsGenericType()) +#endif return null; Type genericType = type.GetGenericTypeDefinition(); -//#if NETFX_CORE -// Type[] genericArguments = type.GetTypeInfo().GenericTypeArguments.ToArray(); -//#else +#if NETFX_CORE + Type[] genericArguments = type.GetTypeInfo().GenericTypeArguments.ToArray(); +#else Type[] genericArguments = type.GetGenericArguments(); -//#endif +#endif // Just a func if (genericType == typeof(Func<>)) { Type returnType = genericArguments[0]; -//#if NETFX_CORE -// MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => !mi.GetParameters().Any()); -//#else +#if NETFX_CORE + MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => !mi.GetParameters().Any()); +#else MethodInfo resolveMethod = typeof(TinyIoCContainer).GetMethod("Resolve", new Type[] { }); -//#endif +#endif resolveMethod = resolveMethod.MakeGenericMethod(returnType); var resolveCall = Expression.Call(Expression.Constant(this), resolveMethod); @@ -3594,11 +3627,11 @@ private object GetLazyAutomaticFactoryRequest(Type type) { Type returnType = genericArguments[1]; -//#if NETFX_CORE -// MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => mi.GetParameters().Length == 1 && mi.GetParameters()[0].GetType() == typeof(String)); -//#else +#if NETFX_CORE + MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => mi.GetParameters().Length == 1 && mi.GetParameters()[0].ParameterType == typeof(String)); +#else MethodInfo resolveMethod = typeof(TinyIoCContainer).GetMethod("Resolve", new Type[] { typeof(String) }); -//#endif +#endif resolveMethod = resolveMethod.MakeGenericMethod(returnType); ParameterExpression[] resolveParameters = new ParameterExpression[] { Expression.Parameter(typeof(String), "name") }; @@ -3610,22 +3643,22 @@ private object GetLazyAutomaticFactoryRequest(Type type) } // 3 parameter func with string as first parameter (name) and IDictionary as second (parameters) -//#if NETFX_CORE -// if ((genericType == typeof(Func<,,>) && type.GenericTypeArguments[0] == typeof(string) && type.GenericTypeArguments[1] == typeof(IDictionary))) -//#else +#if NETFX_CORE + if ((genericType == typeof(Func<,,>) && type.GenericTypeArguments[0] == typeof(string) && type.GenericTypeArguments[1] == typeof(IDictionary))) +#else if ((genericType == typeof(Func<,,>) && type.GetGenericArguments()[0] == typeof(string) && type.GetGenericArguments()[1] == typeof(IDictionary))) -//#endif +#endif { Type returnType = genericArguments[2]; var name = Expression.Parameter(typeof(string), "name"); var parameters = Expression.Parameter(typeof(IDictionary), "parameters"); -//#if NETFX_CORE -// MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => mi.GetParameters().Length == 2 && mi.GetParameters()[0].GetType() == typeof(String) && mi.GetParameters()[1].GetType() == typeof(NamedParameterOverloads)); -//#else +#if NETFX_CORE + MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => mi.GetParameters().Length == 2 && mi.GetParameters()[0].ParameterType == typeof(String) && mi.GetParameters()[1].ParameterType == typeof(NamedParameterOverloads)); +#else MethodInfo resolveMethod = typeof(TinyIoCContainer).GetMethod("Resolve", new Type[] { typeof(String), typeof(NamedParameterOverloads) }); -//#endif +#endif resolveMethod = resolveMethod.MakeGenericMethod(returnType); var resolveCall = Expression.Call(Expression.Constant(this), resolveMethod, name, Expression.Call(typeof(NamedParameterOverloads), "FromIDictionary", null, parameters)); @@ -3640,11 +3673,11 @@ private object GetLazyAutomaticFactoryRequest(Type type) #endif private object GetIEnumerableRequest(Type type) { -//#if NETFX_CORE -// var genericResolveAllMethod = this.GetType().GetGenericMethod("ResolveAll", type.GenericTypeArguments, new[] { typeof(bool) }); -//#else +#if NETFX_CORE + var genericResolveAllMethod = this.GetType().GetGenericMethod("ResolveAll", type.GenericTypeArguments, new[] { typeof(bool) }); +#else var genericResolveAllMethod = this.GetType().GetGenericMethod(BindingFlags.Public | BindingFlags.Instance, "ResolveAll", type.GetGenericArguments(), new[] { typeof(bool) }); -//#endif +#endif return genericResolveAllMethod.Invoke(this, new object[] { false }); } @@ -3661,11 +3694,11 @@ private bool CanConstruct(ConstructorInfo ctor, NamedParameterOverloads paramete var isParameterOverload = parameters.ContainsKey(parameter.Name); -//#if NETFX_CORE -// if (parameter.ParameterType.GetTypeInfo().IsPrimitive && !isParameterOverload) -//#else +#if NETFX_CORE + if (parameter.ParameterType.GetTypeInfo().IsPrimitive && !isParameterOverload) +#else if (parameter.ParameterType.IsPrimitive() && !isParameterOverload) -//#endif +#endif return false; if (!isParameterOverload && !CanResolveInternal(new TypeRegistration(parameter.ParameterType), NamedParameterOverloads.Default, options)) @@ -3680,11 +3713,11 @@ private ConstructorInfo GetBestConstructor(Type type, NamedParameterOverloads pa if (parameters == null) throw new ArgumentNullException("parameters"); -//#if NETFX_CORE -// if (type.GetTypeInfo().IsValueType) -//#else +#if NETFX_CORE + if (type.GetTypeInfo().IsValueType) +#else if (type.IsValueType()) -//#endif +#endif return null; // Get constructors in reverse order based on the number of parameters @@ -3702,11 +3735,11 @@ private ConstructorInfo GetBestConstructor(Type type, NamedParameterOverloads pa private IEnumerable GetTypeConstructors(Type type) { -//#if NETFX_CORE -// return type.GetTypeInfo().DeclaredConstructors.OrderByDescending(ctor => ctor.GetParameters().Count()); -//#else +#if NETFX_CORE + return type.GetTypeInfo().DeclaredConstructors.Where(ctor => ctor.IsPublic).OrderByDescending(ctor => ctor.GetParameters().Count()); +#else return type.GetConstructors().OrderByDescending(ctor => ctor.GetParameters().Count()); -//#endif +#endif } private object ConstructType(Type requestedType, Type implementationType, ResolveOptions options) @@ -3733,7 +3766,7 @@ private object ConstructType(Type requestedType, Type implementationType, Constr { if (requestedType == null || !requestedType.IsGenericType() || !requestedType.GetGenericArguments().Any()) throw new TinyIoCResolutionException(typeToConstruct); - + typeToConstruct = typeToConstruct.MakeGenericType(requestedType.GetGenericArguments()); } #endif @@ -3758,11 +3791,11 @@ private object ConstructType(Type requestedType, Type implementationType, Constr try { - args[parameterIndex] = parameters.ContainsKey(currentParam.Name) ? - parameters[currentParam.Name] : + args[parameterIndex] = parameters.ContainsKey(currentParam.Name) ? + parameters[currentParam.Name] : ResolveInternal( - new TypeRegistration(currentParam.ParameterType), - NamedParameterOverloads.Default, + new TypeRegistration(currentParam.ParameterType), + NamedParameterOverloads.Default, options); } catch (TinyIoCResolutionException ex) @@ -3793,7 +3826,7 @@ private object ConstructType(Type requestedType, Type implementationType, Constr } } -#if USE_OBJECT_CONSTRUCTOR +#if USE_OBJECT_CONSTRUCTOR private static ObjectConstructor CreateObjectConstructionDelegateWithCache(ConstructorInfo constructor) { ObjectConstructor objectConstructor; @@ -3828,15 +3861,15 @@ private static ObjectConstructor CreateObjectConstructionDelegateWithCache(Const private void BuildUpInternal(object input, ResolveOptions resolveOptions) { -//#if NETFX_CORE -// var properties = from property in input.GetType().GetTypeInfo().DeclaredProperties -// where (property.GetMethod != null) && (property.SetMethod != null) && !property.PropertyType.GetTypeInfo().IsValueType -// select property; -//#else +#if NETFX_CORE + var properties = from property in input.GetType().GetProperties() + where (property.GetMethod != null && property.GetMethod.IsPublic) && (property.SetMethod != null && property.SetMethod.IsPublic) && !property.PropertyType.GetTypeInfo().IsValueType + select property; +#else var properties = from property in input.GetType().GetProperties() where (property.GetGetMethod() != null) && (property.GetSetMethod() != null) && !property.PropertyType.IsValueType() select property; -//#endif +#endif foreach (var property in properties) { @@ -3876,28 +3909,28 @@ private IEnumerable ResolveAllInternal(Type resolveType, bool includeUnn private static bool IsValidAssignment(Type registerType, Type registerImplementation) { -//#if NETFX_CORE -// var registerTypeDef = registerType.GetTypeInfo(); -// var registerImplementationDef = registerImplementation.GetTypeInfo(); - -// if (!registerTypeDef.IsGenericTypeDefinition) -// { -// if (!registerTypeDef.IsAssignableFrom(registerImplementationDef)) -// return false; -// } -// else -// { -// if (registerTypeDef.IsInterface()) -// { -// if (!registerImplementationDef.ImplementedInterfaces.Any(t => t.GetTypeInfo().Name == registerTypeDef.Name)) -// return false; -// } -// else if (registerTypeDef.IsAbstract() && registerImplementationDef.BaseType() != registerType) -// { -// return false; -// } -// } -//#else +#if NETFX_CORE + var registerTypeDef = registerType.GetTypeInfo(); + var registerImplementationDef = registerImplementation.GetTypeInfo(); + + if (!registerTypeDef.IsGenericTypeDefinition) + { + if (!registerTypeDef.IsAssignableFrom(registerImplementationDef)) + return false; + } + else + { + if (registerTypeDef.IsInterface) + { + if (!registerImplementationDef.ImplementedInterfaces.Any(t => t.GetTypeInfo().Name == registerTypeDef.Name)) + return false; + } + else if (registerTypeDef.IsAbstract && registerImplementationDef.BaseType != registerType) + { + return false; + } + } +#else if (!registerType.IsGenericTypeDefinition()) { if (!registerType.IsAssignableFrom(registerImplementation)) @@ -3907,7 +3940,7 @@ private static bool IsValidAssignment(Type registerType, Type registerImplementa { if (registerType.IsInterface()) { - if (!registerImplementation.FindInterfaces((t, o) => t.Name == registerType.Name, null).Any()) + if (registerImplementation.GetInterfaces().All(t => t.Name != registerType.Name)) return false; } else if (registerType.IsAbstract() && registerImplementation.BaseType() != registerType) @@ -3915,7 +3948,7 @@ private static bool IsValidAssignment(Type registerType, Type registerImplementa return false; } } -//#endif +#endif return true; } @@ -3949,7 +3982,7 @@ namespace System.Reflection #else public #endif - static class ReverseTypeExtender + static class ReverseTypeExtender { public static bool IsClass(this Type type) { @@ -4002,4 +4035,4 @@ public static Assembly Assembly(this Type type) } } } -#endif +#endif \ No newline at end of file From e63c44dd71a77ae2699c3f32e06f5b888341701e Mon Sep 17 00:00:00 2001 From: Mauro Da Silva Date: Thu, 29 Jan 2015 07:29:05 +0200 Subject: [PATCH 2/2] Fixed issue with GetProperties in Win 8.1/Wp8.1 PCL --- src/TinyIoC/TinyIoC.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/TinyIoC/TinyIoC.cs b/src/TinyIoC/TinyIoC.cs index f718d7e..39716ee 100644 --- a/src/TinyIoC/TinyIoC.cs +++ b/src/TinyIoC/TinyIoC.cs @@ -345,7 +345,9 @@ static TypeExtensions() /// Gets a generic method from a type given the method name, binding flags, generic types and parameter types /// /// Source type +#if !NETFX_CORE /// Binding flags +#endif /// Name of the method /// Generic types to use to make the method generic /// Method parameters @@ -3862,7 +3864,7 @@ private static ObjectConstructor CreateObjectConstructionDelegateWithCache(Const private void BuildUpInternal(object input, ResolveOptions resolveOptions) { #if NETFX_CORE - var properties = from property in input.GetType().GetProperties() + var properties = from property in input.GetType().GetTypeInfo().DeclaredProperties where (property.GetMethod != null && property.GetMethod.IsPublic) && (property.SetMethod != null && property.SetMethod.IsPublic) && !property.PropertyType.GetTypeInfo().IsValueType select property; #else