I have an interface ITradingApi
like so:
public interface ITradingApi
{
IOrder CreateOrder(...);
IEnumerable<Symbol> GetAllSymbols();
// ...
}
This is meant to be a facade for the different APIs of the vendors of trading software. My view model has a dependency on this trading API in its constructor:
public class MainViewModel
{
public MainViewModel(ITradingApi tradingApi) { /* ... */ }
// ...
}
I use Ninject as an IoC container, so I will create an instance of my view model like this:
var vm = kernel.Get<MainViewModel>();
Now, my problem:
The implementation of ITradingApi
might need additional parameters to work.
Example:
- One vendors API uses TCP/IP internally, so I need a hostname and a port.
- Another vendor uses a COM object. Here I don't need any info.
- A third vendor needs username and password of the account.
In the spirit of not allowing incomplete objects, I added these as parameters to the constructors of the concrete implementations.
Now, I am not sure, how this would work. Clearly, these additional parameters do not belong into the interface, because they are specific to each implementation.
On the other hand, these additional parameters need to be entered by the end-user and then passed to the implementation of ITradingApi
, meaning that the user of ITradingApi
needs intimate knowledge about the concrete implementation.
How to solve this dilemma?
UPDATE:
One approach could be to create an ITradingApiProvider
that exposes a list of required parameters. The View could automatically create an input form for these parameters that is databound to the parameters in ITradingApiProvider
. Now, when an ITradingApi
instance is requested from the provider, it can make use of these parameters to create an instance of the concrete implementation. Clearly the implementation of ITradingApiProvider
and ITradingApi
are tightly coupled, but I think that is not a problem as long as each implementation of ITradingApi
comes with a corresponding implementation of ITradingApiProvider
.