Implementing Plugin Architecture - Dynamic DLL loading - c#

I've an application which is basically a designer with preloaded controls where you can design your pages using the controls.
I'm planning to release more and more controls in the future. I don't want to release a new build for newly added controls as it has its disadvantages. So I was thinking of addon/plugin kind of architecture where I just release the addon/plugin separately which they can install and get the controls inside the designer.
Right now I'm using xml files as addons to specify the controls, its behaviors, its styles etc. Each xml (addon) represents a single control. But I'm finding it very difficult to implement this since I've to write a generic parser to read all the plugins.
Instead, can I release a dll for each addon which gives me more control to write code to define the behavior/look of the control and dynamically load it through the main engine? If so how can I check for dlls and load it dynamically in my application?

You might want to look at the Managed Extensibility Framework. This will probably solve most of your issues and more, but will require learning some new tech...
You should also definitely look into the System.Addin Namespace as mathieu suggests!
If you want to go with your own route, I suggest the following approach:
an interface for addons in your main application
implement that interface in addon dlls
load the dlls at runtime with Assembly.Load
you might want to look into loading the addon assemblies into a separate AppDomain

You should have a look at System.Addin namespace, as it really fits your need. After an addin is developped, you just have to drop it in a folder, and it is available (at runtime) for your application.
http://kentb.blogspot.com/2008/06/maf-gymnastics-skeletal-solution.html
See this question for comparison : Choosing between MEF and MAF (System.AddIn)

The MEF or System.Addins routes mentioned are likely the most efficient way to go about this. I only pipe in to say a few things about the alternatives.
I have "hand rolled" this sort of solution a number of times and I would say that unless there is a compelling reason to do it from scratch it is better to use an existing addin framework. But if you are going to do so, I have found dependency injection containers like Castle or (insert your preferred DI container here) to be help handle some of the mechanics.
Also depending on exactly the sort of thing you are looking to do, the approach of embedding a macro language is potentially useful. Iron Python is easily embeddable. And Ayende wrote a very interesting book DSLs in Boo on doing this sort of thing and much more.

Related

Modular System in .NET Able to be Altered at Runtime

Currently I'm working on a .NET hobby project that involves a complex system of objects which work in combination with eachother. However, I encountered a little problem, I am unable to find a mechanism in .NET to support replacing code at runtime, and be able to dispose of the old code, loaded previously. This means replacing a module/object dynamically and almost instantly displaying the changes to the user, for example, when he restarts a procedure, but not the whole program.
I have already taken into account the possibility of having separate AppDomain for each session and loading the necessary assemblies into it but this seems a little bit too expensive. I should also mention that every session benefits from a common base of assemblies, for instance, to connect to a database, so this means loading those classes into every single session. Marshalling data back and forth from the separate AppDomain also represents an additional overhead (could be used when data is sent to the client application through the network, code for this contained in the main AppDomain, which manages the sessions).
Is there a framework or way of replacing/unloading particular parts of code? How is it done in real-world applications? Can there be a workaround? Or have I picked the wrong set of tools?
You need some kind of plugin system with well defined interfaces. Then you load at runtime binaries (your plugin *.dll) and create objects from it and then execute methods on it.
When you create a system where objects from your plugins must be created through your IPluginManager you have no problem with replacing code at runtime. :)
Or
You have something like a folder with *.cs files which will on demand compiled (in memory) and create the objects you want to use from them and call the methods on them.
Which is basically the same like above, without compiling at run time.
From there you can make further improvements.
EDIT:
Like you wrote the only problem without using AppDomain is that once loaded assemblies can't be unloaded. But that's not really a problem.
I don't think you need separate AppDomains: you can dynamically load assemblies within the current AppDomain. And each assembly should probably implement some defined interfaces (depending on your usage). You could use the FileSystemWatcher class, for example, to load/unload assemblies as needed.
See http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx
You can have a look at MEF. It stands for: Managed Extensibility Framework .
Here's another article about it MEF on codeproject.
It is used to load dll's in runtime by composing them. This is what is usually used for plugins or anything else you kinda drop into a folder and expect it to run .
Here's a link to some more tutorials as well: Where can I learn about MEF?
Yes, you're right, it is not possible to simply unload an assembly (only AppDomains). But I think one of the features of ASP.Net vNext is the ability to have just in-memory assemblies and when you simply alter the source code on the drive it gets automatically compiled and loaded. Therefor a mechanism must exist to unload the previous version.
I think they are doing that by simply creating a AppDomain where all assemblies are loaded into again to avoid any cross domain communication. But i don't really know and maybe if you would dig more into the mechanism on how they do this stuff in ASP.NET you maybe find a good solution. More informations about the hot topics from vNext you can maybe also find at Scotts Blog.
Well, I've found 2 solutions that work for me, which I would like to share. The first one is to use CollectibleAssembly and define the types. This is certainly a bit tricky, and a number of restrictions are imposed on this type of dynamic assembies.
The other option is to use a scripting language like IronPython or IronRuby. Also a great feature of the new Roslyn compiler is that it also provides scripting APIs, not previously available in the .NET framework. What's more, the Roslyn scripting languages tend to look very much like their full-blown equivalents (C# or VB). And I've also found a tiny example of its capabilites.

Terminology for allowing patches/modifications to a C# game

I need to be able to allow mods/patches to a very simple game. Essentially I need to allow a folder full of DLL files to be loaded and have their functions override those of the original application.
I know the basics of a hook system where a line of code can be placed throughout the application source to "bring in" code from outside variables and the likes.
I have tried to search for this, however as I am not sure of the terminology I have ended up sifting through about 30 sites and coming back to gaming websites with instructions on how to specifically mods their games. This information was helpful but I need a little assistance
My question is: Is there an common term for what I am trying to achieve that will assist me in google searches?
You should probably look for .NET plug-in/add-in framework. .NET Fx since 3.5 contains its own add-in framework but that may be overkill for your requirement. As such what you want to achieve is quite simple in .NET - here's the broad outline of it:
Define various interfaces (hooks) that need to be implemented by third party. Package them in a separate dll with documentation.
Create a configuration item (a config entry) that will accept the fully qualified type name implementing the requisite interface.
In your program, load the type using the above config entry. You can use reflection for that (see Activator.CreateInstance). Cast the object to interface and use it.
Third party is supposed to provide implementation of these interfaces and place the dll under application folder. And modify config entry to put the type name.
Not sure, but given .NET context, MEF (Managed Extensible Framework) or System.AddIns could work.

Is there a way to give a plugin control of parts of an application directly in C#?

I have a .NET 2.0 application. What I want to do is create a plugin that has access to the main application in some way.
My reason is that I want to be able to add things like buttons and menu items to a form dynamically instead of having a menu item called "Plugins" that I update. This is so that I can add things to the application GUI without releasing the entire application again.
Right now I can think of two ways. One, I can create the plugin in such a way that it always expects a reference to the entire application, all forms included. I can give it access to whatever items I chose in the forms and it can add controls or whatever at will. This makes me a little uneasy, but if this is acceptable let me know.
The other way I can think of is to have some sort of Interface for each form in the main app such that I can use that interface to access the current forms in the app. I am not sure how to implement this, though.
All help, suggestions, website references and comments are appreciated.
Partly this comes down to who will write your plug-ins, do you trust them, and what happens to the user's experience or data when a plug-in goes bad?
Fiddler http://www.fiddler2.com/fiddler2/ is a Web Debugging Proxy that has a plug-in model very much like your first choice - expose everything to the plug-in writer and hope they don't screw up. This makes writing extensions to Fiddler very simple, but it does mean you need to be careful.
If you're unhappy about this approach I would suggest you take a close look at 2 .NET technologies that might help.
The first is the System.AddIn namespace http://msdn.microsoft.com/en-us/library/gg145020.aspx. The types in this namespace are designed to help you create applications that support AddIns.
The second is MEF http://mef.codeplex.com/. The Managed Extensibility Framework is a very powerful API for describing an applications requirements, and allows you to build highly extensible applications.
With regard to MEF and WinForms check out this SO question:
Winforms with MEF
The second approach would be preferible, you could create an interface IApplication with all of the modifyable / pluggable parts of your appilcations and require that all plugins implement and IModifyApp interface with some method like IModifyApp.Modify(IApplication) that takes an instance of the IApplication and returns a modified instance for the application to process.
You should also check out MEF The Microsoft managed extensibility framework.
What I have done before for this kinda scenario is used AppDomain. Which is like a process inside your main process. You can load and unload assemblies in the AppDomain w.o having to stop the main process and as long as your main process knows about interfaces loaded from the "updates" dll inside the AppDomain, it can consume it no problem. If not, then there are always reflections :)
You may want to give a look to something like CAB/Prism to address your needs. A lot of the UI-y-ness (technical term) is built in to that through a series of abstractions.
http://compositewpf.codeplex.com/

Proper API Design for Version Independence?

I've inherited an enormous .NET solution of about 200 projects. There are now some developers who wish to start adding their own components into our application, which will require that we begin exposing functionality via an API.
The major problem with that, of course, is that the solution we've got on our hands contains such a spider web of dependencies that we have to be careful to avoid sabotaging the API every time there's a minor change somewhere in the app. We'd also like to be able to incrementally expose new functionality without destroying any previous third party apps.
I have a way to solve this problem, but i'm not sure it's the ideal way - i was looking for other ideas.
My plan would be to essentially have three dlls.
APIServer_1_0.dll - this would be the dll with all of the dependencies.
APIClient_1_0.dll - this would be the dll our developers would actual refer to. No references to any of the mess in our solution.
APISupport_1_0.dll - this would contain the interfaces which would allow the client piece to dynamically load the "server" component and perform whatever functions are required. Both of the above dlls would depend upon this. It would be the only dll that the "client" piece refers to.
I initially arrived at this design, because the way in which we do inter process communication between windows services is sort of similar (except that the client talks to the server via named pipes, rather than dynamically loading dlls).
While i'm fairly certain i can make this work, i'm curious to know if there are better ways to accomplish the same task.
You may wish to take a look at Microsoft Managed Add-in Framework [MAF] and Managed Extensibiility Framework [MEF] (links courtesy of Kent Boogaart). As Kent states, the former is concerned with isolation of components, and the latter is primarily concerned with extensibility.
In the end, even if you do not leverage either, some of the concepts regarding API versioning are very useful - ie versioning interfaces, and then providing inter-version support through adapters.
Perhaps a little overkill, but definitely worth a look!
Hope this helps! :)
Why not just use the Assembly versioning built into .NET?
When you add a reference to an assembly, just be sure to check the 'Require specific version' checkbox on the reference. That way you know exactly which version of the Assembly you are using at any given time.

When to create your own dll what should be in it

I as of yet, have not had a need to create a dll in .NET as my programs tend to be distinct from one another (and I haven't programmed for too long). However I am starting to gather a library of regularly used methods now which tend to have copies in lots of my programs (or similar methods that could be made more generic).
As I understand it a dll should be created to share common methods between programs.
So I can put my methods in the dll, what about things like custom dialog boxes and common forms. I currently have a custom error form and a print preview dialog which are used in almost all my programs. Is it good practice to put these in a dll?
"Good practice" in this case really relies on how much code-duplication you're cutting down on. If these dialogues are used throughout a lot of your programs and they take up a lot of code, then yes, it's probably a good idea to move them to a shared space.
But don't be tempted to throw everything in there. You'll find yourself having to override it and by that point you're probably writing more code than you were before. Keep things simple. Keep them generic. Keep them useful.
Before you start, though, be aware that you are creating a dependency tree. If you update your library chances are you'll have to put in some time maintaining your apps that use it... But this is no different from using a third-party lib.
To create a new dll, you just add new project (library) to your solution, and add it as a project reference to your main programme.
It is possible to put anything you want to this project. All dialog boxes, user controls, etc. are just classes, so you can share them as easily as any other class. I think it is good practise to share as much as possible.
Sure why not?
What you're building here is actually a small framework, pretty much like the .Net framework itself. Everything that you think is common between your applications can be put in the assemblies: forms, methods, business logic, exceptions, common data access.
When your framework grows you might want to split up that common DLL. For example if you have common forms in a DLL and you also develop batch applications then they don't need to reference to the DLL containing the WinForms specific classes.
Alternatively you can put the source files for these methods in a common place and just add them as links when you include them in your project/solution.

Categories