Skip to content

Commit

Permalink
Switched from TinyIoc to Autofac and added a new mechanism for object…
Browse files Browse the repository at this point in the history
… mothers
  • Loading branch information
dennisdoomen committed Feb 6, 2019
1 parent 63e5661 commit f7939b2
Show file tree
Hide file tree
Showing 26 changed files with 451 additions and 425 deletions.
2 changes: 1 addition & 1 deletion Src/Chill/AutoMockingContainerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Chill
/// <summary>
/// Extensions to the Chill container
/// </summary>
internal static class AutoMockingContainerExtensions
internal static class ChillContainerExtensions
{
/// <summary>
/// chill keeps a list of registered items in memory. This method adds a value to that list
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using Autofac;
using System;
using Autofac;
using Autofac.Builder;
using Autofac.Core;

namespace Chill.Autofac
namespace Chill
{
internal class AutofacChillContainer : IChillContainer
{
Expand Down Expand Up @@ -42,7 +43,8 @@ public void Dispose()

public void RegisterType<T>() where T : class
{
Container.ComponentRegistry.Register(RegistrationBuilder.ForType<T>().InstancePerLifetimeScope().CreateRegistration());
Container.ComponentRegistry.Register(RegistrationBuilder.ForType<T>().InstancePerLifetimeScope()
.CreateRegistration());
}

public T Get<T>(string key = null) where T : class
Expand All @@ -64,7 +66,6 @@ public T Set<T>(T valueToSet, string key = null) where T : class
Container.ComponentRegistry
.Register(RegistrationBuilder.ForDelegate((c, p) => valueToSet)
.InstancePerLifetimeScope().CreateRegistration());

}
else
{
Expand All @@ -73,33 +74,13 @@ public T Set<T>(T valueToSet, string key = null) where T : class
.As(new KeyedService(key, typeof(T)))
.InstancePerLifetimeScope().CreateRegistration());
}
return Get<T>(key);
}


public bool IsRegistered<T>()where T : class
{
return IsRegistered(typeof(T));
return Get<T>(key);
}

public bool IsRegistered(System.Type type)
public bool IsRegistered(Type type)
{
return Container.IsRegistered(type);
}
}

public static class TestBaseExtensions
{
/// <summary>
/// Explicitly register a type so that it will be created from the chill container from now on.
///
/// This is handy if you wish to create a concrete type from a container that typically doesn't allow
/// you to do so. (such as autofac)
/// </summary>
/// <typeparam name="T"></typeparam>
public static void RegisterConcreteType<T>(this TestBase testBase) where T : class
{
testBase.Container.RegisterType<T>();
}
}
}
25 changes: 6 additions & 19 deletions Src/Chill/DefaultChillContainerInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,22 @@ namespace Chill
/// <summary>
/// Default implementation of a Chill Test Initializer. This implementation will create
/// container of TContainerType and wrap it in a
/// <see cref="AutoMockingContainerExtensions"/>. This way, you can create automatic mothers
/// <see cref="ChillContainerExtensions"/>. This way, you can create automatic mothers
/// for your classes.
/// </summary>
/// <typeparam name="TContainerType">The type of the container to create. </typeparam>
public class DefaultChillContainerInitializer<TContainerType> : IChillContainerInitializer
where TContainerType : IChillContainer, new()
{

private AutoMotherContainerDecorator _container;

/// <summary>
/// Find all relevant assemblies that should be scanned (for example for AutoMothers).
/// </summary>
/// <param name="test">The test object to use.</param>
/// <returns>List of assemblies to scan.</returns>
public virtual IEnumerable<Assembly> FindRelevantAssemblies(TestBase test)
{
yield return test.GetType().GetTypeInfo().Assembly;

}
private IChillContainer container;

/// <summary>
/// Build the Chill Container. This container will be wrapped in a AutoMotherContainerDecorator.
/// </summary>
/// <returns></returns>
public virtual IChillContainer BuildChillContainer(TestBase testBase)
{
return _container = new AutoMotherContainerDecorator(testBase.BuildContainer(typeof(TContainerType)));
return container = Activator.CreateInstance<TContainerType>();
}

/// <summary>
Expand All @@ -45,11 +33,10 @@ public virtual IChillContainer BuildChillContainer(TestBase testBase)
/// <param name="test"></param>
public virtual void InitializeContainer(TestBase test)
{
if (_container != null)
if (container != null)
{
_container.RegisterType<Dictionary<Type, object>>();
_container.RegisterType<Dictionary<Tuple<Type, string>, object>>();
_container.LoadAutoMothers(FindRelevantAssemblies(test));
container.RegisterType<Dictionary<Type, object>>();
container.RegisterType<Dictionary<Tuple<Type, string>, object>>();
}
}
}
Expand Down
13 changes: 10 additions & 3 deletions Src/Chill/GivenWhenThen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ protected TResult Result
/// </summary>
public Func<TResult> WhenAction
{
get { return whenAction; }
get
{
return () =>
{
result = whenAction();
return result;
};
}
set
{
EnsureContainer();
Expand All @@ -56,16 +63,16 @@ protected void When(Func<TResult> whenFunc, bool? deferredExecution = null)
{
DeferredExecution = deferredExecution ?? DeferredExecution;
EnsureContainer();
if (WhenAction != null)
if (whenAction != null)
{
throw new InvalidOperationException("When already defined");
}

whenAction = whenFunc;
if (!this.DeferredExecution)
{
EnsureTestTriggered(false);
}

}

internal override void TriggerTest(bool expectExceptions)
Expand Down
29 changes: 0 additions & 29 deletions Src/Chill/IAutoMother.cs

This file was deleted.

9 changes: 1 addition & 8 deletions Src/Chill/IChillContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace Chill
/// </remarks>
public interface IChillContainer : IDisposable
{

/// <summary>
/// Registers a type to the container. For example, autofac cannot create objects until you register them
/// This allows containers like autofac to create the object.
Expand All @@ -36,18 +35,12 @@ public interface IChillContainer : IDisposable
/// <returns></returns>
T Set<T>(T valueToSet, string key = null) where T : class;

/// <summary>
/// Determines whether an instance of this type is registered.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
bool IsRegistered<T>() where T : class;

/// <summary>
/// Determines whether an instance of this type is registered.
/// </summary>
/// <param name="type">The type.</param>
/// <returns></returns>
bool IsRegistered(Type type);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ namespace Chill
/// </summary>
public interface IChillContainerInitializer
{
/// <summary>
/// Finds the relevant assemblies.
/// </summary>
/// <param name="test">The test.</param>
/// <returns></returns>
IEnumerable<Assembly> FindRelevantAssemblies(TestBase test);

/// <summary>
/// Builds the chill container.
/// </summary>
Expand Down
42 changes: 42 additions & 0 deletions Src/Chill/IObjectMother.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;

namespace Chill
{
/// <summary>
/// Represents an object mother that is automatically discovered by Chill to construct test objects
/// whenever you request one using <see cref="TestBase.The{T}"/>.
/// </summary>
public interface IObjectMother
{
/// <summary>
/// Gets a value indicating whether this object mother is supposed to be used as a fallback in a case
/// a more specific object mother is not available.
/// </summary>
bool IsFallback { get; }

/// <summary>
/// Gets a value indicating whether this object mother can build objects of the specified <paramref name="type"/>.
/// </summary>
bool Applies(Type type);

/// <summary>
/// Creates a test instance that is of, inherits from or implements the specified <paramref name="type"/>.
/// </summary>
/// <remarks>
/// The implementation can use the provided <paramref name="objectResolver"/> to get other objects
/// from either Chill's configured container or another object mother.
/// </remarks>
object Create(Type type, IChillObjectResolver objectResolver);
}

public interface IChillObjectResolver
{
/// <summary>
/// Gets a value of the specified type from the container, optionally registered under a key.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">The key.</param>
/// <returns></returns>
T Get<T>(string key = null) where T : class;
}
}
29 changes: 9 additions & 20 deletions Src/Chill/ObjectMother.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,31 @@
namespace Chill
{
/// <summary>
/// Base class for object mothers that construct a single object.
/// Convenience class for object mothers that construct a single type of object.
/// </summary>
/// <typeparam name="TTarget">The type of the target.</typeparam>
public abstract class ObjectMother<TTarget> : IAutoMother
public abstract class ObjectMother<TTarget> : IObjectMother
{
/// <summary>
/// Checks if the specified type applies.
/// </summary>
/// <param name="type">The type.</param>
/// <returns></returns>
public bool IsFallback => false;

public bool Applies(Type type)
{
return type == typeof(TTarget);
}

/// <summary>
/// Creates the specified type using the specified container
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="container">The container.</param>
/// <returns></returns>
/// <exception cref="System.InvalidOperationException">ServerMother only applies to </exception>
public T Create<T>(IChillContainer container)
public object Create(Type type, IChillObjectResolver container)
{
if (!Applies(typeof(T)))
if (!Applies(type))
{
throw new InvalidOperationException("ServerMother only applies to ");
throw new InvalidOperationException("ObjectMother only applies to ");
}
return (T)(object)Create();

return Create();
}

/// <summary>
/// Creates an instance of the requested type.
/// </summary>
/// <returns></returns>
protected abstract TTarget Create();

}
}
Loading

0 comments on commit f7939b2

Please sign in to comment.