Существует ли шаблон, позволяющий вызывать конструктор только с определенной фабрики и ниоткуда? - PullRequest
2 голосов
/ 17 марта 2010

У нас есть класс, скажем LegacyUserSettingsService . LegacyUserSettingsService реализует интерфейс, IUserSettingsService .

Вы можете получить экземпляр IUserSettingsService , позвонив в наш ApplicationServicesFactory. Фабрика использует Spring.NET для создания бетонной LegacyUserSettingsService .

Проблема в том, что новые разработчики иногда делают свое дело и создают новые экземпляры LegacyUserSettingsService напрямую (вместо прохождения через фабрику).

Есть ли способ защитить конструктор конкретного класса, чтобы его можно было вызывать только с завода? Возможно, хорошо известная картина?

Обратите внимание, что конкретный класс находится в другой сборке (отдельно от сборки Factory, поэтому ключевое слово internal не является решением). Заводская сборка ссылается на другую сборку, которая содержит конкретный класс.

Есть идеи?

Ответы [ 5 ]

2 голосов
/ 17 марта 2010

Напротив, internal было бы отличным решением, хотя ключом в том, чтобы сделать заводскую сборку «Сборкой друга» другой. Подробнее см. Сборки друзей .

Сделайте LegacyUserSettingsService internal class, затем в assemblyinfo.cs проекта, который содержит этот класс, добавьте строку [assembly:InternalsVisibleTo("Spring.Core")]. Это должно предоставить Spring.NET доступ к типу, но не к другой сборке.

1 голос
/ 17 марта 2010

Отметьте LegacyUserSettingsService конструкторы с ObsoleteAttribute с IsError, установленным на true. Это просто «атрибут времени компиляции», который приведет к ошибке компиляции везде, где используется конструктор, но экземпляр может быть создан с помощью отражения Spring.NET просто отлично.

0 голосов
/ 17 марта 2010

У вас всегда может быть частный конструктор, который вы вызываете с помощью System.Reflection.ConstructorInfo или System.Linq.Expressions.Expression>. Это остановит случайного разработчика от непосредственного создания экземпляров. Ваш фабричный объект сможет создать экземпляр, но эти противные разработчики будут сорваны!

0 голосов
/ 17 марта 2010

Мы нашли работоспособное решение. Поскольку наша фабрика использует Spring.NET, мы можем просто сделать конструктор LegacyUserSettingsService закрытым. Spring по-прежнему сможет вызывать приватный конструктор.

И никто другой не сможет (если они действительно очень стараются и идут по пути отражения).

0 голосов
/ 17 марта 2010

Единственный способ, которым я знаю, - это сделать конструктор частным и иметь статические фабричные методы для самого класса, которые можно вызывать извне.

Конечно, это не соответствует требованиям ваших вопросов. Так что насчет менее технического подхода, включающего общение и проверку кода ?

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