I'm trying to add plugins to my game and what I'm trying to implement is this:
Plugins will be either mine or 3rd party's so I would like a solution where crashing of the plugin would not mean crashing of the main application.
Methods of plugins are called very often (for example because of drawing of game objects).
What I've found so far:
1) http://www.codeproject.com/KB/cs/pluginsincsharp.aspx - simple concept that seems like it should work nicely. Since plugins are used in my game for every round I would suffice to add the Restart() method and if a plugin is no longer needed Unload() method + GC should take care of that.
2) http://mef.codeplex.com/Wikipage - Managed Extensibility Framework - my program should work on .NET 3.5 and I don't want to add any other framework separately I want to write my plugin system myself. Therefore this solution is out of question.
3) Microsoft provides: http://msdn.microsoft.com/en-us/library/system.addin.aspx but according to a few articles I've read it is very complex.
4) Different AppDomains for plugins. According to Marc Gravell ( Usage of AppDomain in C# ) different AppDomains allow isolation. Unloading of plugins would be easy. What would the performance load be? I need to call methods of plugins very often (to draw objects for example).
Using Application Domains - http://msdn.microsoft.com/en-us/library/yb506139.aspx
A few tutorials on java2s.com
Could you please comment on my findings? New approaches are also welcomed! Thanks!
You can define a public interface which the plugin's must implement. Then with the use of reflection you can scan a "plugin" folder for any classes implementing that interface, then create an instance of that class.
From you're code just work on the interface and call the needed method's. About crashing, always make sure that calls to the "plugin" interface are always encapsulated in a try/catch block. If an exception occurs you can always dispose the plugin
I suspect your two requirements of:
fast performance with drawing objects and
a plugin crash would not crash your app
are going to conflict.
To really ensure a buggy plugin doesn't crash your app, you have to load it in a separate AppDomain (as you've identified already). But you're going to take a performance hit, as the whole point of AppDomains is they isolate instances of objects. So you're, at minimum, going to have to serialize arguments to your plugins (possibly using MarshalByRef objects or Remoting). And I suspect that will mean serializing a good chunk of your game state (which sounds like it at least consists of some sort of image). On the plus side, AppDomains live in the same process space, so the overhead isn't as bad as cross-process communication.
Unloading plugins is as simple as unloading the AppDomain.
Because you have to serialise arguments, you can do validation of your game state after the plugin processes it.
I did some toying with AppDomains once. It takes a few seconds to construct one, in my experience. That may affect how many plugins you load into each AppDomain.
The generalized "secrect" to .NET extensibility is: Dynamic loading (to get the plugin into the AppDomain), Reflection (to verify it supports the methods/interface you specify), Attributes (to get Meta-Data for things like versioning), Late Binding (to actually use the plugin).
If your extensibility needs are very simple, or very unique, you should consider implementing it your way.
I used this tutorial as the basis for my own plug-in architecture a couple of years ago. My architecture was, I believe, a relatively simple architecture, but I hit some problems when it came to passing messages between plug-ins.
If you're intent on writing your own architecture, then fair enough, but I would warn against it. It's no small undertaking, and sooner or later you're going to run into some major design considerations, like message passing, which are non-trivial to solve (if admittedly simultaneously quite interesting and frustrating). There is a tremendous amount of value in using something like MEF that solves these problems for you, and provides a really nice API and framework upon which you can build you plug-ins.
Furthermore, MEF will end up being distributed as part of your application, so you don't need to get your users to download it separately; it's an "invisible" dependency as far as they're concerned, and a light-weight one for developers, including yourself. It's also the official plug-in architecture for Visual Studio 2010, so it has a lot of weight in the .NET community, and there will only ever be more developers able to write plug-ins for your app if you use it too.
Hope that makes some sense.
Related
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.
I have been exploring reinventing the DataTable and I am wondering what the uses are for MarshalByValueComponent. I believe it is used for .NET Remoting (maybe WinForms and WebForms), but that was replaced superseded by WCF. I cannot find any notable usages of it across GitHub or Google. Is MarshalByValueComponent still used?
This is hard to answer. The entire concept of wanting to remote a component is a mystifying one. These design decisions were made 13+ years ago and clearly they had a very different idea of how remoting was going to be practical. Which didn't pan out that well, heavily re-engineered in .NET 3.0
Just noodling about this a bit without knowing the thinking behind it. MarshalByValueComponent exist as the antipode to Component. Which inherits from MarshalByRefObject. By far most components and controls are not serializable, they have way too much runtime state associated with them that can never properly deserialize in another runtime environment. Take an OpenFileDialog, the odds that a verbatim copy of it on another machine can operate correctly are zilch. Again having to suspend the wonder at why you'd want to do this at all. Same for any Control, it has dozens of properties whose value depend on the operating system state.
But MBRO isn't that desirable, the many round-trips take a heavy hit from network latency. There are a few components that don't have runtime state and still make a bit of sense in a remoting scenario. That they are a component is in itself a quirk, it's been a long time since I dropped a DataSet on a Form. But they inherit MBVC as a result. Just ignore this, it isn't practical.
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/
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.
I stand in front of a little problem; I want to create a modular software.
Let's make it more general and not specific for my case. What I want to create is a software which loads dlls and those dlls adds features to the software.
Think of the dlls as xvid, divx or whatever additional codec, feature to your favorite video-player. I want a more custom modular program though, in my case I'm creating a software to handle Customers, Invoices and Products and different users might have different needs and therefore I need to handle this somehow!
However, re-compiling the software and specificly sending the new files to each different user is "stupid" I would rather create a modular software ( don't actually know if this is the correct term ).
So what I was thinking is that I begin creating a pattern of which my DLL's should follow.
Then I create a Module handler in my software which loads the actuall DLL and calls the method in it ( here's where the pattern come in! ).
What I'd like to know is; Am I on the right track?
Might you guys give me some pointers or examples on this matter?
This is all in C#, but would of course be interesting to see how it would differ in Java, Python or C++ too.
create a common interface IMyInterface for your classes which should include everything that is common between all of your Moduals. You should look into the Managed Extensibility Framework I believe you can get it from Codeplex.
You have to have a purpose. You either need the module to conform to some kind of interface or something the app can handle (like a method with a known attribute that you find via reflection). The interface then performs known functionality like invoice creation, invoice printing, etc.
Alternatively your app has to conform to some interface and uses hooks for the module to use to inject itself into your app.
Plugins would be good for something that can be easily sliced up (media codecs). Hooks would be good for something with a well-defined event model (like a web server). Which you use depends on how you want your modularity for customers, invoices, etc. to work.
Here is a similar SO thread. Here's a list of dependency injection frameworks, Microsoft's is Unity. Also, you can look at the Enterprise Library codebase to see how they implement their provider architecture, such as in the caching application block where you can plug in your own caching provider.