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.
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.
I'll write a application but I've never experienced to allow people to use my application programming interface before.I mean how kinda design I should make to let people use my methods from outside world like API.
Please some one show me a way.I am kinda new to this.
Expose as little as you can. Every bit you publish, will return to you x100 in next version. Keeping compatibility is very hard.
Create abstractions for everything you publish. You will definitely change your internals, but your existing users should stay compatible.
Mark everything as internal. Even the main method of your application. Every single method that could be used, will be used.
Test your public API the same way you would for interfaces. Integration tests and so on. Note that your API will be used in unpredictable ways.
Maximize convention over configuration. This is required. Even if your API is a single method you will still need to support this. Just makes your life easier.
Sign, and strong name your assemblies, this is good practice.
Resolve as many FxCop and StyleCop errors as possible.
Check your API is compatible with the Naming Guidelines of your platform.
Provide as many examples as you can, and remember that most of the usage of your API will be Ctrl+C and Ctrl+V from these examples.
Try to provide documentation. Check that you do not have GhostDoc-style auto-generated documentation. Everybody hates this.
Include information on how to find you.
Do not bother with obfuscation. This will help you and your users.
ADDED
API should have as less dependencies as you can. For example, dependecies on the IoC containers should be prohibited. If your code uses it internally. Just ilmerge them into your assemblies.
It may not be the funniest reading, and certainly not the only reading to do on the subject, but while designing your class library (your API), do check in with the Design Guidelines for Developing Class Libraries every now and then, it's a good idea to have a design that corresponds a bit with the .NET Framework iteself.
Make your methods you want to expose to the outside world public.
I found this presentation to be particularly insightful:
How to Design a Good API and Why it Matters
http://lcsd05.cs.tamu.edu/slides/keynote.pdf
One way to do it is to create a DLL for your main functionality that others will use and an EXE that calls the methods in the DLL. If you want your application to support plug-ins, have a look at the System.AddIn namespace.
If you want to see what's new in this area, check out the Managed Extensibility Framework. It's a new/"unified (see the comments...)" method for exposing features for add-ins and other extensibility/modularity.
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.
In my team we have hundreds of shared dlls, which many also reference other dlls that themselves reference other dlls, and so on. We have started to use a 'Shared' directory for all the dlls that we feel are generic enough to use in other projects, such as a database comms dll.
The problem is that if one of the dlls all the way down the tree is changed, then everything that references it needs to be recompiled to avoid versioning issues (which occur at runtime).
To avoid this, there is now talk of adding all our 'shared' dlls into one big assembly, and anyone creating new apps simply reference that, and that alone.
This obviously will get bigger and bigger and i'm not sure if this is the best way or not. Any thoughts please?
What we do is treat the maintenance of the shared DLLs as a project in itself, with its own source-control and everything. Then about twice a year, we do a 'release' of the shared DLLs to the public, with its own version number and everything. As long as you always use the DLLs as a 'set' (meaning all the ones you reference are from the same release) you're guaranteed not to have any dependency issues.
It's most definitely not the best way to do it. I have a few "shared" DLLs at my job that are kind of like that. They get unwieldy and difficult (read: impossible) to make meaningful changes to because it becomes too difficult to ensure that changes don't break apps downstream, which seems like the exact opposite of what you're trying to do.
It sounds like what you really need to do is separate your concerns a little bit better. If all of these DLLs are referencing each other, they're probably too tightly coupled. A true "shared" DLL should be able to stand on its own, or as part of a packet of three or four that travel as a group. If your dependencies are actually preventing you from making changes, then your coupling strategy has gone horribly wrong.
Putting everything in one large DLL certainly isn't going to make anything better. In fact, probably the opposite. Once you've got everything in one DLL, the temptation will be there to couple everything within it even more tightly together, which will make it impossible to pull things apart later.
you can make one solution that include all connected projects.
and when you need to release, just build this solution
Update.
As you say, the solution is cant hold so much dlls.
In other hand you can make an external MSBuild script
or using CruiseControl.NET that have possibilities to make such complicated tasks.
To quote from the GoF book, "Program to an interface, not an implementation." This could apply here to some of your libraries. You are already aware of how brittle your develop becomes when you have tight coupling. Now what needs to be addressed is how to give you breathing room.
You can create an interface. This will provide a contract that any application can use to specify that a minimum set of functionality is available.
You can create a Service that implements an interface. This will allow you to provide what would be thought of as an addon or a plugin. This allows you to design towards a contract version with expectations that your tools will adhere to.
You can create a Service that only uses an interface. This will allow your application to send in any concrete implementation that adheres to a contract of design.
Products like development editors and web browsers use this approach to make some code reuse possible. Thank you. Good day.
Design Principles from Design Patterns
Plugin