Is it possible to register an interface in a registry, then "re-register" it to override the first registration?
I.E.:
For<ISomeInterface>().Use<SomeClass>();
For<ISomeInterface>().Use<SomeClassExtension>();
What I want here on runtime is that my object factory returns SomeClassExtension
when I ask for ISomeInterface
.
Thanks in advance!
Good news, I found out that yes. It all depends on the order that the registry rules are added to the object factory container. So if you are using multiple registry classes as I was doing, you need to find a way to give a priority to add them to the container.
In other words, instead of using the .LookForRegistries()
which gets all the Registry
classes in the wrong order, try to find all the Registry
files, set them in the order you want and add them manually to the object factory container:
ObjectFactory.Container.Configure(x => x.AddRegistry(registry));
That way, you have full control on what rules you want.
Hope it helps :)
I just wanted to add my solution to the problem when I needed to override some parts of a registry in my SpecFlow test.
I did find this thread pretty early in my search, but it didn´t really help me find the solution, so I hope it will help you.
My problem was that the "DataContext" in "StoreRegistry" (used by the application) use the "HybridHttpOrThreadLocalScoped" and I needed it to be "Transient" in my tests.
The code looked like this:
[Binding]
public class MySpecFlowContext
{
...
[BeforeFeature]
private static void InitializeObjectFactories()
{
ObjectFactory.Initialize(x =>
{
x.AddRegistry<StoreRegistry>();
x.AddRegistry<CommonRegistry>();
});
}
}
To override the scope setting you will need to explicitly set it in the registration. And the override needs to be below what is overridden
The working code looks like this:
[Binding]
public class MySpecFlowContext
{
...
[BeforeFeature]
private static void InitializeObjectFactories()
{
ObjectFactory.Initialize(x =>
{
x.AddRegistry<StoreRegistry>();
x.AddRegistry<CommonRegistry>();
x.AddRegistry<RegistryOverrideForTest>();
});
}
class RegistryOverrideForTest : Registry
{
public RegistryOverrideForTest()
{
//NOTE: type of scope is needed when overriding the registered classes/interfaces, when leaving it empty the scope will be what was registered originally, f ex "HybridHttpOrThreadLocalScoped" in my case.
For<DataContext>()
.Transient()
.Use<DataContext>()
.Ctor<string>("connection").Is(ConnectionBuilder.GetConnectionString());
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With