Reputation: 894
How do I pass, inject or instantiate one or more instance of an object that I only have a reference to it's interface?
I'm not sure if I'm asking this correctly, here is my simple pseudo code problem.
In this example, this is a data layer that has access to a reference to a project that contains the common interfaces, but not the concrete implementations. I would like to pass in (or inject) the List that will return a collection of one or more provider objects.
The problem is, I can't instantiate a new instance of a IProvider
item for each record in the set returned by the stored procedure because I only have reference to the IProvider
interface.
Would DI solve this? I still don't know how many instances of the Provider
item to pass in, if any at the time I call into this method.
I have a feeling this is a pattern problem more than anything, but I can't wrap my head around the correct solution.
public List<IProvider> GetProviders(List<IProvider> providers, IProvider provider)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Providers.usp_GetProviders";
SQLDatabase db = new SQLDatabase();
using(cmd.Connection = db.GetConnection())
{
cmd.Connection.Open();
SqlDataReader rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
// Internal private method called for each row
// needs a new instance of an IProvider
MapDbToEntity(rdr, provider);
providers.Add(provider);
}
}
return providers;
}
Upvotes: 0
Views: 147
Reputation: 894
I think the proper way to solve this is with a factory pattern.
The factory which implements an interface to create an object is injected into the lower data layer that doesn't know anything about the entities, only the interfaces.
I'm NOT a pattern expert by any means so I'm looking for confirmation - this does work however.
Keeping things simple:
namespace MyApplication.Common.Factory
{
public interface IFactory
{
IProvider GetProvider();
}
}
Then, in my business entity layer:
public class ProviderFactory : IFactory
{
public IProvider GetProvider()
{
return new Provider();
}
}
Which in turn allows me to call up and out to a factory to create an instance of an object which implements the IProvider interface:
public List<IProvider> GetProviders(List<IProvider> providers, IFactory factory)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Providers.usp_GetProviders";
SQLDatabase db = new SQLDatabase();
using(cmd.Connection = db.GetConnection())
{
cmd.Connection.Open();
SqlDataReader rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
IProvider provider = factory.GetProvider();
MapDbToEntity(rdr, provider);
providers.Add(provider);
}
}
return providers;
}
Upvotes: 1