I have an interface that represents a table in a 3rd party API. Each instance provides the ability to search a single table using forward-only cursors:
public interface ITable
{
string TableName { get; }
ICursor Search(string whereClause);
}
I have written a wrapper class to handle searching an ITable and returning an enumerable instead (it's a little more complex than that in reality, but sufficient for showing my issue):
public interface ITableWrapper
{
IEnumerable<object> Search(string whereClause);
}
public class TableWrapper : ITableWrapper
{
private ITable _table;
public TableWrapper(ITable table)
{
_table = table;
}
public IEnumerable<Row> Search(string whereClause)
{
var cursor = _table.Search(whereClause);
while(cursor.Next())
{
yield return cursor.Row;
}
}
}
I then have several repository classes that should have a table wrapper injected:
public class Table1Repository
{
private ITableWrapper _table;
public Table1Reposiroty(ITableWrapper table)
{
_table = table;
}
//repository methods to actually do things
}
Since each table will have its own wrapper, and repositories need the correct table injecting, my thought was to use named bindings on the tables and wrappers so that ninject provides the correct instance. Thus the above class would have NamedAttribute applied to the constructor argument, and the binding would be as follows:
public void NinjectConfig(IKernel kernel, ITableProvider provider)
{
Bind<ITable>().ToMethod(ctx => provider.OpenTable("Table1")).Named("Table1").InSingletonScope();
Bind<ITableWrapper>().ToMethod(ctx => new TableWrapper(ctx.ContextPreservingGet<ITable>("Table1"))).Named("Table1Wrapper").InSingletonScope();
}
My questions are:
- Is there a cleaner way to express this binding? I was thinking maybe a way to bind ITableWrapper once and have a new instance returned for each named ITable, with the repository constructor parameter attribute picking the named ITable for which it wants the ITableWrapper.
- If the ITable should never be used by anything, and everything should always use ITableWrapper, is it ok (or even recommended) to bind just ITableWrapper and have that combine both ToMethod contents:
public void NinjectConfig(IKernel kernel, ITableProvider provider)
{
Bind<ITableWrapper>().ToMethod(ctx => new TableWrapper(provider.OpenTable("Table1"))).Named("Table1Wrapper").InSingletonScope();
}