Можно ли настроить поведение модификаторов доступа? - PullRequest
1 голос
/ 16 ноября 2011

У меня есть приложение winform, состоящее из двух сборок: бизнес-уровня и интерфейсного уровня. Каждый usercontrol (интерфейсный уровень) относится к классу бизнес-уровня, т.е. CustomerUserControl использует класс Customer .

Редактируемые свойства, т. Е. Customer.Name , имеют общедоступные установщики, так что их значения можно изменять с помощью внешних элементов управления.

Мой вопрос: возможно ли изменить доступность свойства для установки, чтобы сделать его более или менее ограничительным только для определенных классов. В моем примере установщик Customer.Name будет внутренним, он недоступен внешним элементам управления, но доступен для его соответствующего элемента управления CustomerUserControl . В противном случае сеттер будет общедоступным, но не доступным для элементов управления, отличных от CustomerUserControl .

Можно ли получить такие настроенные права доступа?

Ответы [ 3 ]

3 голосов
/ 16 ноября 2011

Я бы использовал внутренний модификатор для сеттера. Это делает его доступным только внутри сборки. Если CustomerUserControl находится в другой сборке, вы можете использовать InternalsVisibleToAttribute

[assembly: InternalsVisibleTo("assembly name")] 

РЕДАКТИРОВАТЬ : Вы правы. Вот еще одна возможность: Объявите интерфейс, который будет реализован элементами управления, которым разрешено устанавливать имена:

public interface ICustomerNameProvider
{
    string CustomerName { get; }
}

В Customer добавьте метод:

public void SetName(ICustomerNameProvider customerNameProvider)
{
    this.Name = customerNameProvider.CustomerName;
}

CustomerUserControl будет называть это так:

cust.SetName(this);

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

1 голос
/ 16 ноября 2011

Насколько я знаю, нет никакого способа применить то, что вы просите, непосредственно к установщику свойств, так как он не знает, откуда был инициирован вызов.Тем не менее, вы можете собрать что-нибудь вместе, используя методы-мутаторы:

public class Customer
{
   ...
   public string Name
   {
      get;
      private set;
   }

   public void SetName(string callingControlName, string newName)
   {
      // you'd use TypeOf the same way to pass in callingControlName
      if(TypeOf(this).Name + "UserControl" == callingControlName)
         this.Name = newName;
   }
   ...
}

Обратите внимание, что это смешно тесно связано и плохая практика проектирования, но это должно делать то, что вы хотите, при условии, что вы строго придерживаетесь соглашений об именах, изложенныхв вопросе (Customer соответствует 1: 1 с CustomerUserControl).Кроме того, я не просто статически сравнивал callingControlName с "CustomerUserControl", чтобы получить небольшое улучшение в удобстве обслуживания, если вы хотите сделать что-то вроде переименования класса CustomerUserControl.Также важно отметить тот факт, что это легко устранить, позвонив по номеру Customer.SetName("CustomerUserControl","badName").Надеюсь, вы не раскрываете это кодерам, которые будут делать подобные вещи, но это вполне возможно.

Реальная проблема здесь в том, что ваш бизнес-уровень не должен зависеть от вашего уровня представления.Зачем вам нужно ограничивать доступ к конкретному UserControl?Если у вас есть реальная необходимость (и я не могу придумать ни одного), чтобы бизнес-свойство set было доступно только из определенного класса пользовательского интерфейса, тогда требуется существенный редизайн вашего приложения.

0 голосов
/ 16 ноября 2011

Вы можете ограничить область действия get или set accessors следующим образом:

//private set accessor - this is what you're looking for
public int SomeProperty { get; private set; } 

//private get accessor
public int SomeOtherProperty { private get; set; }
...