Click here to Skip to main content
15,888,016 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am working on a GUI framework. The framework is a WPF executable that can load ‘modules’ (.NET assemblies) that belong to components. The framework can show views that are defined in a module. Each main project in the organization creates their own component. Each component is a VS solution with multiple projects containing views and a reference to the framework executable which is the startup project.

Some modules of a component need to interface with a module of another component. There is a requirement to store in the interface between them in a human readable format. Preferably XML, but C# is okay too. However, It is not allowed for Project A to have references to Project B.

Anyone got a good idea for a clean implementation?

Currently, it’s done by having a single C# file with the interface in a central place. Project A and B both have a symbolic link to it and compile it. Both projects need to implement the interface. If A needs B, the framework offers some functionality (implemented via reflection) so the implementation at A side can invoke the method at B side. This works okay but gets complicated when you want to pass around types that are defined in the interface file: each side will have its own compiled version, and although they are the same you cannot cast them to each other. So A needs to create an instance in B (again via reflections) and move all properties from the object used a B side to the object at A side. This gets messy if the type is a class that has subclasses.

Any ideas for an alternative are welcome!
Posted

1 solution

It looks like what you need is the plug-in architecture.

In this case, referencing of assembly is not an option. You can load an assembly during run-time using System.Reflection or you can compile assembly out of source code and load it. Behind the scene, this second option is actually reduced to two steps: compilation and loading from a temporary file, but this can be hidden from you as an application developer. There is one more difficult option: emitting the assembly code during run-time using System.Assembly.Emit.

The possible architectural solution are classified into two dramatically different classes: 1) if you need to load the plug-ins; 2) if you need to re-load them during run-time.

The second type of requirement makes programming way more difficult. However, this is quite doable.

The example of the second type if a kind of ".NET calculator" or a miniature "Visual Studio". If you want to enter some source code, compile it, process compilation errors, and, in case of success, load it and execute some loaded code, you would need to unload loaded code every time you want to load the new one, otherwise you would create a memory leak. The problem here is: there is no a way to unload a loaded assembly! The solution is: load an assembly in a separate Application Domain and unload the whole domain. Domain are very well isolated from each other, as well as different processes. In this way, you would have to work throw the Application Domain boundaries, which is much more difficult. Essentially, the mechanism for passing data is IPC (Inter-Process Communication).

In my past solutions, I actually provided enough information and a good deal of advice. Please see:
Create WPF Application that uses Reloadable Plugins...[^],
AppDomain refuses to load an assembly[^],
code generating using CodeDom[^],
Dynamically Load User Controls[^],
how to Catch an unhandled exception thrown from a sub domain when calling a method by inkove(reflection)[^].

Sorry, those posts are irregular, linked to each other; a log of information is repeated. Also, the very first inquirer asked overly tricky and vague question (probably did not really understand what he wanted), so I discussed overly difficult problems (out of fun, maybe) which should not concern you. The whole architecture should be simpler, the idea to compose a UI across Application Domain is wrong.

If you read them and still need an advice on your particular situation, please write a comment. Chances are, you will see a solution by yourself.

—SA
 
Share this answer
 
v3
Comments
Espen Harlinn 25-Jan-12 14:05pm    
Impressed again :)
Sergey Alexandrovich Kryukov 25-Jan-12 14:06pm    
Thank you, Espen.
--SA
Dropmans 26-Jan-12 3:29am    
SAKryukov: Thank you for your elaborate answer, but perhaps my question was not clear enough. The whole architecture of the framework and main projects in the organization using that for their components has been up and running for some years. We are not going to change that.

What I was asking was, given that architecture, how can component-modules interface with each other (the 2nd paragraph). We are looking for alternatives to the mechanism mentioned in the 3th paragraph.

Again, thanks for the effort.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900