Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 18.08.04 11:09
Оценка:
Не знаю, может быть вопрос в .NET правильней задать, но всёже:
Есть мысль разделить объект на 2 интерфейса — один общедоступный, который позволять поля, но не позволяет изменять их,
другой же как раз предназначен для редактирования всего, что только вздумается. Разделить просто на 2 интерфейса я могу (пусть от этого код и раздуется несколько, не настолько это страшно), но вот вопрос возникает — как сделать разные права доступа к 2 интерфейсам организовать так, чтобы 1-й был публичным, а 2-й был доступен только из определённых "мест" (определённых классов, скажем так). В голову приходит только friend-классы из C++, но в C# такого нет, поэтому пока в тупике...
Заранее большоие спасибо за любые мысли по данному (и возможно не тольк) поводу!
Re: Разделение доступа
От: A_Gura Россия http://a-gura.livejournal.com
Дата: 18.08.04 11:34
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Не знаю, может быть вопрос в .NET правильней задать, но всёже:

К>Есть мысль разделить объект на 2 интерфейса — один общедоступный, который позволять поля, но не позволяет изменять их,
К>другой же как раз предназначен для редактирования всего, что только вздумается. Разделить просто на 2 интерфейса я могу (пусть от этого код и раздуется несколько, не настолько это страшно), но вот вопрос возникает — как сделать разные права доступа к 2 интерфейсам организовать так, чтобы 1-й был публичным, а 2-й был доступен только из определённых "мест" (определённых классов, скажем так). В голову приходит только friend-классы из C++, но в C# такого нет, поэтому пока в тупике...
К>Заранее большоие спасибо за любые мысли по данному (и возможно не тольк) поводу!

если я не ошибаюсь, в C# есть пакетная видимость.
Т.о. второй интерфейс может быть доступен например только в пределах пакета.
... << RSDN@Home 1.1.4 @@subversion >>
Работать надо над собой...
Re[2]: Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 18.08.04 11:45
Оценка:
Здравствуйте, A_Gura, Вы писали:

A_G>если я не ошибаюсь, в C# есть пакетная видимость.

A_G>Т.о. второй интерфейс может быть доступен например только в пределах пакета.

Если ты под пакетом понимаешь сборку (assembly), то нафиг такое решение, ибо бизнесс-объекты мешать (в одну длл совать) с гуем — нет ничего хуже.
В том-то и дело, что internal доступ ну совсем не в тему...
Re: Разделение доступа
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 18.08.04 12:59
Оценка:
Здравствуйте, Курилка, Вы писали:

К>В голову приходит только friend-классы из C++, но в C# такого нет, поэтому пока в тупике...


Ну что же Вы так сразу в тупике-то...
Carrier = INTERFACE
  PROCEDURE GetViewer(OUT Viewer: CarrierViewer); // раздает просмотрщик всем кому ни попадя
  PROCEDURE Accept(v: CarrierVisitor);
END;

CarrierFriend = INTERFACE
  PROCEDURE SetCarrierEditor(Editor: CarrierEditor);
END;

//----------------------------------------------------------------------------------

PROCEDURE TCarrier.Accept(v: CarrierVisitor);
BEGIN
  (v AS CarrierFriend).SetCarrierEditor(SELF.Editor); // Выдает интерфейс редактора только друзьям
END;

В PROCEDURE TCarrier.Accept(v: CarrierVisitor); у Визитора можно еще пароль спросить...
Re[2]: Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 18.08.04 13:17
Оценка:
Здравствуйте, S.Yu.Gubanov, Вы писали:

SYG>Здравствуйте, Курилка, Вы писали:


К>>В голову приходит только friend-классы из C++, но в C# такого нет, поэтому пока в тупике...


SYG>Ну что же Вы так сразу в тупике-то...

SYG>
SYG>Carrier = INTERFACE
SYG>  PROCEDURE GetViewer(OUT Viewer: CarrierViewer); // раздает просмотрщик всем кому ни попадя
SYG>  PROCEDURE Accept(v: CarrierVisitor);
SYG>END;

SYG>CarrierFriend = INTERFACE
SYG>  PROCEDURE SetCarrierEditor(Editor: CarrierEditor);
SYG>END;

SYG>//----------------------------------------------------------------------------------

SYG>PROCEDURE TCarrier.Accept(v: CarrierVisitor);
SYG>BEGIN
SYG>  (v AS CarrierFriend).SetCarrierEditor(SELF.Editor); // Выдает интерфейс редактора только друзьям
SYG>END;
SYG>

SYG>В PROCEDURE TCarrier.Accept(v: CarrierVisitor); у Визитора можно еще пароль спросить...

Ммм, если честно слабо поняли идею, какие-то названия совершенно непонятные, носители какие-то и т.д....
Хотелось бы что-то типа:


public interface IA
{
int a{get};  
}

//вот паблик тут не в тему...
public interface IAEditor
{
int a{set};  
}

//а класс примерно так выглядеть должен, хотя с доступом не получится :( :
public class A: IA, IAEdtor
{
//тут реализация конкретная
}


Так вот какие классы/интерфейсы твоим соответствуют?
Re[3]: Разделение доступа
От: kig Россия  
Дата: 18.08.04 17:22
Оценка:
Здравствуйте, Курилка, Вы писали:

[]

К>В том-то и дело, что internal доступ ну совсем не в тему...


Может это подойдет?

[msdn]
Securing Method Access
Some methods might not be suitable to allow arbitrary untrusted code to call. Such methods pose several risks: the method might provide some restricted information; it might believe any information passed to it; it might not do error checking on the parameters; or with the wrong parameters, it might malfunction or do something harmful. You should be aware of these cases and take suitable action to secure the method.

In some cases, you might need to restrict methods that are not intended for public use, but still must be public. For example, you might have an interface that needs to be called across your own DLLs, and hence must be public, but you do not want to expose it publicly to prevent customers from using it or to prevent malicious code from exploiting the entry point into your component. Another common reason to restrict a method not intended for public use (yet that must be public) is to avoid having to document and support what may be a very internal interface.

....

[/msdn]
Re[4]: Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 19.08.04 05:08
Оценка:
Здравствуйте, kig, Вы писали:

kig>Здравствуйте, Курилка, Вы писали:


kig>[]


К>>В том-то и дело, что internal доступ ну совсем не в тему...


kig>Может это подойдет?


kig>[msdn]

<skipped/>
kig>[/msdn]

Дак это всё общее, говорится что нужно делать, а о том КАК это сделать — ни слова.
Re: Разделение доступа
От: Sinclair Россия https://github.com/evilguest/
Дата: 19.08.04 05:19
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Не знаю, может быть вопрос в .NET правильней задать, но всёже:

К>Есть мысль разделить объект на 2 интерфейса — один общедоступный, который позволять поля, но не позволяет изменять их,
К>другой же как раз предназначен для редактирования всего, что только вздумается. Разделить просто на 2 интерфейса я могу (пусть от этого код и раздуется несколько, не настолько это страшно), но вот вопрос возникает — как сделать разные права доступа к 2 интерфейсам организовать так, чтобы 1-й был публичным, а 2-й был доступен только из определённых "мест" (определённых классов, скажем так). В голову приходит только friend-классы из C++, но в C# такого нет, поэтому пока в тупике...
К>Заранее большоие спасибо за любые мысли по данному (и возможно не тольк) поводу!
НУ, вроде как для этого есть CAS (code access security). Я сам столкнулся с этой проблемой. Пока что мы на нее забили, т.е. просто "вручную" следим за тем, чтобы лишние сборки не лезли в Mutable интерфейс. Планирую в будущем поплотнее заняться этим вопросом.
... << RSDN@Home 1.1.4 beta 1 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 19.08.04 05:29
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Курилка, Вы писали:


К>>Не знаю, может быть вопрос в .NET правильней задать, но всёже:

К>>Есть мысль разделить объект на 2 интерфейса — один общедоступный, который позволять поля, но не позволяет изменять их,
К>>другой же как раз предназначен для редактирования всего, что только вздумается. Разделить просто на 2 интерфейса я могу (пусть от этого код и раздуется несколько, не настолько это страшно), но вот вопрос возникает — как сделать разные права доступа к 2 интерфейсам организовать так, чтобы 1-й был публичным, а 2-й был доступен только из определённых "мест" (определённых классов, скажем так). В голову приходит только friend-классы из C++, но в C# такого нет, поэтому пока в тупике...
К>>Заранее большоие спасибо за любые мысли по данному (и возможно не тольк) поводу!
S>НУ, вроде как для этого есть CAS (code access security). Я сам столкнулся с этой проблемой. Пока что мы на нее забили, т.е. просто "вручную" следим за тем, чтобы лишние сборки не лезли в Mutable интерфейс. Планирую в будущем поплотнее заняться этим вопросом.

ОК, попробую на досуге с CAS поразбираться (ибо не горит пока такая задача), но если какое-нибудь решение откопаете — был бы реально признателен, если дадите знать о нём
Re: Разделение доступа
От: Cider Россия  
Дата: 19.08.04 06:15
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Не знаю, может быть вопрос в .NET правильней задать, но всёже:

К>Есть мысль разделить объект на 2 интерфейса — один общедоступный, который позволять поля, но не позволяет изменять их,
К>другой же как раз предназначен для редактирования всего, что только вздумается. Разделить просто на 2 интерфейса я могу (пусть от этого код и раздуется несколько, не настолько это страшно), но вот вопрос возникает — как сделать разные права доступа к 2 интерфейсам организовать так, чтобы 1-й был публичным, а 2-й был доступен только из определённых "мест" (определённых классов, скажем так). В голову приходит только friend-классы из C++, но в C# такого нет, поэтому пока в тупике...
К>Заранее большоие спасибо за любые мысли по данному (и возможно не тольк) поводу!

Сделать фабрики (пулы или еще что-нибудь в этом роде), которые выдают соответствующие интерфейсы. Одна фабрика дает readonly интерфейс, другая mutable. А в клиентах работать только с интерфейсами. Сделать сам тип объекта недоступным для клиента и дать возможность обращаться только к соответствующей фабрике.

Cider
Cider
Re[2]: Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 19.08.04 06:18
Оценка:
Здравствуйте, Cider, Вы писали:

C>Сделать фабрики (пулы или еще что-нибудь в этом роде), которые выдают соответствующие интерфейсы. Одна фабрика дает readonly интерфейс, другая mutable. А в клиентах работать только с интерфейсами. Сделать сам тип объекта недоступным для клиента и дать возможность обращаться только к соответствующей фабрике.

Уже что-то похожее на правду, но вопрос — если класс не известен клиенту, то как он доступ к объекту будет получать? И как ты разграничишь доступ к фабрикам, которые тоже суть классы
Re[3]: Разделение доступа
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 19.08.04 06:56
Оценка: 4 (1)
Здравствуйте, Курилка, Вы писали:

К>Ммм, если честно слабо поняли идею, какие-то названия совершенно непонятные, носители какие-то и т.д....

К>Хотелось бы что-то типа:

К>

К>public interface IA
К>{
К>int a{get};  
К>}

К>//вот паблик тут не в тему...
К>public interface IAEditor
К>{
К>int a{set};  
К>}

К>//а класс примерно так выглядеть должен, хотя с доступом не получится :( :
К>public class A: IA, IAEdtor
К>{
К>//тут реализация конкретная
К>}
К>


К>Так вот какие классы/интерфейсы твоим соответствуют?


Ваш class A — это мой ICarrier — носитель какой-либо информации. Эту информацию можно просматривать, а можно редактировать. В общем случае информацию могут одновременно просматривать несколько клиентов и каждого из них, быть может, интересует не вся информация, а лишь какое-то ее подмножество. Тоже самое касается редактирования информации содержащейся в носителе — возможны несколько интерфейсов по редактированию.

Ваш IA — это интерфейс для просмотра (чтения) информации содержащейся в носителе. То есть, это мой ICarrierReader. В общем случае их может быть несколько ICarrierReader1, ICarrierReader2, ICarrierReader3,...

Ваш IAEditor — это интерфейс для редактирования (записи) информации носителя. То есть, это то что я назвал ICarrierEditor. В общем случае их тоже может быть несколько: ICarrierEditor1, ICarrierEditor2, ICarrierEditor3.

Пусть, для простоты, будет всего один интерфейс чтения и один интерфейс записи.

Тогда интерфейс ICarrier будет такой
TYPE
  ICarrier = INTERFACE
    PROCEDURE GetNewCarrierReader(OUT Reader: ICarrierReader);
    PROCEDURE GetNewCarrierEditor(OUT Editor: ICarrierEditor);
  END;

В вашем случае ICarrierReader и ICarrierEditor будут такими:
TYPE
  ICarrierReader = INTERFACE
    PROCEDURE GetA(OUT a: INTEGER);
  END;

  ICarrierEditor = INTERFACE
    PROCEDURE SetA(CONST a: INTEGER);
  END;

Теперь Вы хотите, чтобы носитель информации сам решал кому он может выдать свой ICarrierEditor, а кому не может. Один из способов сделать это, например, такой. Убираем из интерфейса ICarrier метод GetNewCarrierEditor(OUT Editor: ICarrierEditor); а вместо него вставляем что-то такое:
TYPE
  ICarrier = INTERFACE
    PROCEDURE GetNewCarrierReader(OUT Reader: ICarrierReader);
    PROCEDURE QueryCarrierEditor(Visitor: IInterface);
  END;

Visitor — это любой интерфейс (IInterface = IUnknown).
Создаем дополнительный интерфейс — друга носителя.
TYPE
  ICarrierFriendForEditing = INTERFACE
    PROCEDURE SetCarrierEditor(CONST Editor: ICarrierEditor);
  END;

Метод QueryCarrierEditor реализуем например так:
PROCEDURE TCarrier.QueryCarrierEditor(Visitor: IInterface);
BEGIN
  (Visitor AS ICarrierFriendForEditing).SetCarrierEditor(SELF.CarrierEditor());
END;

То есть носитель информации — Carrier самостоятельно решил, что выдавать свой интерфейс редактирования он будет только друзьям — ICarrierFriendForEditing.


Принципиальная разница между тем что предложил Вам я, и тем что написано у Вас:
К>public class A: IA, IAEdtor

думаю очевидна. В Вашем случае интерфейсы чтения и записи жестко привязаны к самому классу. В моем случае никаких классов нет вообще — кругом одни лишь интерфейсы. В вашем случае стоит лишь только кому-нибудь заполучить экземпляр класса A, как он сразу сможет с ним сделать все что захочет. В моем случае никто не имеет доступа непосредственно к самому объекту носителю информации. Весь внешний мир работает лишь только с его интерфейсом ICarrier. Интерфейсы ICarrierReader1,2,3.. и ICarrierEditor1,2,3.. могут быть реализованы другими классами объектов, но могут быть реализованы и в одном классе (в самом носителе) — внешний мир, все равно, об этом знать не должен.
Re[4]: Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 19.08.04 07:15
Оценка:
Здравствуйте, S.Yu.Gubanov, Вы писали:

<поскипано злобными ёжиками/>

т.е. у тебя получается проверка в рантайме за счёт QueryCarrierEditor? Без вызова которого работать схема не будет?
Лучше было бы чтобы проверка была на этапе компиляции...
Но и так выглядит довольно симпотно (хотя код зупутывается однозначно)
Спасибки!

BTW вроде бы в рсдн принято на ты общаться, а не на вы
Re[3]: Разделение доступа
От: PeterZT  
Дата: 20.08.04 06:59
Оценка: 8 (2)
К>В том-то и дело, что internal доступ ну совсем не в тему...
В 2.0 есть InternalsVisibleToAttribute, пример:
[assembly:InternalsVisibleTo ("AssemblyB", PublicKeyToken="32ab4ba45e0a69a1")]
Сам еще не использовал.
... << RSDN@Home 1.1.4 @@subversion >>
Re[4]: Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.08.04 07:04
Оценка:
Здравствуйте, PeterZT, Вы писали:

К>>В том-то и дело, что internal доступ ну совсем не в тему...

PZT>В 2.0 есть InternalsVisibleToAttribute, пример:
PZT>[assembly:InternalsVisibleTo ("AssemblyB", PublicKeyToken="32ab4ba45e0a69a1")]
PZT>Сам еще не использовал.

Ну на 2.0 мы ещё не перешли, но надо сей факт запомнить,
тока вот просто интёрнал не подойдёт, т.к. сборка будет содержать далеко не 1 класс (а десятки и сотни), и доступ к каждому свой, а атрибут сделает видимыми ВСЕ интерналы
Re[5]: Разделение доступа
От: PeterZT  
Дата: 20.08.04 08:11
Оценка:
К>Ну на 2.0 мы ещё не перешли, но надо сей факт запомнить,
К>тока вот просто интёрнал не подойдёт, т.к. сборка будет содержать далеко не 1 класс (а десятки и сотни), и доступ к каждому свой, а атрибут сделает видимыми ВСЕ интерналы
Вынести необходимые классы в отдельную сборку, пометить их как интернал и предоставить доступ необходимым сборкам.
... << RSDN@Home 1.1.4 @@subversion >>
Re[6]: Разделение доступа
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.08.04 08:32
Оценка:
Здравствуйте, PeterZT, Вы писали:

К>>Ну на 2.0 мы ещё не перешли, но надо сей факт запомнить,

К>>тока вот просто интёрнал не подойдёт, т.к. сборка будет содержать далеко не 1 класс (а десятки и сотни), и доступ к каждому свой, а атрибут сделает видимыми ВСЕ интерналы
PZT>Вынести необходимые классы в отдельную сборку, пометить их как интернал и предоставить доступ необходимым сборкам.

Т.е. имеем в итоге сотню-другую дллин от нечего делать?
А если у меня винформы лежат в одной сборке для более простого деплоймента? И доступ нужен просто для разных формочек разный.
Re: Разделение доступа
От: SiAVoL Россия  
Дата: 30.08.04 18:22
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Заранее большоие спасибо за любые мысли по данному (и возможно не тольк) поводу!

C#: CallerPermission
Автор: SiAVoL
Дата: 30.08.04
... << RSDN@Home 1.1.4 @@release >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.