The Decorator pattern demonstrates how we can extend the behaviour of a component without modifying the underlying implementation. But this means I have two components that implement the same interface. Is there a way to Register these in AutoFixture so that I can still refer to my component polymorphically as its interface?
A code example my help with my meaning. Let's assume I want to decorate an IComponent with a LoggingComponent
interface IComponent
{
void DoStuff();
}
class Component : IComponent
{
public void DoStuff()
{
// Do something amazing!
}
}
class LoggingComponent : IComponent
{
private readonly IComponent _Component;
public LoggingComponent(IComponent Component)
{
_Component = Component;
}
public void DoStuff()
{
Console.WriteLine("Calling DoStuff()");
_Component.DoStuff();
}
}
How would I go about both registering LoggingComponent as an IComponent and creating a LoggingComponent without a circular dependency?
What's the alternative to registering LoggingComponent this way:
_fixture.Register<IComponent>(_fixture.Create<LoggingComponent>);
And then trying to create an instance of IComponent using this code:
var Component = _fixture.Create<IComponent>();
Which obviously results in this ObjectCreationException exception being thrown:
AutoFixture was unable to create an instance of type Ploeh.AutoFixture.Kernel.SeededRequest because the traversed object graph contains a circular reference. Information about the circular path follows below. This is the correct behavior when a Fixture is equipped with a ThrowingRecursionBehavior, which is the default. This ensures that you are being made aware of circular references in your code. Your first reaction should be to redesign your API in order to get rid of all circular references. However, if this is not possible (most likely because parts or all of the API is delivered by a third party), you can replace this default behavior with a different behavior: on the Fixture instance, remove the ThrowingRecursionBehavior from Fixture.Behaviors, and instead add an instance of OmitOnRecursionBehavior.