Звучит как хороший кандидат для использования Dependency Injection. Для начала посмотрите этот пример на сайте Spring.NET. Извиняюсь за краткий ответ, но я могу уточнить, когда у меня будет больше времени, чтобы сесть и написать короткий пример, более подходящий для вашего поста.
EDIT:
Хорошо, давайте сначала представим два дочерних объекта, TinasModeling.Model и BobTheBuilder.Builder
public class Model : IPerson
{
private bool canAct;
public bool CanAct
{
get { return canAct; }
set { canAct = value; }
}
private double weight;
public double Weight
{
get { return weight; }
set { weight = value; }
}
public Model()
{
}
public bool PayPerson(double Amount)
{
if (canAct)
RequestFilmBoxOfficeRevenue();
Pay();
}
public bool NewJobRequest()
{
SendPhotoPortfolioToClient();
SendJobLocationToModel();
if (canAct)
NotifyFilmCrew();
if (weight < 40.00)
ContactNutritionist();
}
}
public class Builder : IPerson
{
private bool canOperateDigger;
public bool CanOperateDigger
{
get { return canOperateDigger; }
set { canOperateDigger = value; }
}
private double certifiedBuilder;
public double CertifiedBuilder
{
get { return certifiedBuilder; }
set { certifiedBuilder = value; }
}
public Builder()
{
}
public bool PayPerson(double Amount)
{
ReuqestTimeSheet();
Pay();
}
public bool NewJobRequest()
{
SendBluePrintsToBuilder();
if (!certifiedBuilder)
RequestLegalAdvice();
if (canOperateDigger)
RequestDrivingPermit();
}
Оба класса реализованы в отдельных проектах - они не обязательны, но по причинам, которые я объясню позже. Как вы можете видеть, они оба работают по-разному, но имеют одну общую черту: они реализуют интерфейс IPerson.
public interface IPerson
{
bool PayPerson(double Amount);
bool NewJobRequest();
}
Этот интерфейс реализован, опять же, в отдельной сборке, чем оба вышеупомянутых объекта, и, следовательно, наши дочерние объекты ссылаются на эту сборку, давайте назовем ее BOL (Уровень бизнес-объектов). В BOL мы реализуем другой класс под названием PersonController
public class PersonController
{
private IPerson thePerson;
public IPerson ThePerson
{
get { return this.thePerson; }
set { this.thePerson = value; }
}
public PersonController()
{
}
public bool PayPerson(double Amount)
{
return this.thePerson.PayPerson(Amount);
}
public bool NewJob()
{
return this.thePerson.NewJobRequest();
}
}
Самая важная вещь, которую следует отметить в PersonController, - это свойство ThePerson. Это будет наша точка внедрения зависимости. На этом этапе стоит отметить, что слой BOL полностью отделен от любых дочерних объектов. Это важная функция, обеспечивающая большую гибкость при развертывании и обслуживании.
Теперь мы используем и настраиваем то, что построили до сих пор. Наше приложение ссылается только на слой BOL (также отделяя наше основное приложение от любых дочерних объектов). В нашем основном приложении мы используем сборку Spring.NET Spring.Core, а в файл app.config добавляем следующее (для удобства чтения я опустил тег configSections)
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<description>An example that demonstrates simple IoC features.</description>
<object name="Person" type="BOL.BOL.PersonController, BOL.BOL">
<property name="ThePerson" ref="Person"/>
</object>
<object name="Person" type="BobTheBuilder.BobTheBuilder.Builder, BobTheBuilder.BobTheBuilder">
</object>
</objects>
Хорошо, надеюсь, все до сих пор со мной - первый элемент объекта относится к классу, который требует внедрения зависимости, в нашем случае PersonController. Дочерний элемент свойства ссылается на точку внедрения зависимости в PersonController или, в нашем случае, на свойство ThePerson. Атрибут ref этого элемента относится к нашему второму элементу объекта.
Второй элемент объекта, который мы устанавливаем, какой дочерний объект мы хотим внедрить во время выполнения (т.е. TinasModeling.Model или BobTheBuilder.Builder).
Наконец-то код, который собирает все вместе
static void Main(string[] args)
{
IApplicationContext ctx = ContextRegistry.GetContext();
PersonController person = (PersonController)ctx.GetObject("Person");
// Ready to use person with implementation specified in config
person.NewJob();
person.PayPerson();
}
Таким образом, это создаст экземпляр PersonController на основе того, как мы настроили «Person» в нашем app.config.
Таким образом, ответ на первый вопрос - нет (по крайней мере, как описано выше) - вы полностью отделяете свои базовые реализации.
Ответ на вопрос два ( Является ли это наилучшим способом построения этого ), вероятно, немного субъективен - но, с моей точки зрения, распространение и обслуживание являются вашей главной заботой, приведенный выше дизайн отвечает вашим потребностям, потому что сборки, которые на самом деле делают тяжелую работу, полностью отделены.
Надеюсь, я достаточно хорошо объяснил себя.