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

时间:2015-10-18 19:18:19

标签: c# interface dependency-injection inversion-of-control

如何传递,注入或实例化一个或多个对象实例,我只引用它的界面?

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

在此示例中,这是一个数据层,可以访问包含公共接口的项目的引用,但不能访问具体实现。我想传入(或注入)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;
    }

1 个答案:

答案 0 :(得分:1)

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

实现创建对象的接口的工厂被注入到较低的数据层,该数据层对实体,只有接口知之甚少。

我不是模式专家,所以我正在寻找确认 - 但这确实有效。

保持简单:

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