【问题标题】:How to Pass or Inject an Unknown Number of Objects in a Method Call如何在方法调用中传递或注入未知数量的对象
【发布时间】:2016-01-17 01:49:48
【问题描述】:

如何传递、注入或实例化一个或多个我只引用它的接口的对象实例?

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

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

【问题讨论】:

  • 您将传递从 IProvider 继承并提供实现的类的实例
  • @EhsanSajjad 是的,但我不知道我需要多少个提供程序,并且我需要为记录集中的每一行创建一个新实例。实现这一点的模式正在逃避我。
  • 为了更清楚起见,方法调用显示了 IProvider 提供者的参数 - 这可能不正确,但不确定如何在此方法中求解,我无法根据需要在此处新建提供者然后填充并添加到集合中。

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


【解决方案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;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 2016-02-15
    • 2015-05-24
    • 1970-01-01
    • 2012-05-16
    • 2023-03-12
    相关资源
    最近更新 更多