Created
April 8, 2014 11:38
-
-
Save stormoz/10112651 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace FunqConventionTests | |
{ | |
using Funq;//Install-Package Funq | |
using Microsoft.VisualStudio.TestTools.UnitTesting; | |
using MyNamespace; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
[TestClass] | |
public class FuncTests | |
{ | |
private Container _container; | |
[TestInitialize] | |
public void BeforeEachTest() | |
{ | |
_container = new Container(); | |
} | |
[TestMethod] | |
public void IocCanResolveTypeForWhichMappingConfigured() | |
{ | |
_container.Register<IService>(x => new Service(null)); | |
var instance = _container.Resolve<IService>(); | |
Assert.IsInstanceOfType(instance, typeof(Service)); | |
} | |
[TestMethod] | |
public void EnsureThatForAllTypesOfNamespaceAllCtorParamsAreInterfaces_WhenTrue_ShouldPass() | |
{ | |
var namespaceName = "MyNamespace"; | |
AssertConstructorParametersAllInterfaces(namespaceName); | |
} | |
[TestMethod] | |
[ExpectedException(typeof(NotSupportedException))] | |
public void EnsureThatForAllTypesOfNamespaceAllCtorParamsAreInterfaces_WhenFalse_ShouldTrow() | |
{ | |
var namespaceName = "MyNamespace2"; | |
AssertConstructorParametersAllInterfaces(namespaceName); | |
} | |
[TestMethod] | |
public void EnsureThatIocMappingSetForInterfacesOnly_WhenTrue_ShouldPass() | |
{ | |
_container.Register<IService>(x => new Service(null)); | |
AssertFunqMappingSetForInterfacesOnly(); | |
} | |
[TestMethod] | |
[ExpectedException(typeof(NotSupportedException))] | |
public void EnsureThatIocMappingSetForInterfacesOnly_WhenFalse_ShouldThow() | |
{ | |
_container.Register<Service>(x => new Service(null)); | |
AssertFunqMappingSetForInterfacesOnly(); | |
} | |
private void AssertConstructorParametersAllInterfaces(string namespaceName) | |
{ | |
var typelist = GetTypesInNamespace(Assembly.GetExecutingAssembly(), namespaceName); | |
foreach (var type in typelist) | |
{ | |
if (type.IsInterface) | |
continue; | |
var ctors = type.GetConstructors(); | |
if (ctors.Length > 1) | |
throw new NotSupportedException(); | |
var ctor = ctors[0]; | |
if (ctor.GetParameters().Any(param => !param.ParameterType.IsInterface)) | |
{ | |
throw new NotSupportedException(); | |
} | |
} | |
} | |
private void AssertFunqMappingSetForInterfacesOnly() | |
{ | |
dynamic services = GetFieldOrPropertyValue(typeof(Container), _container, "services"); | |
foreach (dynamic service in services) | |
{ | |
var value = GetFieldOrPropertyValue(service.GetType(), service, "Key"); | |
var factoryType = GetFieldOrPropertyValue(value.GetType(), value, "FactoryType"); | |
var type = (Type) factoryType.UnderlyingSystemType.UnderlyingSystemType.GenericTypeArguments[1]; | |
if (type.IsInterface || type == typeof (Container)) | |
continue; | |
throw new NotSupportedException("Only mapping to interfaces are allowed!"); | |
} | |
} | |
private IEnumerable<Type> GetTypesInNamespace(Assembly assembly, params string[] nameSpaces) | |
{ | |
return assembly.GetTypes().Where(t => nameSpaces.Any(ns=>ns.Equals(t.Namespace, StringComparison.OrdinalIgnoreCase))).ToArray(); | |
} | |
private object GetFieldOrPropertyValue(Type type, object instance, string fieldName) | |
{ | |
var bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.DeclaredOnly | BindingFlags.InvokeMethod | BindingFlags.Static; | |
var field = type.GetField(fieldName, bindFlags); | |
return field != null ? field.GetValue(instance) : type.GetProperty(fieldName).GetValue((object)instance, null); | |
} | |
} | |
} | |
namespace MyNamespace | |
{ | |
public interface IDependency | |
{ } | |
public class Dependency : IDependency | |
{ } | |
public interface IService | |
{ } | |
public class Service : IService | |
{ | |
public Service(IDependency dep) | |
{ } | |
} | |
} | |
namespace MyNamespace2 | |
{ | |
public interface IDependency | |
{ } | |
public class Dependency : IDependency | |
{ } | |
public interface IService | |
{ } | |
public class Service : IService | |
{ | |
//Note: dependency is concrete type | |
public Service(Dependency dep) | |
{ } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment