2013-10-15 2 views
0

В следующем сценарии (простите мой псевдокод):Возможно ли иметь встроенный модификатор доступа при создании экземпляра, а не в декларации?

Assembly Lib: 
    Interface A; 
    Class 123; //Utilizes multiple properties with a { get; internal set; } pattern. 

    //Contains more class definitions like Class 123 

Assembly Impl: //References Lib 
    Class MyImpl; //Implements Interface A and utilizes Class 123. 


ClientApplication: 
    //Consumes Interface A 

мне было интересно, если есть способ, чтобы класс MyImpl для доступа к набору свойств() класса 123 без использования статический объявленный друг сборок и сохранения тех, set() также скрыт от ClientApplication.

Конечной целью является возможность развертывания таким образом, который позволяет ClientApplication использовать типы из AssemblyLib и возможность отбрасывать новые сборки реализации без необходимости перекомпилировать и распространять Assembly Lib.

Я думал что-то вроде того, как найти способ сделать внутренний модификатор вступать в силу при его создании (Assembly Impl), а не в его объявлении (Assembly Lib), но я не верю, что C# поддерживает что-то подобное.

Я понимаю, что это, вероятно, очень уродливое, если это можно сделать, и я не уверен, что это возможно, но, увы, именно поэтому я здесь! Заранее благодарны за Вашу помощь.

+0

Я не понимаю, почему вы нуждаетесь в MyImpl, чтобы иметь возможность доступа к внутренним элементам 123. Как это связано с «возможностью отказаться от новых сборок реализации без необходимости перекомпилировать и перераспределить Ассамблею Lib»? Как это часто бывает с внутренними элементами, если вы не можете настроить свой дизайн так, как они работают, то, вероятно, что-то не так с вашим дизайном. –

+0

Можете ли вы изменить его таким образом, чтобы классы и интерфейсы Lib-сборщика не определяли настройки для свойств (определяли только геттеры), а затем определяли внутренние сеттеры в сборке Impl? Это имеет смысл только в том случае, если сборка Lib предназначена только для абстрактных классов и интерфейсов, а Impl - это фактическая реализация. –

+0

@BorisB. Это похоже на то, как я пойду. Мне действительно нравится реализация Давидса ниже. – Gyrien

ответ

2
  1. Вы могли бы использовать отражение для доступа к внутренностям Lib. Это не очень хорошее решение.
  2. Вы можете сделать Impl другу сборку Lib. Это не очень хорошее решение.
  3. Вы можете перестроить свой дизайн, чтобы исправить необходимость использования Impl для доступа к внутренним частям Lib. Это приятное решение.

Используя ваш пример, вот идея того, что я получаю. Почему бы не изменить конструкцию на:

Assembly Lib: 
    Interface A; 
    Interface B; //Utilizes multiple properties with a { get; } pattern. 

    //Contains more interface definitions like Interface B 

Assembly Impl: //References Lib 
    Class 123; //Utilizes multiple properties with a { get; internal set; } 
       //pattern. Implements B. 

    //Contains more class definitions like Class 123 

    Class MyImpl; //Implements Interface A and utilizes Class 123. 

ClientApplication: 
    //Consumes implementations of Interface A and B provided by Impl. 
+0

Дэвид, мне очень нравится этот дизайн, и я думаю, что буду двигаться к этому. Спасибо за кучу за вашу помощь, я не могу поверить, что я не думал об этом, чтобы начать! – Gyrien

0

Для этого вам может понадобиться InternalsVisibleToAttribute.

Например, в вашей Lib сборке, добавьте следующую строку в файл assemblyinfo.cs:

[assembly:InternalsVisibleTo("Impl")] 
+2

Есть две проблемы: 1. InternalsVisibleTo - это запах кода. Необходимость использовать это - признак того, что в вашем решении есть что-то не так. 2. Это использование предотвращает подписание сборок или требует, чтобы новая версия Lib была распространена с каждой новой версией Impl, чтобы синхронизировать подписанные сборки. –

 Смежные вопросы

  • Нет связанных вопросов^_^