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

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

Обновить

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

4 ответа

Решение

Если это тот подход, который вы хотите или должны использовать, вы можете сделать объекты 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 { }
}

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

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

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

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

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

public class BusinessObject
{
    private class SqlObject
    {
    }
}

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

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

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

Другие вопросы по тегам