Как можно избежать создания экземпляра с использованием нового ключевого слова? - PullRequest
0 голосов
/ 20 сентября 2019

Я просто студент, пытающийся поправиться.Сейчас я разрабатываю приложение, которое читает из Excel.Для этого у меня есть класс DataReader.

public class DataReader : IDataReader
{
    Workbook workbook;
    public DataReader()
    {
        workbook = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveWorkbook);
    }


    public Worksheet GetWorksheetByName(string name)
    {
        Worksheet sheet = (Worksheet)Globals.Factory.GetVstoObject(workbook.Worksheets[name]);
        return sheet;
    }


}

и этот класс я звоню из разных мест.Вот пример того, как я создаю его экземпляр в одном классе

    public List<ConfigModel> Instances { get; set; }
    public IDataReader dr;
    public Worksheet sheet;
    public PopulateConfigModel()
    {
        Instances = new List<ConfigModel>();
        dr = new DataReader();
        sheet = dr.GetWorksheetByName("Your_Data_Sheet");
    }

, а вот еще один пример

public class RangeCreator : IRangeCreator
{
    IDataReader dr;
    Worksheet sheet;
    public Xcl.Range GetDestinationRange()
    {
        dr = new DataReader();
        DataHandler dh = new DataHandler();
        sheet = dr.GetWorksheetByName("Your_CSV_File");
        string range = "A" + ((dh.GetLastRow(sheet) + 1) + ":A" + (dh.GetLastRow(sheet) + 3));
        Xcl.Range rng = sheet.Range[range];
        return rng;
    }

Обратите внимание, что я также вызываю новый DataHandler в этом методе.

Я не думаю, что это хорошая практика, но у меня нет лучшего решения, так как же обходится создание этого класса в нескольких местах?Я думаю, я мог бы пойти с DI, но тогда мне пришлось бы DI и DataReader и DataHandler в нескольких местах, и я не уверен, что это лучшее решение.

Не знаю,

ОБНОВЛЕНИЕ:

public void BeginProcess()
    {
        dh = new DataHandler1();
        //Returns a List<List<int>> with all used boxsizes {{ 5,1 }, { 15, 3 }} & startCell for each of those boxes eg {{ "B6" }, { "B27" }}
        ListHandler lh = dh.GetListHandlerData();
        //Holds a list of instances
        IPopulateConfigModel pc = new PopulateConfigModel();
        //For hver boks vi har i dokumentet
        for (int i = 0; i < lh.cellAddresses.Count; i++)
        {
            //Adds list of instances to list of models 
            models.Add(pc.PopulateInstances(lh.boxSizes[i], lh.cellAddresses[i]));
        }

        ConfigModelHandler cm = new ConfigModelHandler(models);

        cm.StartModelProcessing(dh);
    }

Теперь я вставляю DataHandler в качестве параметра в StartModelProcessing

public void StartModelProcessing(IDataHandler1 dh)
    {
        IFileSaver fileSaver = new FileSaver();
        Worksheet sheet = dr.GetWorksheetByName("Your_CSV_File");
        //Each model - each with their own sheet
        for (int i = 0; i < models.Count; i++)
        {
            //Contains all instances of an object
            string[][] instances = new string[models[i].Count][];

            string filePath = Directory.GetCurrentDirectory() + @"\" + models[i][0].TemplateName + ".csv";
            //Clears our sheet so we're ready for a new set of instances 
            dh.ClearWorksheet(sheet);
            //Each instance - sharing their worksheet
            for (int j = 0; j < models[i].Count; j++)
            {
                Xcl.Range rngPopulated = GetPopulatedSourceRange(models[i][j]);

                string[] rows = new string[3];

                //Get our data from our populated range to our string array. It's in the form of:
                /*
                 * one string array = one instance
                 * rows[0] = TEMPLATE
                 * rows[1] = Properties
                 * rows[2] = Variables
                 */
                for (int ti = 0; ti < rngPopulated.Rows.Count; ti++)
                {
                    for (int tu = 1; tu < rngPopulated.Rows[ti + 1].Cells.Count; tu++)
                    {
                        rows[ti] += rngPopulated.Rows[ti + 1].Cells[tu].Value2 + ",";
                    }
                }
                instances[j] = rows;
                Xcl.Range testRange = rangeGetter.GetDestinationRange(dh);
                //We aint using this sheet - it's only if the user will change and save it manually but only last instance of last document is showing
                di.PopulateCsvFile(rows, testRange);

            }

            fileSaver.SaveFile(instances, filePath);
        }
    }

икак вы можете видеть, добавив его снова в качестве параметра в методе rangeGetter.GetDestRange.

и вот метод

public Xcl.Range GetDestinationRange(IDataHandler1 dh)
    {
        dr = new DataReader1();
        sheet = dr.GetWorksheetByName("Your_CSV_File");
        string range = "A" + ((dh.GetLastRow(sheet) + 1) + ":A" + (dh.GetLastRow(sheet) + 3));
        Xcl.Range rng = sheet.Range[range];
        return rng;
    }

Ответы [ 2 ]

0 голосов
/ 20 сентября 2019

пожалуйста, поймите

это очень "код sudo", и здесь просто неграмотно, что важнее, чем попытка избежать "нового", это то, как код потребляется другим кодом.

Ваш код трудно комментировать, так как всю картинку нельзя увидеть ... (что к чему)

Если вы не понимаете, что я пытаюсь показать ниже, тогда я удалю, но еслиу тебя тогда отлично получается!Я опустил много кода, чтобы его было легче понять ... ну, надеюсь,

class Main 
{

    DataReader1 _dr;
    DataHandler _dh;
    public Main()
    {
        _dr = new DataReader1();
        _dh = new DataHandler();
        BeginProcess();
    }

    public void BeginProcess()
    {
        //...code ommitted
        ConfigModelHandler cm = new ConfigModelHandler(models);
        cm.StartModelProcessing();
    }

    public void StartModelProcessing(IDataHandler1 dh)
    {   
        Worksheet sheet = dr.GetWorksheetByName("Your_CSV_File");
        //Each model - each with their own sheet
        for (int i = 0; i < models.Count; i++)
        {
                for (int j = 0; j < models[i].Count; j++)
            {
                Worksheet sheetInner = dr.GetWorksheetByName("Your_CSV_File");
                //do stuff with sheet
                var range = GetDestinationRange(sheetInner);
            }

            fileSaver.SaveFile(instances, filePath);
        }
    }

    public Xcl.Range GetDestinationRange(Worksheet sheet)
    {
        var lastRow = dh.GetLastRow(sheet);
        string range = "A" + ((lastRow  + 1) + ":A" + (lastRow + 3));
        Xcl.Range rng = sheet.Range[range];
        return rng;
    }
}
0 голосов
/ 20 сентября 2019

Одним из способов является создание класса DataReader в виде одноэлементного шаблона, например:

class DataReader
{       
     private static DataReader instance = null;
     private DataReader()
     {
       //workbook goes here...
     }

     public static DataReader Instance
     {
         get
         {
             if (instance == null)                   
                  instance = new DataReader();               
               return instance;
          }
      }     
}

И затем вы можете вызвать метод следующим образом:

...
sheet = DataReader.Instance.GetWorksheetByName("Your_CSV_File");

Здесь вам не нужно использовать new ключевое слово каждый раз

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...