I have an interface like
public interface IAddressProvider
{
string GetAddress(double lat, double long);
}
In my consuming class I want to cycle through the concrete providers until I get a result, like (simplified):
string address;
address = _cachedAddressProvider.GetAddress(lat, long);
if(address == null)
address = _localDbAddressProvider.GetAddress(lat, long);
if(address = null)
address = _externalAddressProvider.GetAddress(lat, long);
return address ?? "no address found";
I can then mock each provider for unit testing, setting null as the return value to appropriately test all code paths.
How would i inject the interface into my consuming class (preferably using StructureMap) so that each concrete implementation is correctly resolved?
Could you not just use
container.GetAllInstances
?, like so:Edit:
I see what you mean now. If you're using StructureMap 2.x then I would recommend looking at the
Conditionally
clause. However this has been removed in version 3 in favour of creating your own builder class that should be responsible for returning the correct instance.For example:
The fact that you have multiple address-providers is not something the calling code should have to deal with. So create a specific provider-proxy to handle with these multiple providers.
Like this.
I'm not familiar with StructureMap specifically but there are two solutions as far as I can see.
1) Named Instances - You register your 3 concrete implementations of
IAddressProvider
with StructureMap as named instances, and then configure the constructor parameters.StructureMap named instance configuration: http://docs.structuremap.net/InstanceExpression.htm#section14
Using named parameters in constructor injection: http://lookonmyworks.co.uk/2011/10/04/using-named-instances-as-constructor-arguments/
2) More Interfaces - Assuming that there's only ever going to be a few
IAddressProvider
implementations and not hundreds you could create anICachedAddressProvider
,ILocalDbAddressProvider
, andIExternalAddressProvider
that implementIAddressProvider
and then use those in the constructor of the consuming class.If there are likely to be significantly more concrete
IAddressProvider
implementations then you might want to look into something along the lines of an Abstract Factory instead.