Modules and Dependencies

Arokh

Centurion
Joined
Apr 11, 2006
Messages
124
Hi,
I'm currently rewriting a program so that it can be modularised and it is progressing well,
but now I have a problem which I'm having problems with:

Lets say I have two projects.
The Main project with class main and
another project Extention with class ext.

Now assume 'class ext' is an extended version of a Dictionary object and it is used in many other objects.
So the project Extention cannot depend on the Main project.

But the Main Project cannot depend on the Extention Project either since I want to make the Main Project modular,
so basically I want the possibillity to either exchange the Extention Project with another Project,
which implements the same needed methods or even to not include it, without the Main Project throwing errors.

I've tried creating identical Interfaces in both Projects and
then cast the one Interface into the other but as expected it threw an exception.

An example to better understand what I'm trying to do:
[CSharp]//Project Main
class Main{
iExt dict;

private iExt GetExtention(){
dict = (iExt)[Retrieve class Ext from Project Extention']
}
}

interface iExt{
object GetValue();
}


//Project Extention
class Ext : iExt{

}

interface iExt{
object GetValue();
}

//No dependencies set between the two Projects
//Project Extention can be replaced by another Project which implements iExt
//If there is no Project which implements iExt the Main Project shouldn't throw an error[/CSharp]

Is there a way to pull this off, or is it impossible/to complex to do?
 
Yeh, you can pull off that scenario with a loosely typed language, but .Net is strongly typed.


In my experience, interfaces are seperated into their own assembly. If you put IExt into a seperate assembly and reference it from both main and whatever project you are using, then the extension project will be replaceable. Although your definition of replaceable is somewhat inflexible, as the solution needs to be recompiled.

Also, the guideline for naming interfaces is to prepend a capital I.
Also, extention is not a word, but extension is.

and you should declare scope for all class variables, ie. the dict variable.

and finally, one more tip, put more thought into the design.
Maybe you should be dynamically loading assemblies to get a certain class?
or using generics to strongly type the extension class?
 
One way would be to put the common interfaces / base classes into a 3rd library and have both the main project and the extension project reference this common library.

In the extension library have your classes implement the interfaces from the common library and in the main project have the application use these interfaces.

At runtime the Main project would need to load the extension library dynamically via reflection (not too difficult) and create an instance of the class. One way to make this 'tidier' is to implement a basic factory pattern in the common library and have it do the creation / loading of the real extension library.
 
One way would be to put the common interfaces / base classes into a 3rd library and have both the main project and the extension project reference this common library.

Thats the way I'm currently doing it.
I was just hoping to be able to completly sever any dependency link between the two Projects.
Because the way it is now I still need something that is known by both projects.
Main --> Lib <-- Ext

I already have a library for such common interfaces and base classes in my project.
So including the interface there, which is known by both parties is a little too much,
since it also includes many things not needed by the extension project.
It would also force me to load this library for every other project which references this extension.
Which would mean I have to create another library so the dependency would look like this:
Main --> Lib --> ExtLib <-- Ext

Which also seems like an odd solution since this issue is not only limited to this one extension.
So that would be one extra library per extension.

It seems more like my project management is the issue here:
I keep the libraries (or extension to be coherent with the previous example) which I use frequently
at one central place and if one project uses them, I only make references to them.
That way I can update a library and the projects using it would also be updated.

But if I were to make a modified copy of the library it would solve the problems I'm having instantly,
at the expense of having to maintain different versions of the same library.

I guess I'll make the modified copies of the libraries, since it is the solution with the fewest compromises.
 
Multiple copies of the same library are likely to be a maintenance burden though, if these things are genuinely supposed to be reusable then perhaps it is more of a design issue rather than a physical packaging issue.

If the interface isn't changing then you should be able to build clients that could be built against the old version but still use the newer versions.

If you are changing the interfaces between versions then you could create new interfaces that inherit the old ones to maintain compatibility. If that isn't suitable then perhaps the interfaces themselves aren't being thought out correctly in the first place.
 
Ok to be more concrete:

I keep my end-user projects in the project root folder.
The library projects I use for them are stored in a subfolder called components.

The project(solution) I'm currently working on called AniTracker uses two of these libraries.
(These two libraries are also used by many other projects.)

The two libraries in question:
Memory
Something I wrote to store and retrieve program settings also loading and saving them when the program open or closes.
I couldn't bring myself to like the way .NET handles this, so I wrote my own.

MultiKeyDictionary (I couldn't find a better name)
Something that acts like a database if I were to describe it in a few words. An example:
I have a list of 8000 entries of fileinformation which between other things contain FileID, SeriesID, FilePath etc..
Now I want to easily get all files which contain the same SeriesID.
It just let me does that.

Neither of these two libraries implement an interface or depend on another library.

Now since I want to make my project(solution) AniTracker completely modularised,
the project AniTracker (inside the solution AniTracker) is more like a framework I guess.
It loads any dll file it can find in its Plugin folder and
if the dll file contains classes which implement the interface IMod it gets loaded and instantiated.

Those instantiated plugins get an interface passed to its constructor (IAT)

[CSharp]public interface IAT
{
Modules.iMod GetModule(string modName);
}[/CSharp]

With this every plugin is able to get another loaded plugin by its name.
This works well since every plugin specifically written for my program AniTracker implements the IMod interface,
which for the libraries Memory & MultiKeyDictionary is obviously not the case.

And there is also my problem:
If I make a dependency to any of those two libraries so I can use them,
I loose the ability to use other libraries which achieve the same objective.
Meaning the end-user can't implements ones own Memory library and use it in conjuction with my program.

If I create an interface which then those libraries implement,
I have to put the interface into something my program AniTracker has access to.
That would be either my AT_Lib (the library which contains all my base classes & interfaces for my program AniTracker)
which is a bad solution since any other unrelated project which uses one of those libraries would also need to reference the AT_Lib library,
or I create another library which only contains the needed interface but that would also require me to reference this additional library to all of my projects.

Sorry this post gotten longer than I expected.
But hopefully you understand my problem now.

If you have a solution to this or found an error in my "logic", let me know.
I'm always happy to learn something new or make something better.
 
Last edited:
Back
Top