Plugin based application in C# - c#

I have to make a graphical user interface application using the language of my choice. The application will run on Windows XP. It will be some sort of a complex windows form application.
I think and as per most suggestions, C# will be the best to use.
The tree structure on the left of the GUI will populate after reading from a configuration file which will be a binary file . (but initially I can work with a simple ASCII file to test my code.). The application will accept some inputs from the user through this GUI and will write the back to the same config file and will reflect the changes in the tree structure or the labels or any other pertaining field on the form.
There will be 3 tabs and 3 corresponding config files for each of the tabs.
I need some help designing the application for now. I am planning to make a host application (main application) and use the 3 tab controls as plugins. Is this workable ? If so can you please guide me on this. I mean how do I make 3 plugins in C# and how do I write the interfaces so that the main application knows which plugin to load and when to load it ? Will there be a separate “Plugin” folder under my project folder ? I hope you got my point though this is too little of an information for you to begin with.
Also there are some .cpp files already existing in the project. These files along with some .h files contain some important definitions and constants in them. These need to be integrated with my C# application. I have no clue how to do that but I am sure that it is possible by compiling the .cpp code in a .dll and then exposing the compiled .dll to my C# application. Please let me know if you need some more information for the top level design.
Thanks,
Viren

To implement a plugin interface manually, you will need a method something like this. I've left some TODOs in, where you would want to enhance the error handling and/or make the implementation a little more case specific.
public List<T> LoadPlugin<T>(string directory)
{
Type interfaceType = typeof(T);
List<T> implementations = new List<T>();
//TODO: perform checks to ensure type is valid
foreach (var file in System.IO.Directory.GetFiles(directory))
{
//TODO: add proper file handling here and limit files to check
//try/catch added in place of ensure files are not .dll
try
{
foreach (var type in System.Reflection.Assembly.LoadFile(file).GetTypes())
{
if (interfaceType.IsAssignableFrom(type) && interfaceType != type)
{
//found class that implements interface
//TODO: perform additional checks to ensure any
//requirements not specified in interface
//ex: ensure type is a class, check for default constructor, etc
T instance = (T)Activator.CreateInstance(type);
implementations.Add(instance);
}
}
}
catch { }
}
return implementations;
}
Example to call:
List<IPlugin> plugins = LoadPlugin<IPlugin>(path);
As for the c++ part of your question. There are few different ways you could approach this, though the correct choice depends on your specific situation. You can make a clr compliant .dll in c++, which your c# project could reference and call like any other .dll it references. Additionally, you could use P/Invoke to call into a native .dll.

One of the easiest plugin concepts I have ever used was certainly the Managed Extensibility Framework which will be part of .NET 4 (afaik). Unfortunately it is not yet finished and only a preview is available which may differ from the final version. That being said, we used MEF Preview 3 for a uni project and it worked without problems and it certainly made the whole plugin stuff a lot easier.

Look at the System.Addin namespace :
http://msdn.microsoft.com/en-us/library/system.addin.aspx
Otherwise you can do everything yourself. Before this namespace was available, I used a common interface "IPlugin" that every plugin/addin needed to use. I then had a loader which inspected all the *.dll in a folder then used reflection to check for the interface. I could then create instances of classes which implemented my plugin/addin interface
The cpp files will probably need converting to c#, or you could possibly create a dll to reference.

Take a look to Castle.

.NET Framework use COM model in its guts. See http://blog.caljacobson.com/2007/07/26/creating-a-plug-in-framework-in-c-resources/ for a list of plugin example using this techique.

Related

Is it possible to add C# classes immediately before compilation in Visual Studio

Now I programmatically generate sources and create some classes before compilation and obviously add it to project in solution. Maybe it is possible to "silently" add classes before compilation without creating .cs files in disk and not showing these classes in Solution Explorer (maybe using Roslyn).
EDIT: I must not use any runtime code generation.
You can put the classes in a separate DLL (class library). When you create that DLL using another solution you will not see the classes in your solution explorer of the project where you include them.
Don't forget to add a reference to the DLL (class library) in your main project.
You could probably do something with MSBuild, creating a custom project target which does the work, but I've never done this.
What I have done recently which is now achievable on the DNX-based ASP.NET 5 platform, is a concept known as meta-programming. I've written a blog article about this concept specifically with examples of generating code at compile time. In my particular example, I've got a class that won't compile, but then with an introduction of an ICompileModule, I can fill in the missing method return statement at compile time.
This is possible because in DNX-based applications, the RoslynCompiler class actually supports loading instances of ICompileModule at compile time, and then running these instances before your main project compilation. This enables you to add/remove/replace syntax trees in the compilation before the compiler finishes its work.
If you're looking to develop on ASP.NET 5, this could enable you to do what you need, but I don't know how you would go about doing this otherwise.
Seems quite aspecty to me.
I asked a question which I also answered myself about engineering a compile-time solution that performs code generation for another scenario:
Getting interface implementations in referenced assemblies with Roslyn
And lastly, other examples where this might be useful, and something I've been toying around with, is the ability to generate EF-style migration classes from .sql files embedded in my assemblies. All these scenarios are now easier for me to implement on ASP.NET 5 + Roslyn.
Without knowing your use-case properly, here's an idea...
Create a VSIX that listens to an 'on build' event
Upon initialisation of the build, the VSIX creates your new classes*
The same VSIX will also listen for a 'build complete' event
Upon completion of the build the VSIX would tear down the new classes
*Your question states that the classes should not be created on disc, so the VSIX could
create the classes as a memory stream (?)
add the new class as code within existing files on disc
create the new class as a new file on disc (or cloud ?) in C:\Temp or elsewhere
the new class could be part of a partial class (either a real partial class in your application or an empty new dummy partial class)
In any case the project file would need to be auto-edited (by the vsix) to reference the new file(s). Presumably you want the project file reverted aferwards ?
And if, unlike me, you want to get down and dirty, you could always interfere with the IL, but you're on your own there !
As TarkaDaal says, without knowing why you need this it's not easy to provide a more definative answer.

Interface change between versions - how to manage?

Here's a rather unpleasant pickle that we got into on a client site. The client has about 100 workstations, on which we deployed version 1.0.0 of our product "MyApp".
Now, one of the things the product does is it loads up an add-in (call it "MyPlugIn", which it first looks for on a central server to see if there's a newer version, and if it is then it copies that file locally, then it loads up the add-in using Assembly.Load and invokes a certain known interface. This has been working well for several months.
Then the client wanted to install v1.0.1 of our product on some machines (but not all). That came with a new and updated version of MyPlugIn.
But then came the problem. There's a shared DLL, which is referenced by both MyApp and MyPlugIn, called MyDLL, which has a method MyClass.MyMethod. Between v1.0.0 and v1.0.1, the signature of MyClass.MyMethod changed (a parameter was added). And now the new version of MyPlugIn causes the v1.0.0 client apps to crash:
Method not found: MyClass.MyMethod(System.String)
The client pointedly does not want to deploy v1.0.1 on all client stations, being that the fix that was included in v1.0.1 was necessary only for a few workstations, and there is no need to roll it out to all clients. Sadly, we are not (yet) using ClickOnce or other mass-deployment utilities, so rolling out v1.0.1 will be a painful and otherwise unnecessary exercise.
Is there some way of writing the code in MyPlugin so that it will work equally well, irrespective of whether it's dealing with MyDLL v1.0.0 or v1.0.1? Perhaps there's some way of probing for an expected interface using reflection to see if it exists, before actually calling it?
EDIT: I should also mention - we have some pretty tight QA procedures. Since v1.0.1 has been officially released by QA, we are not allowed to make any changes to MyApp or MyDLL. The only freedom of movement we have is to change MyPlugin, which is custom code written specifically for this customer.
The thing is that the changes you made have to be basically in addition and not the change. So if you want to be back compatible in your deployment (as much as I understood in current deployment strategy you have this is an only option) you should never change the interface but add a new methods to it and avoid tight linking of your plugin with shared DLL, but load it dynamically. In this case
you will add a new funcionality without disturbing a old one
you will be able to choose which version of dll to load at runtime.
I have extracted this code from an application I wrote some time ago and removed some parts.
Many things are assumed here:
Location of MyDll.dll is the current directory
The Namespace to get reflection info is "MyDll.MyClass"
The class has a constructor without parameters.
You don't expect a return value
using System.Reflection;
private void CallPluginMethod(string param)
{
// Is MyDLL.Dll in current directory ???
// Probably it's better to call Assembly.GetExecutingAssembly().Location but....
string libToCheck = Path.Combine(Environment.CurrentDirectory, "MyDLL.dll");
Assembly a = Assembly.LoadFile(libToCheck);
string typeAssembly = "MyDll.MyClass"; // Is this namespace correct ???
Type c = a.GetType(typeAssembly);
// Get all method infos for public non static methods
MethodInfo[] miList = c.GetMethods(BindingFlags.Public|BindingFlags.Instance|BindingFlags.DeclaredOnly);
// Search the one required (could be optimized with Linq?)
foreach(MethodInfo mi in miList)
{
if(mi.Name == "MyMethod")
{
// Create a MyClass object supposing it has an empty constructor
ConstructorInfo clsConstructor = c.GetConstructor(Type.EmptyTypes);
object myClass = clsConstructor.Invoke(new object[]{});
// check how many parameters are required
if(mi.GetParameters().Length == 1)
// call the new interface
mi.Invoke(myClass, new object[]{param});
else
// call the old interface or give out an exception
mi.Invoke(myClass, null);
break;
}
}
}
What we do here:
Load dynamically the library and extract the type of MyClass.
Using the type, ask to the reflection subsystem the list of MethodInfo present in that type.
Check every method name to find the required one.
When the method is found build an instance of the type.
Get the number of parameters expected by the method.
Depending on the number of parameters call the right version using Invoke.
My team has made the same mistake you have more than once. We have a similar plugin architecture and the best advice I can give you in the long run is to change this architecture as soon as possible. This is a maintainability nightmare. The backwards compatibility matrix grows non-linearly with each release. Strict code reviews can provide some relief, but the problem is you always need to know when methods were added or changed to call them in the appropriate way. Unless both the developer and reviewer know exactly when a method was last changed you run the risk of there being a runtime exception when the method is not found. You can NEVER call a new method in MyDLL in the plugin safely, because you may run on a older client that does not have the newest MyDLL version with the methods.
For the time being, you can do something like this in MyPlugin:
static class MyClassWrapper
{
internal static void MyMethodWrapper(string name)
{
try
{
MyMethodWrapperImpl(name);
}
catch (MissingMethodException)
{
// do whatever you need to to make it work without the method.
// this may go as far as re-implementing my method.
}
}
private static void MyMethodWrapperImpl(string name)
{
MyClass.MyMethod(name);
}
}
If MyMethod is not static you can make a similar non-static wrapper.
As for long term changes, one thing you can do on your end is to give your plugins interfaces to communicate through. You cannot change the interfaces after release, but you can define new interfaces that the later versions of the plugin will use. Also, you cannot call static methods in MyDLL from MyPlugIn. If you can change things at the server level (I realize this may be outside your control), another option is to provide some sort of versioning support so that a new plugin can declare it doesn't work with an old client. Then the old client will only download the old version from the server, while newer clients download the new version.
Actually, it sounds like a bad idea to change the contract between releases. Being in an object-oriented environment, you should rather create a new contract, possibly inheriting from the old one.
public interface MyServiceV1 { }
public interface MyServiceV2 { }
Internally you make your engine to use the new interface and you provide an adapter to translate old objects to the new interface.
public class V1ToV2Adapter : MyServiceV2 {
public V1ToV2Adapter( MyServiceV1 ) { ... }
}
Upon loading an assembly, you scan it and:
when you find a class implementing the new interface, you use it directly
when you find a class implementing the old interface, you use the adapter over it
Using hacks (like testing the interface) will sooner or later bite you or anyone else using the contract - details of the hack have to be known to anyone relying on the interface which sounds terrible from the object-oriented perspective.
In MyDLL 1.0.1, deprecate the old MyClass.MyMethod(System.String)and overload it with the new version.
Could you overload MyMethod to accept MyMethod(string) ( version 1.0.0 compatible) and MyMethod(string, string) (v1.0.1 version)?
Given the circumstances, I think the only thing you can do really is have two versions of MyDLL running 'side by side',
and that means something like what Tigran suggested, loading the MyDLL dynamically - e.g. as an a side example not related but might help you, take a look at the the RedemptionLoader http://www.dimastr.com/redemption/security.htm#redemptionloader (that's for an Outlook plugins which often have problems crashing to each other referencing different versions of a helper dll, just as a background story - that's a bit more complex cause of the COM involved but doesn't change much here) -
it's what you can do, something similar. Load dynamically the dll by it's location, name - you can specify that location internally, hard-code, or even set it up from config or something (or check and do that if you see that MyDll is not of the right version),
and then 'wrap' the objects, calls form the dynamically loaded dll to match what you normally have - or do some trick like that (you'd have to wrap something or 'fork' on the implementation) to make everything work in both cases.
Also to add on the 'no-nos' and your QA sorrows :),
they should not break the backward compatibility from 1.0.0 to 1.0.1 - those are (usually) the minor changes, fixes - not breaking changes, major version # is needed for that.

Library MAY need to reference the application using it? C#

Sorry for dodgy title, couldn't think of anything better...
Anyway, I have written a library for the viewing of a system basically. This library is used by the editor application of the system. Unfortunately, i got hit by the sudden need for the library to have a variable in one of its classes to access the editing application. Of course this isn't possible without a reference. The thing is, i feel it is unnecessary to reference the editor application when out of the hundreds of times this library may be used, only one of the applications using it (the editor), will mean the library needs to have the editor referenced to it.
I really hope that made sense.
In most cases : Application uses Library
In editor case: Editor uses Library uses Editor
I basically want a way around having to reference the editor from the library. All my requirements is for a variable of type (or a loop hole to access) MyClass (default value null) to be stored in the library. MyClass is part of the editor though, not the library, and i DO NOT want to have to reference the editor.
Thanks for any help!
Create an interface which you "Editor" implements. The library does not need to know the concrete implementation, it can work with the interface.

How to Make a "Dashboard" Utility that Accepts Modules/Add-Ins

I hope this question makes sense. Basically, I am looking for a set of guidelines, or even a tutorial, that will show how to make an application that can easily add and remove "modules" or "add-ins"
For example, in Microsoft Office, you will commonly see programs that you can download and install and they will just add an extra tab into Microsoft Word (for example) that will implement some new feature.
I have several applications that use basically the same data source, and I'd like to consolidate them and also leave open the possibility of adding more functionality in the future without 1. Requiring a brand new install and 2. Tweaking every piece of my code.
I'm looking for a place to start, mostly.
Thanks in advance.
**
Edit: To elaborate a little more...
The thing I have in mind specifically is an application that accesses a large set of data that is stored in text files and uses some of the data to create a few graphs and maybe some tables. I'd like the ability to add different graphs in the future using the same data. So, you can click Button_A and generate Graph_A, then a few weeks later, you can click Button_B and generate Graph_B.
It would be really nice if I could come up with a way that only required reading the data from the file(s) once, but I know that would involve having to adjust my DataReader class a bit.
One place to start would be to define an interface for your future modules, and build a utility that scans all the dll's therein, looking for classes that implement said interface.
Once you've found supporting classes you can create instances at runtime and add to your application. That's a common idiom in .NET for supporting "plug-ins"
The Activator class is a common way to create instances from a Type at runtime.
http://msdn.microsoft.com/en-us/library/system.activator.aspx
It's hard to give more details without more info in your question. Can you elaborate a bit?
Take a look at the Composite Application Library from Microsoft.
It is aimed at WPF but you could get some ideas from there.
As Adam said, the first thing to do is define the interface for your plugin modules - what can they expect to receive from the container, and what methods must the container be able to call?
As far as the container itself goes, I'm partial to MEF as a location technology; you can create catalogs and re-compose the system when new DLLs are added. I've built a similar system to this for parsing dissimilar files, and the composition capabilities of MEF are awesome for runtime discovery.

How to create a loosely coupled architecture with hot-swap capability?

I'm interested in creating a desktop application composed of modules such that the source code to those modules is embedded in the application itself, allowing the user to edit the application as they are running it and have the updated modules put into use without restarting the application. Can anyone suggest a good architecture for this?
I'm looking to use Microsoft.Net and C# for this. DLR is not an option.
Thanks!
It's not easy to suggest a good architecture for this in a short posting.
At first, i'd define a contract (an Interface) every module the user writes/modifies must implement. It should contain at least an Execute method.
Then I'd create a Wrapper-Class for these modules which:
loads the source code from a file
The wrapper compiles the file and also makes sure it implements the contract
Contains an indicator of whether the file could be compiled sucessfully
It should also implement the contract, for easy calling and handling
Then I'd have some kind of shell which contains a collection of all the module-wrappers. Any wrapper that sucessfully compiled would then let the Shell call the Execute method of the module interface.
When it comes to compiling and executing code on the fly, this link should provide all the information you need:
http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm
Well, a dynamic language certainly would have been the best fit...
You can use the types in the System.Reflection.Emit namespace to dynamically create assemblies.
However, it's going to be really painful because you'd need to load those dynamic assemblies into custom AppDomains because otherwise you'll not be able to unload them again.
This again means that you must address marshalling and assembly resolution issues related to cross-AppDomain communication.
What you are probably looking for is the concept of Dependency Injection.
Dependency Injection means that instead of having module X use module Y directly, module X only relies on an interface, and the application tells module X which implementation should use for it, e.g. using module Y.
There are several ways of implementing Dependency Injection. One is to have references to the interfaces in each of your modules, and explicitly let the application configure each of its modules with the right implementation of the interface.
The second wahy of implementing it (and probably the most useful in your case) is by using a central registry. Define all the interfaces that you want to have in your application. These are the interface for which you want to dynamically change the implementation. Then define identifications for these interfaces. These could be strings or integers or GUID's.
Then make a map in your application that maps the identifications to the interfaces, and fill the map with the correct implementations of the interfaces. In a C++ application (I'm not very skilled in C# yet) this could work like this:
std::map<std::string,IInterface> appInterfaces;
appInterfaces["database"] = new OracleDatabaseModule();
appInterfaces["userinterface"] = new VistaStyleUserInterface();
Make all modules go to this central registry whenever they want to use one of the modules. Make sure they don't access the modules directly, but they only pass via the registry. E.g.
MyModule::someMethod()
{
IDatabaseInterface *dbInterface = dynamic_cast<IDatabaseInterface *>(appInterfaces["database"]);
dbInterface->executeQuery(...);
}
If you now want to change the implementation for an interface in the application, you can simply change the entry in the registry, like this:
IInterface *iface = appInterfaces["database"];
if (iface) delete iface;
appInterface["database"] = new SqlServerDatabaseInterface();

Categories

Resources