Сделать объект доступным только для одного другого объекта в той же сборке? - PullRequest
3 голосов
/ 15 сентября 2009

Каждый бизнес-объект имеет соответствующий объект, который содержит вызовы sql. Я хотел бы ограничить эти объекты SQL таким образом, чтобы они могли использоваться только соответствующим бизнес-объектом. Как этого достичь?

Обновление

Грег поднял вопрос о тестируемости. Так как SqlObjects будет содержать очень специфичные для бизнес-процессов sql, я не хочу, чтобы они использовались повторно в нескольких объектах buiness. (Все основные операции CRUD генерируются кодом). Есть ли способ сделать SqlObjects доступными только для одного бизнес-объекта в бизнес-сборке (как показали yshuditelu и Greg Beech) И предоставить SqlObjects сборке для модульного тестирования?

Ответы [ 4 ]

9 голосов
/ 15 сентября 2009

Если вы хотите или должны использовать этот подход, вы можете сделать объекты sql частными в бизнес-объекте.

public class BusinessObject
{
    private class SqlObject { }
}

Кроме того, используя частичные классы, вы можете при желании разделить их на отдельные файлы.

//in one file
public partial class BusinessObject
{
    //business object implementation
}

//in another file
public partial class BusinessObject
{
    private class SqlObject { }
}

Джоэл делает хороший комментарий в комментарии ниже: «SqlObject все еще может наследовать от общего типа, так как такие вещи, как информация о соединении, могут совместно использоваться этими« внутренними »классами». это абсолютно верно и потенциально очень полезно.

В ответ на ваши изменения модульные тесты могут тестировать только публичные классы и функции (без использования отражения в ваших тестах). Единственный вариант, который я могу придумать, это сделать:

  • сделать одну сборку на пару объектов business / sql
  • изменение private class SqlObject на internal class SqlObject
  • затем используйте [InternalsVisibleTo("UnitTestsAssembly")] для проекта

Кроме того, на этом этапе вам не нужно будет хранить объект sql как вложенный класс. Вообще говоря, я думаю, что это, вероятно, добавит больше сложности, чем ценность, которую я добавляю, но я полностью понимаю, что каждая ситуация различна, и если ваши требования / ожидания ведут вас к этому, я желаю вам всего наилучшего. Лично я думаю, что хотел бы сделать SqlObjects общедоступными (или внутренними с внутренностями, видимыми для модульного тестирования) и принять тот факт, что это означает, что классы sql доступны всем бизнес-классам.

4 голосов
/ 15 сентября 2009

Единственный способ сделать это - сделать объект SQL закрытым вложенным типом, т.е.

public class BusinessObject
{
    private class SqlObject
    {
    }
}

Является ли это хорошей идеей с точки зрения тестируемости - это совсем другой вопрос ...

0 голосов
/ 15 сентября 2009

Вы также можете работать с двумя сборками (одна для бизнес-объектов и одна для связанных объектов SQL) и использовать внутренний модификатор для каждого класса SQL и затем использовать [InternalsVisibleTo("BusinessObjectAssembly")] для сборки SQLAssembly.

0 голосов
/ 15 сентября 2009

Вы пытаетесь реализовать класс Friend в C ++. Насколько я знаю, C # и VB.Net не имеют ничего эквивалентного. Мое единственное предложение состоит в том, чтобы сделать класс, который вы хотите ограничить, внутренним классом, которому требуется доступ.

...