А можно ли запретить "обычный" вызов метода?
От: Artem Korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 01.08.17 17:27
Оценка:
Есть у меня хранимые процедуры в SQL-базе и мэппинг на EntityFramework для вызова тех хранимых процедур.
Т.к. это SQL, там бывают довольно длинные списки параметров. Вот, например:

var studies = ctx.usp_SearchStudies(
    patientID:        patientId,
    facilityMRN:      facilityMrn,
    firstName:        firstName,
    lastName:         lastName,
    patientName:      patientName,
    firstAndLastName: firstAndLastName,
    middleName:       middleName,
    patientPrefix:    patientPrefix,
    patientSuffix:    patientSuffix,
    gender:           gender,
    modality:         modality,
    aetitle:          aetitle,
    studyId:          studyId,
    description:      description,
    accession:        accession,
    refPhysician:     refPhysician,
    studyDateFrom:    studyDateFrom,
    studyDateTo:      studyDateTo,
    perPhysician:     perPhysician);


Все или почти все параметры — одного типа (string). Если вызывать процедуру без указания имён параметров, то там запросто можно дико накосячить.
Можно ли как-то средствами C# запретить вызов метода без указания имён параметров? Т.е. чтоб вот такая инструкция сразу давала ошибку компилляции:

var studies = ctx.usp_SearchStudies(
    patientId,
    facilityMrn,
    firstName,
    lastName,
    patientName,
    firstAndLastName,
    middleName,
    patientPrefix,
    patientSuffix,
    gender,
    modality,
    aetitle,
    studyId,
    description,
    accession,
    refPhysician,
    studyDateFrom,
    studyDateTo,
    perPhysician);


?
С уважением, Artem Korneev.
Отредактировано 01.08.2017 17:27 Artem Korneev . Предыдущая версия .
Re: А можно ли запретить "обычный" вызов метода?
От: bnk СССР http://unmanagedvisio.com/
Дата: 01.08.17 18:25
Оценка: 4 (1)
Здравствуйте, Artem Korneev, Вы писали:

AK>Есть у меня хранимые процедуры в SQL-базе и мэппинг на EntityFramework для вызова тех хранимых процедур.

AK>Т.к. это SQL, там бывают довольно длинные списки параметров.

AK>Все или почти все параметры — одного типа (string). Если вызывать процедуру без указания имён параметров, то там запросто можно дико накосячить.

AK>Можно ли как-то средствами C# запретить вызов метода без указания имён параметров? Т.е. чтоб вот такая инструкция сразу давала ошибку компилляции:

AK>
AK>var studies = ctx.usp_SearchStudies(
AK>    patientId,
AK>    facilityMrn,
AK>    firstName,
AK>    lastName,
AK>    patientName,
AK>    firstAndLastName,
AK>    middleName,
AK>    patientPrefix,
AK>    patientSuffix,
AK>    gender,
AK>    modality,
AK>    aetitle,
AK>    studyId,
AK>    description,
AK>    accession,
AK>    refPhysician,
AK>    studyDateFrom,
AK>    studyDateTo,
AK>    perPhysician);
AK>


AK>?


если вызов не авто-генерированый, то есть стандартное решение — передавать объект params, у которого все эти параметры — проперти.


тогда не будет проверяться что ты их все поставил, но это решается гораздо проще, через валидацию, которая скорее всего и так уже есть на уровне базы.

Если авто-генерированвй, менять генератор

Если они приходят с фроненда, можно начать использовать автомаппер (automapper) например.
Отредактировано 01.08.2017 18:32 bnk . Предыдущая версия . Еще …
Отредактировано 01.08.2017 18:29 bnk . Предыдущая версия .
Отредактировано 01.08.2017 18:26 bnk . Предыдущая версия .
Re: А можно ли запретить "обычный" вызов метода?
От: kov_serg Россия  
Дата: 01.08.17 20:26
Оценка: 6 (2) +1
Здравствуйте, Artem Korneev, Вы писали:

AK>Есть у меня хранимые процедуры в SQL-базе и мэппинг на EntityFramework для вызова тех хранимых процедур.

AK>Т.к. это SQL, там бывают довольно длинные списки параметров. Вот, например:
...
AK>Все или почти все параметры — одного типа (string). Если вызывать процедуру без указания имён параметров, то там запросто можно дико накосячить.
AK>Можно ли как-то средствами C# запретить вызов метода без указания имён параметров? Т.е. чтоб вот такая инструкция сразу давала ошибку компилляции:
AK>?
Делайте по старинке
public class SearchStudiesParams {
    public string patientID;
    public string facilityMRN;
    public string firstName;
    public string lastName;
    public string patientName;
    public string firstAndLastName;
    public string middleName;
    public string patientPrefix;
    public string patientSuffix;
    public string gender;
    public string modality;
    public string aetitle;
    public string studyId;
    public string description;
    public string accession;
    public string refPhysician;
    public string studyDateFrom;
    public string studyDateTo;
    public string perPhysician;
    public virtual bool valid() {
        return
            patientID != null &&
            facilityMRN != null &&
            firstName != null &&
            lastName != null &&
            patientName != null &&
            firstAndLastName != null &&
            middleName != null &&
            patientPrefix != null &&
            patientSuffix != null &&
            gender != null &&
            modality != null &&
            aetitle != null &&
            studyId != null &&
            description != null &&
            accession != null &&
            refPhysician != null &&
            studyDateFrom != null &&
            studyDateTo != null &&
            perPhysician != null;
    }
}
...
  var studies = ctx.usp_SearchStudies(new SearchStudiesParams() {
      patientID = patientId,
      facilityMRN = facilityMrn,
      firstName = firstName,
      lastName = lastName,
      patientName = patientName,
      firstAndLastName = firstAndLastName,
      middleName = middleName,
      patientPrefix = patientPrefix,
      patientSuffix = patientSuffix,
      gender = gender,
      modality = modality,
      aetitle = aetitle,
      studyId = studyId,
      description = description,
      accession = accession,
      refPhysician = refPhysician,
      studyDateFrom = studyDateFrom,
      studyDateTo = studyDateTo,
      perPhysician = perPhysician            
  });
Re[2]: А можно ли запретить "обычный" вызов метода?
От: bnk СССР http://unmanagedvisio.com/
Дата: 01.08.17 21:25
Оценка: 47 (8) +1
Здравствуйте, kov_serg, Вы писали:

_>Делайте по старинке


Ну да, и я про то же. Для этого даже название специальное есть у Фаулера: Introduce Parameter Object

Да, загуглил ради интереса
Оказывается народ вот такой хак придумал

    int RegisterUser(
#if DEBUG
      int _ = 0,
#endif
      string nameFirst = null,
      string nameLast = null,
      string nameMiddle = null,
      string email = null) { /*...*/ }
Отредактировано 01.08.2017 21:30 bnk . Предыдущая версия .
Re: А можно ли запретить "обычный" вызов метода?
От: Vladek Россия Github
Дата: 05.08.17 13:49
Оценка: 2 (1) +1
Здравствуйте, Artem Korneev, Вы писали:

AK>Все или почти все параметры — одного типа (string). Если вызывать процедуру без указания имён параметров, то там запросто можно дико накосячить.

AK>Можно ли как-то средствами C# запретить вызов метода без указания имён параметров? Т.е. чтоб вот такая инструкция сразу давала ошибку компилляции:

Есть простой приём — https://sourcemaking.com/design_patterns/builder

Пусть этот объект собирает все возможные аргументы воедино и единолично отвечает за вызов процедуры в случае корректного набора собранных аргументов. Косячить больше не получится.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.