Хотелось бы такого — чтобы можно было передать в чужой код ссылку на объект, и любая попытка его изменения приводила бы к исключению. Точнее, там не один объект, а сложная система из объектов с перекрестными ссылками. То есть нужно, чтобы блокировались вызовы методов, которые изменяют состояние.
Насколько я понимаю, в CLI вполне возможно добиться такого, с помощью перехвата вызовов например.
Где-нибудь есть готовые реализации?
Здравствуйте, Torie, Вы писали:
T>Хотелось бы такого — чтобы можно было передать в чужой код ссылку на объект, и любая попытка его изменения приводила бы к исключению. Точнее, там не один объект, а сложная система из объектов с перекрестными ссылками. То есть нужно, чтобы блокировались вызовы методов, которые изменяют состояние.
А зачем предоставлять чужому коду доступ к методам, изменяющим состояние?
Здравствуйте, Aen Sidhe, Вы писали:
AS>А зачем предоставлять чужому коду доступ к методам, изменяющим состояние?
Ну так для моего кода такой доступ нужен. То есть придется делать по две версии каждого интерфейса, а там еще и коллекции BCL, и коллекции интерфейсов, и вложенные объекты, и наследование.. В общем, это гемор фантастических масштабов. Я например работал с Microsoft.CCI, там разработчики пошли именно по этому пути. Скажу прямо — это чудовищно, до сих пор снятся в страшных снах все эти прыжки с бубном
Хочется добиться аналогичного результата, но без кучи ручной работы.
Здравствуйте, Torie, Вы писали:
T>Здравствуйте, Aen Sidhe, Вы писали:
AS>>А зачем предоставлять чужому коду доступ к методам, изменяющим состояние?
T>Ну так для моего кода такой доступ нужен. То есть придется делать по две версии каждого интерфейса, а там еще и коллекции BCL, и коллекции интерфейсов, и вложенные объекты, и наследование.. В общем, это гемор фантастических масштабов. Я например работал с Microsoft.CCI, там разработчики пошли именно по этому пути. Скажу прямо — это чудовищно, до сих пор снятся в страшных снах все эти прыжки с бубном T>Хочется добиться аналогичного результата, но без кучи ручной работы.
Здравствуйте, Torie, Вы писали:
T>Хотелось бы такого — чтобы можно было передать в чужой код ссылку на объект, и любая попытка его изменения приводила бы к исключению. Точнее, там не один объект, а сложная система из объектов с перекрестными ссылками. То есть нужно, чтобы блокировались вызовы методов, которые изменяют состояние. T>Насколько я понимаю, в CLI вполне возможно добиться такого, с помощью перехвата вызовов например. T>Где-нибудь есть готовые реализации?
"Чужой код" обычно ожидает некий интерфейс (не в смысле C# interface, а в общем смысле) через который с объектом и работает. Например, "чужому коду" который занимается сортировкой требуется передать массив данных. Какой смысл запрещать этому коду изменять содержимое массива?
Если "чужой код" требует такой интерфейс, через который объект можно изменить, то значит или "чужому коду" действительно требуется изменить объект и не понятно, зачем и как (исключением? игнорированием?) изменение запретить, или же "чужой код" не будет изменять объект и тогда беспокоиться незачем.
Может быть, у вас другая задача — не "передать в чужой код ссылку на объект", а предоставить такой интерфейс своих объектов, через который нельзя было бы объекты изменить?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Может быть, у вас другая задача — не "передать в чужой код ссылку на объект", а предоставить такой интерфейс своих объектов, через который нельзя было бы объекты изменить?
У меня этих интерфейсов десятки, они все связаны и образуют сложную объектную модель. Ты представляешь себе объем гемора, если я буду отграничивать доступ вручную?
Здравствуйте, Torie, Вы писали:
T>Здравствуйте, _FRED_, Вы писали:
_FR>>Может быть, у вас другая задача — не "передать в чужой код ссылку на объект", а предоставить такой интерфейс своих объектов, через который нельзя было бы объекты изменить?
T>У меня этих интерфейсов десятки, они все связаны и образуют сложную объектную модель. Ты представляешь себе объем гемора, если я буду отграничивать доступ вручную?
Могу предложить рантаймовый AOP типа Unity с Interception. Просто атрибутами навесить обработчики на методы, которые нельзя вызывать и отдавать прокси стороннему коду.
Здравствуйте, Torie, Вы писали:
_FR>>Может быть, у вас другая задача — не "передать в чужой код ссылку на объект", а предоставить такой интерфейс своих объектов, через который нельзя было бы объекты изменить?
T>У меня этих интерфейсов десятки, они все связаны и образуют сложную объектную модель. Ты представляешь себе объем гемора, если я буду отграничивать доступ вручную?
Не представляю, так как не понимаю, что требуется Сначала давайте посмотрим на то, что нужно, а потом уже будем представлять, на сколько это сложно Так что же всё-таки требуется? может, пример можно привести?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, gandjustas, Вы писали:
G>Могу предложить рантаймовый AOP типа Unity с Interception. Просто атрибутами навесить обработчики на методы, которые нельзя вызывать и отдавать прокси стороннему коду.
А можно сделать, чтобы прокси автоматически навешивались на все ссылки, которые чужой код получит от моего исходного прокси?
Здравствуйте, _FRED_, Вы писали:
_FR>Не представляю, так как не понимаю, что требуется Сначала давайте посмотрим на то, что нужно, а потом уже будем представлять, на сколько это сложно Так что же всё-таки требуется? может, пример можно привести?
Посмотри на объектную модель Microsoft.CCI, там хороший пример во что выливаются попытки сделать, как предлагаешь ты
Здравствуйте, Torie, Вы писали:
_FR>>Не представляю, так как не понимаю, что требуется Сначала давайте посмотрим на то, что нужно, а потом уже будем представлять, на сколько это сложно Так что же всё-таки требуется? может, пример можно привести?
T>Посмотри на объектную модель Microsoft.CCI, там хороший пример во что выливаются попытки сделать, как предлагаешь ты
Во-первых, почему я должен на что-то смотреть? Я попросил лишь внятно и понятно сфорсмулировать вопрос. Или это такой вопрос: мне нужно тоже что там, но е так? Так вопросы не задают.
Во-вторых, я ещё ничего предложить не успел, кроме как объяснить мне свои желания. Не хочется — не надо.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Torie, Вы писали:
T>Здравствуйте, gandjustas, Вы писали:
G>>Могу предложить рантаймовый AOP типа Unity с Interception. Просто атрибутами навесить обработчики на методы, которые нельзя вызывать и отдавать прокси стороннему коду.
T>А можно сделать, чтобы прокси автоматически навешивались на все ссылки, которые чужой код получит от моего исходного прокси?
Здравствуйте, Torie, Вы писали:
_FR>>Во-первых, почему я должен на что-то смотреть? Я попросил лишь внятно и понятно сфорсмулировать вопрос.
T>Я сформулировал внятно и понятно — для тех, кто в теме. А если кто не в теме, то им я помочь не могу
Вовсе не обязательно при этом грубить тем, кто не понял. Ведь помощь-то нужна как раз вам.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Вовсе не обязательно при этом грубить тем, кто не понял. Ведь помощь-то нужна как раз вам.
Всегда удивляюсь с людей, которые не поняли сути вопроса, но рвутся обязательно что-нибудь написать.
Можно было просто промолчать — на вопрос или ответил бы кто-нибудь, кто понял, или автор уточнил бы вопрос
Здравствуйте, Torie, Вы писали:
_FR>>Вовсе не обязательно при этом грубить тем, кто не понял. Ведь помощь-то нужна как раз вам.
T>Всегда удивляюсь с людей, которые не поняли сути вопроса, но рвутся обязательно что-нибудь написать. T>Можно было просто промолчать — на вопрос или ответил бы кто-нибудь, кто понял, или автор уточнил бы вопрос
Здесь всё-таки форум и писать сюда у меня прав не меньше чем у вас. И вопросы по интересующей теме задавать я могу не меньше вашего. Мне стала интересна ваша ситуация и вот уж не ожидал, что получу такой ответ на своё любопытство. Очень жаль.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здесь всё-таки форум и писать сюда у меня прав не меньше чем у вас. И вопросы по интересующей теме задавать я могу не меньше вашего. Мне стала интересна ваша ситуация и вот уж не ожидал, что получу такой ответ на своё любопытство.
Я разве запрещаю? Просто удивляюсь с нелогичного поведения.
Вопрос тебе не понятен, смотреть ни на что ты не хочешь
Здравствуйте, Torie, Вы писали:
T>Хотелось бы такого — чтобы можно было передать в чужой код ссылку на объект, и любая попытка его изменения приводила бы к исключению. Точнее, там не один объект, а сложная система из объектов с перекрестными ссылками. То есть нужно, чтобы блокировались вызовы методов, которые изменяют состояние. T>Насколько я понимаю, в CLI вполне возможно добиться такого, с помощью перехвата вызовов например. T>Где-нибудь есть готовые реализации?
Можно попробовать разместить всю толпу объектов в отдельном контексте c помошью ContextBoundObject. При этом в .NET межконтекстные вызовы можно перехватывать.
Учтите только, что межконтекстные вызовы штука весьма тормознутая, и на межконтестные вызовы налагаются ограничения по JIT-оптимизации.
Здравствуйте, SE, Вы писали:
SE>Учтите только, что межконтекстные вызовы штука весьма тормознутая, и на межконтестные вызовы налагаются ограничения по JIT-оптимизации.
Здравствуйте, Torie, Вы писали:
SE>>Учтите только, что межконтекстные вызовы штука весьма тормознутая, и на межконтестные вызовы налагаются ограничения по JIT-оптимизации.
T>Насколько, приблизительно?
Здравствуйте, Torie, Вы писали:
T>Хотелось бы такого — чтобы можно было передать в чужой код ссылку на объект, и любая попытка его изменения приводила бы к исключению. Точнее, там не один объект, а сложная система из объектов с перекрестными ссылками. То есть нужно, чтобы блокировались вызовы методов, которые изменяют состояние.
Вначале, такие методы нужно как-то найти. Делать это в рантайме
T>Насколько я понимаю, в CLI вполне возможно добиться такого, с помощью перехвата вызовов например.
Готовой инфраструктуры для перехвата изменения состояния объекта в CLI нет. С другой стороны, если для работы с объектами используются интерфейсы то, можно написать framework который в "полу-автоматическом" режиме будет создавать read-only враппер для произвольного объекта.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, _FRED_, Вы писали:
_FR>"чужому коду" который занимается сортировкой требуется передать массив данных. Какой смысл запрещать этому коду изменять содержимое _FR>массива?
Потому что вот такой своеобразный подход к проектированию объектной модели.
Например, публичное свойство-последовательность, которое по логике вещей должно:
а) только читаться;
б) быть неизменяемой для клиентского кода последовательностью;
делается как:
public List<T> SomeSequence { get; set; }
вместо:
private List<T> _someListField;
public IEnumerable<T> SomeSequence
{
get { return _someListField; }
}
Потом клиентский код делает SomeSequence.Clear() и все падает.
А List<T> оно потому что:
а) так удобней, потому что можно использовать auto-implemented property;
б) этот тип использовался в схожем примере в MSDN/блоге/и т.д.
в) так делает когодгенератор, кем-то написанный;
г) так с этим свойством легко работает какой-нибудь XmlSerializer;
д) так действительно получается меньше кода;
е) ... и еще миллион причин...
IMHO, такое имеет право на жизнь в ситуации, когда код объектов должен быть максимально-простым и тащить за собой минимум зависимостей.
Навскидку могу назвать один use-case, где подобное можно и нужно использовать — DTO. Но вот только граф DTO, полученный, например с клиента, подлежит последующей валидации.
В остальных случаях использовать такую модель не хочется...
Здравствуйте, HowardLovekraft, Вы писали:
_FR>>"чужому коду" который занимается сортировкой требуется передать массив данных. Какой смысл запрещать этому коду изменять содержимое _FR>массива? HL>Потому что вот такой своеобразный подход к проектированию объектной модели. HL>Например, публичное свойство-последовательность, которое по логике вещей должно: HL>а) только читаться; HL>б) быть неизменяемой для клиентского кода последовательностью; HL>делается как: HL>
HL>Потом клиентский код делает SomeSequence.Clear() и все падает.
Перечитайте пожалуйста сообщение, на которое дали ответ. Мои слова про массив имели отношение к тому, что было сказано топикстартером: "передать в чужой код ссылку на объект". Здесь же (List/Enumerable) обсуждается вопрос проектирования своего кода, что бы "чужой код" не мог бы cделать чего-то ненужного. Это несколько разные вопросы. Советы о том, как обеспечить неизменяемость своего кода нужны топикстартеру
HL>А List<T> оно потому что: HL>а) так удобней, потому что можно использовать auto-implemented property; HL>б) этот тип использовался в схожем примере в MSDN/блоге/и т.д. HL>в) так делает когодгенератор, кем-то написанный; HL>д) так действительно получается меньше кода; HL>е) ... и еще миллион причин...
Достаточно одной — глупость и лень ей имя.
HL>г) так с этим свойством легко работает какой-нибудь XmlSerializer;
Сростить объект, который должден быть неизменяемым с XmlSerializer-ом задача сродни скрешивания ежа с ужом — и не получится ничего хорошего и процесс не понравится
HL>IMHO, такое имеет право на жизнь в ситуации, когда код объектов должен быть максимально-простым и тащить за собой минимум зависимостей. HL>Навскидку могу назвать один use-case, где подобное можно и нужно использовать — DTO. Но вот только граф DTO, полученный, например с клиента, подлежит последующей валидации. HL>В остальных случаях использовать такую модель не хочется...
Что имелось в виду под выделенным я не понял — свойства типа List или свойства типа IEnumerable?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Torie, Вы писали:
T>Хотелось бы такого — чтобы можно было передать в чужой код ссылку на объект, и любая попытка его изменения приводила бы к исключению. Точнее, там не один объект, а сложная система из объектов с перекрестными ссылками. То есть нужно, чтобы блокировались вызовы методов, которые изменяют состояние.
Если объекты ваши, то можно замутить подобное с помощью того же PostSharp-а. Но это достаточно геморойно будет.
Здравствуйте, Torie, Вы писали:
T>Здравствуйте, gandjustas, Вы писали:
G>>Ну он же не сам получает — вы передаете
T>Ну да, можно перехватывать такие вызовы и отдавать прокси вместо ссылки. Но может быть, там уже есть такой функционал?
Ну тем же Unity делать прокси для объектов стороннего кода, которые проксируют передаваемые объекты
Здравствуйте, Torie, Вы писали:
T>Здравствуйте, gandjustas, Вы писали:
G>>Ну тем же Unity делать прокси для объектов стороннего кода, которые проксируют передаваемые объекты
T>Это само собой! Просто пытаюсь сообразить, как это сделать с минимальным количеством гемора. Объектов то много и создаются в куче разных мест.
Тупо позаменять new {Type}() на Container.Resolve<{Type}>(). Думаю это покроет довольно много сценариев.
Здравствуйте, _FRED_, Вы писали:
_FR>Не представляю, так как не понимаю, что требуется Сначала давайте посмотрим на то, что нужно, а потом уже будем представлять, на сколько это сложно Так что же всё-таки требуется? может, пример можно привести?
Кажется, я понял. Он хочет что-то наподобие С++ const:
void GetItem(int& v) const; // здесь просто геттер такой, но он не меняет состояния своего инстанса.void SetItem(constint& v); // а здесь сеттер, принимает ссылку, но объект по ссылке менять нельзя. Причём если это будет сложный объект, у него будут вызываемы только методы с модификатором const