Сделать объект доступным только для одного другого объекта в той же сборке?
Вопрос
Каждый бизнес-объект имеет соответствующий объект, который содержит вызовы sql.Я бы хотел ограничить эти объекты sql таким образом, чтобы они могли использоваться только соответствующим бизнес-объектом.Как этого можно достичь?
Обновить
Грег затронул тему тестируемости.Поскольку SqlObjects будут содержать sql, специфичный для бизнес-процесса, я не хочу, чтобы они повторно использовались в нескольких объектах buiness.(Все основные операции CRUD генерируются в коде) Есть ли способ сделать SqlObjects доступными только для одного бизнес-объекта в бизнес-сборке (как показали yshuditelu и Greg Beech) И предоставить SqlObjects для сборки модульного тестирования?
Решение
Если это тот подход, который вы хотите или должны использовать, вы могли бы сделать объекты 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 все еще может наследовать от общего типа, чтобы такие вещи, как информация о соединении, могли совместно использоваться этими "внутренними" классами". это абсолютно верно и потенциально очень полезно.
В ответ на вашу правку модульные тесты могут тестировать только общедоступные классы и функции (без использования отражения в ваших тестах).Единственный вариант, который я могу придумать, который мог бы это сделать, это:
- создайте одну сборку для каждой пары бизнес-объектов / 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.