внедрение зависимостей и ado.net и asp.net MVC - PullRequest
0 голосов
/ 04 июня 2018

Я изучал DI и что-то реализовал, но я хочу быть уверен, что моя реализация соответствует или не соответствует правилам DI:

интерфейс с сигнатурой:

 public interface IDashboardRepository
{

   public object sumAndAVG(string regionalManager, string dtFrom, string dtTo);
}

класс для реализации сигнатуры интерфейса:

        public class DashboardRepo:IDashboardRepository
        {

            private string cn = System.Configuration.ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
            NpgsqlConnection con = null;
            public object sumAndAVG(string regionalManager, string dtFrom, string dtTo)
            {
                DataTable dt_sumProAval = new DataTable();
                NpgsqlDataAdapter SumOfProduction = new NpgsqlDataAdapter(@"TheSQL is here since its long not part of the topic i removed it", cn);
                SumOfProduction.Fill(dt_production);
                var sumAndAvail = (from DataRow dr in dt_production.Rows
                                   select new AverageSumViewModel

                                   {
                                      avg = Convert.ToDouble(dr["avalability"] == DBNull.Value ? 0.0 : dr["avalability"]),
                                   }).ToList();

                return sumAndAvail;
            }
        }

В конце в моем контроллере я использую его как:

  _idashboard.sumAndAVG( regionalManager,  dtFrom,  dtTo);

пожалуйста, скажите мне, если я в правильном направлении

Ответы [ 4 ]

0 голосов
/ 04 июня 2018

Вот что я понимаю о внедрении зависимости и инверсии управления:

"Внедрение зависимостей, проще говоря, является реализацией шаблона IOC. Вместо тесной связи зависимости одного объекта с другим с помощью ключевого слова 'new', передайте его как внешнюю зависимость, используяКонструктор / свойство / метод внедрения ".

Подробнее см. здесь - https://martinfowler.com/articles/injection.html

Что касается вашего вопроса, вы реализовали шаблон, используя внедрение конструктора в свой код

Интерфейс :

public interface IDashboardRepository
{

   public object sumAndAVG(string regionalManager, string dtFrom, string dtTo);
}

Реализация:

public class DashboardRepo:IDashboardRepository
{
    //Simplified for understanding
}

Использование IDashboardRepository в другом объекте:

public class DashboradHandeler
{
  public  IDashboardRepository _idashboard;

  public DashboradHandeler(IDashboardRepository _idashboard)
  {

      this._idashboard = _idashboard;
  }
}

Использование DashboradHandeler в другом объекте (вашем контроллере):

DashboradHandeler dashboard = new DashboradHandeler(new DashboardRepo());
        dashboard._idashboard.sumAndAVG(regionalManager,dtFrom,dtTo);

Наблюдения :

  1. Внедрение IDashboardRepository в DashboradHandeler слабо связано.Он переворачивает ответственность за создание объекта IDashboardRepository класса от DashboradHandeler на вызывающую сторону.В вашем случае это DashboradHandeler .

    Однако экземпляр класса DashboradHandeler можно изменить.Вместо того, чтобы делать: DashboradHandeler dashboard = new DashboradHandeler(new DashboardRepo());, вы можете инвертировать создание объекта во внешний контейнер, такой как Autofac, Ninject.Старайтесь не использовать ключевое слово 'new' везде, где это применимо.

  2. Соглашения об именах могут быть улучшены.Нотация '_' используется главным образом с частными свойствами.Используйте один из них, а не оба:

Ваш код :

    public class DashboradHandeler
    {
      public  IDashboardRepository _idashboard;

      public DashboradHandeler(IDashboardRepository _idashboard)
      {
          this._idashboard = _idashboard;
      }
    }

С нотацией '_' :

public class DashboradHandeler
    {
      private IDashboardRepository _idashboard;

      public DashboradHandeler(IDashboardRepository idashboard)
      {

          _idashboard = idashboard;
      }
    }

Без обозначения '_' :

public class DashboradHandeler
    {
      private IDashboardRepository idashboard;

      public DashboradHandeler(IDashboardRepository idashboard)
      {

          this.idashboard = idashboard;
      }
    }

Это несколько моментов, о которых я могу подумать прямо сейчас.

0 голосов
/ 04 июня 2018

Вы близки, но думаете, что хотите настроить это примерно так:

public class DashboradHandeler
{
  private readonly IDashboardRepository _idashboard;

  public DashboradHandeler(IDashboardRepository idashboard)
  {

      this._idashboard = idashboard;
  }

}

Тогда используйте это как-то так.Я оборачиваю метод inject class здесь для иллюстрации, а не потому, что это требуется.Это не совсем идеальный способ сделать DI, но должен помочь вам.

DashboradHandeler dashboard = new DashboradHandeler(new DashboardRepo());
dashboard.sumAndAVG(regionalManager,dtFrom,dtTo);

// This is in your DashboradHandeler class
public object sumAndAVG(string regionalManager, string dtFrom, string dtTo)
  {
     _idashboard(sumAndAVG(regionalManager,dtFrom,dtTo));
  }
0 голосов
/ 04 июня 2018

См. Этот пример:

ваш контроллер

public IGetService iGetService { get; set; }

public HomeController() { }

public HomeController(IGetService iGetService)
{
     this.iGetService = iGetService;
}

Теперь, если какое-либо действие в вашем контроллере хочет вызвать метод из этого интерфейса, вы просто делаете что-то вроде следующего:

public void MyAction()
{
    var myVar = iGetService.GetAllFromDataBase();
}
0 голосов
/ 04 июня 2018

На мой взгляд, вам не нужен ваш DashboradHandeler - вы можете внедрить интерфейс в конкретный контроллер в его собственном конструкторе.Кроме того, вы используете new, а это не то, что DI хочет от вас;)

Для этого у вас всегда есть нужные интерфейсы только внутри вашего контроллера.

Подумайте о десятках /сотни контроллеров, использующих DashboradHandeler: вы не сможете узнать все интерфейсы, используемые в DashboradHandeler.И все ваши контроллеры будут сильно зависеть от этого класса ...

...