I have a console demo app using StructureMap IoC container. The demo has all the interfaces and implementation all in one file in one project and the scanning registry looks like the following:
public class ConsoleRegistry : Registry
{
public ConsoleRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});
}
}
And the demo uses the convention ISomething
and Something
so StructureMap can automatically find an implementation for an interface.
Now, when I go to move this to a real project where there is a UI project and Business project. I keep the convention of ISomething
and Something
but I get the following error message when I try to run an integration test in my unit test project.
Message: Test method AbcCompany.Tests.IntegrationTestsForTasks.Get_something_test threw exception: StructureMap.StructureMapConfigurationException: No default Instance is registered and cannot be automatically determined for type 'AbcCompany.DomainLayer.ISomething'
There is no configuration specified for AbcCompany.DomainLayer.ISomething 1.) Container.GetInstance()
If I change the registry to the following it works:
class ScanningRegistry : Registry
{
public ScanningRegistry()
{
this.For<ISomething>().Use<Something>();
this.Policies.SetAllProperties(y => y.WithAnyTypeFromNamespaceContainingType<Something>());
}
}
However, I like that if I stay with standard naming convention StructureMap will find all my interfaces and implementation for me without having to specify them.
You are only scanning TheCallingAssembly
. When your application runs, the calling assembly is your application. When the test runner runs, the calling assembly is the test runner.
To make it reliable, you should manually specify each assembly:
Scan(scan =>
{
scan.Assembly(typeof(SomeTypeFromAssembly1).Assembly);
scan.Assembly(typeof(SomeTypeFromAssembly2).Assembly);
scan.WithDefaultConventions();
});
Or you should use one of the other methods in the scanning documentation to specify assemblies by directory name.