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.
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 an application that I have designed and this app has a pretty decent core dll that contains an API that my main view's exe uses. I would like to allow other developers to access this core dll as well but I don't want them to have as much access as me since it would be a security risk. What is the standard way of exposing my core dll? Are there any particular design patterns I should be looking at?
I'm using C#
Edit: my question was a little vague so here is some clarification
My program is deployed as a windows exe which references the core.dll. I want other people to create extensions which dynamically get loaded into my program at start up by loading dlls in the /extensions directory. The 3rd party dlls will inherit/implement certain classes/interfaces in my core.dll. I only want to give 3rd parties limited access to my core but I want to give my exe additional access to the core.
I should mention that this is the first time I have written a program that imports DLLs. Perhaps this whole method of allowing users to add extensions is wrong.
How do I modify/expose my API for
other developers?
To deliberately allow other developers to work with an API you've built touches on many things, which can be broken into two areas:
Resources (documentation, samples, etc) that makes it easier for them to understand (yes - basically an SDK).
Architecting, constructing and deploying your solution so that it's easy to actually work with.
Examples include:
By packing it in a way that suits re-use.
By using naming conventions and member names that others can easily follow.
Documentation, samples.
Providing the source code (as open source) if you're happy for them to modify it.
I would like to allow other developers
to access this core dll as well but I
don't want them to have as much access
as me since it would be a security
risk.
Ok, so this gets us right into the second area - the actual solution.
The problem you have is not a trivial one - but it's also quite do-able; I'd suggest:
Looking into existing material on plugins (https://stackoverflow.com/questions/tagged/plugins+.net)
Personally, I've found using attributes and Dependency Inversion to be a great approach.
There's also stuff like the Managed Extensibility Framework which you should consider.
The big issue you face is that you're into serious architecture territory - the decisions you make now will have a profound impact on all aspects of the solution over time. So you might not be able to make an informed decision quickly. Still - you have to start somewhere :)
The "design patterns" in terms of an API are more related to things like REST.
I don't want them to have as much
access as me since it would be a
security risk
Then i would (for the sake of maintenance), layer on top of the core DLL extra logic to prevent this.
The thing is, the "clients" call the API, not the Core DLL.
"How" the API accesses the Core DLL is under your full control. Just only expose operation contracts that you wish.
Since you're using C#, I would look at Microsoft's Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries and use FxCop to in-force many of them (latest version here). This won't be all you'll likely need, but it would help put you in the right direction.
Also, take a look at the freely available distillation of Framework Design Guidelines by the same author.
Sure, there's a type of project in Visual Studio that outputs a DLL that people can use. I know that. I'm just wondering what are some of the standards that devs will expect when using my DLL file.
I'll be providing a class that searches for movies in IMDB and returns results for a dev to consume.
Not a webservice, but a local DLL file. (I'm aware that IMDB frowns upon web scraping, but I'm also aware that they give permission to people if asked. My permission is already sent.)
How should I approach this?
Check out Microsoft's Design Guidelines for Class Library Developers.
Or the newer version of same (thanks to paper1337).
You're then interested in best practices when designing a class library. There is much to say to this thema.
One of the first and foremost things you need to do is to publish all your dependencies. Avoid any hidden dependencies in your code.
For example, don't rely on some key to be set in a shared key-value collection, such as Session. There is no way a user of your library can find it out.
If some method requires some service to be preinitialized, require a valid reference to be passed as an argument.
You need to provide a simple to use API, full documentation and worked examples as a minimum. If you can provide unit tests that would be a bonus.
Internally, you need to verify all inputs into your routines, as well as clearly document what configuration the user is expected to do. Solid exception handling is a given, and you should possibly consider some localisation support in there as well.
If you, or anybody, is serious about creating a good framework for others to use, check out http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321246756
What ever you make public, should remain public and their signatures cannot be changed in your next version and you must support it forever.
So, take care in establishing your contracts and document them with examples. Make public members only if it needs to be.
Easy-to-use API with appropriate class, method and property names.
API has been tested (e.g. unit tests)
Supporting documentation.
Im currently adding a interface to my application so other people can extend it with plugins. My application is used by MMO gamers and i will not have any control over the plugins ( In that anyone will be allowed to make them ) and i was hoping i could have some degree of control over the code in the plugins.
What im afraid of is someone making a plugin that either contains bad code that starts writing to folders outside "allowed" folders or does this by design. Since this will be run by a MMO gamers some sort of keylogger would be very bad.
So im hoping there is a way for me to:
Force the plugin to run inside a sandbox where it does not have direct access to filesystem,windows or network. In effect forcing them to use the API i provide for those actions.
I was thinking it might be posible to inspect the plugin dll hoping it contained a list of what namespaces it uses, and simply not load plugins that contained "bad" namespaces.
My plugin interface is based on this great codeproject artice , i did try to search for some information on this. But i was unable to refine my search to a point where it returned something usefull, if it mathers my skill level is C# and some cross platform c++.
It would be possible to inspect the assembly for certain things before you load it. Prior to executing code or constructing a type within the assembly, you could run through the entire set of assembly types and references using reflection, and search for "invalid" references. However, this is not going to be very effective, as you're always searching for things that are bad - when really, you need to define the operations that are good, instead, and only allow those.
The only way to cleanly enforce a different security policy for plugin is to load the plugin into a different AppDomain.
By loading the plugin in it's own AppDomain, you can enforce different security policies upon its code (basically run it within a sand box). You can provide interfaces or classes that are passed into the plugin in order to give it access to functionality beyond those in the plugin itself.
My company is currently in the process of creating a large multi-tier software package in C#. We have taken a SOA approach to the structure and I was wondering whether anyone has any advice as to how to make it extensible by users with programming knowledge.
This would involve a two-fold process: approval by the administrator of a production system to allow a specific plugin to be used, and also the actual plugin architecture itself.
We want to allow the users to write scripts to perform common tasks, modify the layout of the user interface (written in WPF) and add new functionality (ie. allowing charting of tabulated data). Does anyone have any suggestions of how to implement this, or know where one might obtain the knowledge to do this kind of thing?
I was thinking this would be the perfect corner-case for releasing the software open-source with a restrictive license on distribution, however, I'm not keen on allowing the competition access to our source code.
Thanks.
EDIT: Thought I'd just clarify to explain why I chose the answer I did. I was referring to production administrators external to my company (ie. the client), and giving them someway to automate/script things in an easier manner without requiring them to have a full knowledge of c# (they are mostly end-users with limited programming experience) - I was thinking more of a DSL. This may be an out of reach goal and the Managed Extensibility Framework seems to offer the best compromise so far.
Just use interfaces. Define an IPlugin that every plugin must implement, and use a well defined messaging layer to allow the plugin to make changes in the main program. You may want to look at a program like Mediaportal or Meedios which heavily depend on user plugins.
As mentioned by Steve, using interfaces is probably the way to go. You would need to design the set of interfaces that you would want your clients to use, design entry points for the plugins as well as a plugin communication model. Along with the suggestions by Steve, you might also want to take a look at the Eclipse project. They have a very well defined plugin architecture and even though its written in java, it may be worth taking a look at.
Another approach might be to design an API available to a scripting language. Both
IronPythonand Boo are dynamic scripting languages that work well with C#. With this approach, your clients could write scripts to interact with and extend your application. This approach is a bit more of a lightweight solution compared to a full plugin system.
I would take a look at the MEF initiative from Microsoft. It's a framework that lets you add extensibility to your applications. It's in beta now, but should be part of .Net 4.0.
Microsoft shares the source, so you can look how it's implemented and interface with it. So basically your extensibility framework will be open for everyone to look at but it won't force you to publish your application code or the plug-ins code.
Open source is not necessary in any way shape or form to make a product extensible.
I agree that open source is a scary idea in this situation. When you say approval by a production administrator - is that administrator within your company, or external?
Personally, I would look at allowing extensibility through inheritance (allowing third parties to subclass your code without giving them the source) and very carefully specified access modifiers.
Microsoft already did exactly this, resulting in Reporting Services, which has every attribute you mention: user defined layout, scriptability, charting, customisable UI. This includes a downloadable IDE. No access to source code is provided or required, yet it's absolutely littered with extensibility hooks. The absence of source code inhibits close-coupling and promotes SOA thinking.
We are currently in a similar situation. We identified different scenarios where people may want to create a live connection on a data level. In that case they can have access to a sinle webservice to request and import data.
At some point they may want to have a custom user interface (in our case Silverlight 2). For this scenario we can provide a base class and have them register the module in a central repository. It then integrates into our application in a uniform way, including security, form and behaviour and interaction with services.