Skip to content

Instantly share code, notes, and snippets.

@stormoz
Created April 8, 2014 11:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stormoz/10112651 to your computer and use it in GitHub Desktop.
Save stormoz/10112651 to your computer and use it in GitHub Desktop.
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