We're using Unity as our dependency injection framework.
I want to create an acceptance test and need an instance of DossierService.
Unfortunately I get the following exception:
BoDi.ObjectContainerException: 'Interface cannot be resolved [...]'
[Binding]
public class DossierServiceSteps : BaseSteps
{
private IDossierService dossierService;
public DossierServiceSteps(IDossierService dossierService)
{
this.dossierService = dossierService;
}
}
Thanks in advance
Edit:
I've tried using SpecFlow.Unity
like so:
public static class TestDependencies
{
[ScenarioDependencies]
public static IUnityContainer CreateContainer()
{
var container = UnityConfig.GetConfiguredContainer();
container.RegisterTypes(typeof(TestDependencies).Assembly.GetTypes().Where(t => Attribute.IsDefined(t, typeof(BindingAttribute))),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled);
return container;
}
}
In UnityConfig
the types are correctly registered
container.RegisterType<IDossierService, DossierService>(new InjectionConstructor(typeof(IDataService), typeof(IDossierRepository), typeof(IDbContext), true));
But I still get the same exception. When I put a breakpoint at the start of the CreateContainer()
method of TestDependencies
it doesn't break...
We solved this problem by implementing SpecFlow RuntimePlugin. In our case it was Castle.Windsor, but principle is the same. First you define the plugin which override default SpecFlow Instance Resolver:
public class CastleWindsorPlugin : IRuntimePlugin
{
public void Initialize(RuntimePluginEvents runtimePluginEvents, RuntimePluginParameters runtimePluginParameters)
{
runtimePluginEvents.CustomizeScenarioDependencies += (sender, args) =>
{
args.ObjectContainer.RegisterTypeAs<CastleWindsorBindingInstanceResolver, IBindingInstanceResolver>();
};
}
}
Where in CastleWindsorBindingInstanceResolver
we needed to implement single method: object ResolveBindingInstance(Type bindingType, IObjectContainer scenarioContainer);
. This class contains container and resolution (in your case instance of IUnityContainer
. I recommend to inject to the container instance of self, so that you could inject the instance of IUnityContainer
to SpecFlow binding classes)
This plugin needs to be in separate assembly and you load that to your test project like adjusting app.config
like this:
<specFlow>
<plugins>
<add name="PluginAssemblyName" path="." type="Runtime" />
</plugins>
...
</specFlow>