如何在方法调用中传递或注入未知数量的对象

问题描述:

如何传递,注入或实例化一个对象的一个​​或多个实例,并只引用它的接口?如何在方法调用中传递或注入未知数量的对象

我不确定如果我正确地问这个,这是我的简单的伪代码问题。

在这个例子中,这是一个数据层,可以访问对包含公共接口的项目的引用,但不能访问具体的实现。我想传入(或注入)将返回一个或多个提供者对象集合的List。

问题是,我无法为存储过程返回的集合中的每条记录实例化一个IProvider项目的新实例,因为我只参考了IProvider接口。

DI会解决这个问题吗?我仍然不知道有多少个Provider项目要传入,如果有的话在我调用这个方法的时候。

我有一种感觉,这是一个模式问题比什么都重要,但我无法围绕正确的解决方案包裹我的头。

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; 
    } 
+0

你将传递类的实例继承来自IProvider并提供实现 –

+0

@EhsanSajjad是的,但我不知道我需要多少提供程序,我需要为记录集中的每一行创建一个新实例。完成这一模式正在逃避我。 – Richard

+0

为了更加清晰,方法调用显示了IProvider提供程序的参数 - 这可能不正确,但不知道如何在此方法内部解决此问题,我无法根据需要在此新建提供程序,然后填充并添加到集合中。 – Richard

我认为解决这个问题的正确方法是使用工厂模式。

实现接口来创建一个对象的工厂被注入到不知道任何关于实体的只有接口的较低数据层中。

我不是任何方式的模式专家,所以我正在寻找确认 - 这确实工作。

让事情简单:

namespace MyApplication.Common.Factory 
{ 
    public interface IFactory 
    { 
     IProvider GetProvider(); 
    } 
} 

然后,在我的业务实体层:

public class ProviderFactory : IFactory 
{ 
    public IProvider GetProvider() 
    { 
     return new Provider(); 
    } 

} 

这反过来又可以让我起来了调用一个工厂来创建一个实例实现IProvider接口的对象:

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; 
    }