Реализации классов в интерфейсе dll? - PullRequest
0 голосов
/ 03 декабря 2009

Моя проблема: Внутри приложения все интерфейсы объявлены внутри собственной библиотеки DLL (например, "интерфейсы проекта").

Внутри интерфейсов проекта также есть много реализаций классов.

Теперь мне нужен один из реализованных классов внутри другого проекта и я получаю кольцевую зависимость, потому что этот проект также является ссылкой в ​​интерфейсах проекта.

Итак, как лучше обойти эту кольцевую зависимость? Возможно ли, что это большая ошибка в дизайне приложения?

Схематическое изображение:

IBigInterface.cs (все в одном файле):

interface ISomeInterfaceA
{
    void SomeFunctionA(ClassB x);    // ClassB from newProject.cs
    void SomeFunctionB();
}

//
// etc.
//
class ClassA
{
    //
    // Code
    //
}

newProject.cs (все в одном файле):

class ClassB
{
    //
    // used in interfaces.dll
    //
}

class ClassC
{
    void SomeFunction(ClassA a)    // ClassA from IBigInterface.cs
    {
        //
        // do something
        //
    }
}

Первое, что приходит мне в голову, это что-то. как:

IBigInterface.cs:

interface ISomeInterfaceA
{
    void SomeFunctionA(IInterfaceB x);    // use interface instead of a class
    void SomeFunctionB();
}

interface IInterfaceB
{
    //
    // declarations
    //
}

class ClassA
{
    //
    // implementation
    //
}

newProject.cs:

class ClassB : IInterfaceB    // implementation of IInterfaceB
{
}

class ClassC
{
    void SomeFunction(ClassA a)
    {
        //
        // implementation
        //
    }
}

, чтобы проект newProject больше не был ссылкой в ​​интерфейсах проекта (хотя это означает изменения во всем приложении).

P.S .: Я унаследовал это приложение, поэтому идея реализации классов в интерфейсном проекте не была моей идеей :). В общем, я бы создал один файл для каждого класса (поэтому не указывайте на это:).

Ответы [ 4 ]

6 голосов
/ 03 декабря 2009

Во-первых, нет ничего плохого в объединении конкретных классов и интерфейсов, которые они реализуют, в одну сборку (хотя было бы немного странно называть проект "интерфейсами").

Сказав это, циклические ссылки обычно являются признаком того, что вы чрезмерно модулировали свой код: части, вызывающие циклическую ссылку, объединяются, и их следует объединить в одну сборку.

В других случаях циклическая ссылка - это просто знак того, что класс находится не в том слое; класс должен быть полностью перемещен в другую сборку (обычно из сборки инфраструктуры более низкого уровня и в сборку более высокого уровня). Например, ClassC может действительно принадлежать другому проекту, который ссылается на сборку "интерфейсов".

1 голос
/ 03 декабря 2009

Если у вас есть конкретный проект, который, как вы говорите, содержит все ваши интерфейсы, почему бы не представить другой проект, содержащий «вспомогательные классы», такие как ClassA? Тогда ваша интерфейсная DLL и проекты, зависящие от интерфейсной DLL, могут использовать классы.

1 голос
/ 03 декабря 2009

Именно поэтому Java требует, чтобы публичные определения были в их собственных файлах (но я думаю, что вы поняли концепцию здесь:)).

Обычно нехорошо смешивать чистый интерфейс и реализацию (хотя бывают случаи, когда это может быть полезно), и определенно проблематично, если вы экспортируете их в DLL.

Циклическая зависимость означает, что ваши проекты слишком связаны, чтобы различаться. Обычно это признак плохого дизайна ( большой шарик грязи -подобный). Вам следует либо поработать над удалением этой связи, либо объединить оба проекта вместе.

0 голосов
/ 03 декабря 2009

Я бы попытался выделить классы и интерфейсы, которые являются общими для нескольких проектов, в «общую» сборку (или аналогичную), которая не имеет зависимостей от сборок, ссылающихся на нее.

Например, бизнес-объект, такой как Product, не должен ничего знать о том, как он сохраняется в базе данных или извлекается через веб-службу, но компоненты службы, которые делают вещи с Product, например IProductsRepository, необходимо знать, что такое Product. Таким образом, сборка (или пространство имен), где определено IProductsRepository, содержит ссылку на сборку (или пространство имен), в которой находится Product, но не наоборот.

...