简体   繁体   中英

Class implementations in interface dll?

my problem: Inside an application, all interfaces are declared inside an own dll(project "interfaces", for example).

Inside project interfaces, there are many class implementations, too.

Now I need one of this implemented classes inside another project and get a ring dependency because this project is also a reference in project interfaces.

So, what is the best way to get around this ring dependency? Could it be possible that this is a big mistake in the design of the application?

Schematic representation:

IBigInterface.cs (everything in one file):

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

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

newProject.cs (everything in one file):

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

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

First thing that comes into my mind would be sth. like:

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
        //
    }
}

so that project newProject wouldn't be a reference in project interfaces anymore (although this means changes in the whole application).

PS: I inherited this application so the idea of implementing classes in an interface-project was not my idea :). In General, I would create one file per class (so don't point to this :).

First, there's nothing wrong with combining concrete classes and the interfaces they implement into a single assembly (though it would be a bit strange to call the project "interfaces").

Having said that, circular references are usually a sign that you've over-modularized your code: the parts causing the circular reference belong together and they should be merged into a single assembly.

Other times, a circular reference is just a sign that a class is in the wrong layer; the class needs to be moved into another assembly altogether (usually out of a lower-level infrastructure assembly and into a higher-level assembly). For example, ClassC might really belong in another project that references the "interfaces" assembly.

That's exactly the reason why Java requires public definitions to be in their own files (but I think you get the concept here :)).

It's usually not good to mix pure interface and implementation (though there are cases where it could be useful), and it's definitely a troublemaker if you export those into DLLs.

A cyclic dependency means your projects are too coupled to be distinct. This is usually a symptom of bad design ( big ball of mud -like). You should either work on removing that coupling or merge both projects together.

If you have a specific project that, as you say, contains all your interfaces, why not introduce another project that contains "helper classes" such as ClassA ? Then your interface DLL and the projects depending on the interface DLL could use the classes.

I would try to factor out the classes and interfaces that are common to several projects into a "Common" assembly (or similar), which has no dependencies to the assemblies that reference it.

For example, a business entity such as Product does not have to know anything about how it is persisted to a database or fetched via a web service, but the service components that do things with Product , for example IProductsRepository , needs to know what a Product is. Thus the assembly (or namespace) where IProductsRepository is defined holds a reference to the assembly (or namespace) where Product lives, but not the other way around.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM