У меня есть класс A с открытым методом в C#. Я хочу предоставить доступ к этому методу только к классу B. Действительно ли это возможно?
ОБНОВЛЕНИЕ:
Это - то, что я хотел бы сделать:
public class Category
{
public int NumberOfInactiveProducts {get;}
public IList<Product> Products {get;set;}
public void ProcessInactiveProduct()
{
// do things...
NumberOfInactiveProducts++;
}
}
public class Product
{
public bool Inactive {get;}
public Category Category {get;set;}
public void SetInactive()
{
this.Inactive= true;
Category.ProcessInactiveProduct();
}
}
Я хотел бы, чтобы другие программисты сделали:
var prod = Repository.Get<Product>(id);
prod.SetInactive();
Я хотел бы удостовериться, что они не называют ProcessInactiveProduct вручную:
var prod = Repository.Get<Product>(id);
prod.SetInactive();
prod.Category.ProcessInactiveProduct();
Я хочу предоставить доступ Категории. ProcessInactiveProduct только к продукту класса. Другие классы не должны мочь к категории вызова. ProcessInactiveProduct.
Поместите оба класса в отдельную сборку и сделайте метод внутренним.
Можно, если сделать класс A
приватным, вложенным внутри класса B
:
class B
{
class A
{
public Int32 Foo { get; set; }
}
}
Только B
сможет видеть A
и его члены в этом примере.
В качестве альтернативы можно вложить B
внутрь A
:
class A
{
Int32 Foo { get; set; }
public class B { }
}
В этом случае каждый может видеть и A
, и B
, но только B
может видеть A.Foo
.
Вы можете использовать шаблон типа «Наблюдатель», где Категория регистрирует интерес к определенным событиям в Продукте (возможно, событие ProductInactivated?), А затем обрабатывает логику соответствующим образом. Этот шаблон, основанный на событиях, очень распространен и значительно снижает взаимосвязь. Категория в конечном итоге несет ответственность за свое собственное состояние и не полагается на то, что Продукт знает что-то о том, что его содержит, чтобы сохранить состояние Категории в неизменном виде. Продукт просто сообщает заинтересованным клиентам, когда с ним что-то случилось.
Другой вариант - провести рефакторинг вашего класса Category, чтобы он содержал или содержался в некотором объекте CategoryProductServices, который инкапсулирует методы, которые Продукт должен будет выполнить для своей содержащей Category. В контексте, который создает категории и продукты, передайте экземпляр этого объекта CategoryProductServices в продукт, а не полную категорию. Такой дизайн делает интерфейс общедоступным, но не позволяет вашему клиенту получить доступ к службам, поскольку они не могут получить экземпляр. Это также ослабляет тесную привязку Продуктов к классу Category, ограничивая его только теми услугами, о которых Продукты должны знать. Это оставляет Продукт ответственным за состояние, но, по крайней мере, ограничивает то, что ему нужно знать / делать.
На ваш вопрос нет готового ответа.
Если они уже находятся в одной сборке, почему бы не сделать метод внутренним?
Если они находятся в разных сборках, вы можете использовать синтаксис "friend", который охватывает все внутренние методы.
Вероятно, лучшим решением будет ограничить доступ к публичным методам конкретной сборкой (сборками). Это означает, что кто-то не сможет просто написать новую сборку и вызвать ваши публичные методы. Учитывая, что у вас есть модель домена, похоже, что вы должны разрешить вызов этого метода из других объектов домена, но, возможно, не из бизнес-логики. Этого можно достичь, назначив уникальное сильное имя DLL модели домена.
Вы можете ограничить доступ к публичному методу, чтобы разрешить его вызов только методами в сборках, удовлетворяющих заданному публичному ключу. см. msdn StrongNameIdentityPermission