What is the best way expose key classes/methods my core API to 3rd party developers? - c#

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.

Related

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.

.Net Logger (Write your own vs log4net/enterprise logger/nlog etc.)

I work for an IT department with about 50+ developers. It used to be about 100+ developers but was cut because of the recession.
When our department was bigger there was an ambitious effort made to set up a special architecture group.
One thing this group decided to do was create our own internal logger. They thought it was such a simple task that we could spend recources and do it ourselves. Now we are having issues with performance and difficulty viewing the logs generated and some employees are frustrated that we are spending recources on infrastructure stuff like this instead of focusing on serving our business and using stuff that already exists like log4net or Enterprise Logger.
Can you assist me in listing up reasons why you should not create your own .net logger.
Also reasons for why you should are welcome to get a fair point of view :)
In my last job, almost all the infrastructure was written by us instead of using some of-the-shelf products. (and by "all the infrastructure" I mean ALL of it - Logging, Messaging, Database, Containers of so on).
One of the biggest disadvantages of it was that it made us spend most of our time working on the things that are irrelevant to the end-user instead of adding more features.
from that job I've learned to always focus on the things your product was meant to solve. is your company developing loggers? will the quality of your logger influence your customer more than another feature? I don't think so.
You have a limited budget and manpower - use it wisely. Don't reinvent the wheel. I'm sure that your company and your customers will benefit if you'll focus your attention on things that they need.
in my current project I'm using NHibernate as ORM framework instead of an in-house one that is in use in other projects. instead of fixing bugs in the old ORM framework, my focus is on the main roadmap of the project. furthermore, NHibernate has it's own roadmap which means that additional features will come without much resources from my company.
I would take a different approach. How about first introducing a common interface to your own library such as Common Infrastructure Libraries (http://netcommon.sourceforge.net/). Then you can gradually move all projects over to that interface and if your own library is not up to the job for large projects then simply switch over to one of the open source frameworks (or even a commercial solution).
HTH
Alex
I use a custom logging API that uses a provider model design, that allows an external logging framework to be plugged in. I have developed providers for Log4Net, EntLib and the System.Diagnostics.Trace loggers.
This is essentially the same concept as the Common Infrastructure Libraries.
This means that internal developments do not have an explicit dependency on an external logging framework, yet you can still benefit from all the features of your favorite logging framework. In practice we usually use Log4Net except for customers who are already using EntLib.
It cost money.
It was done so many time before.
You are not as special as you think. If you are, then do something about it.
Maybe you are not as smart as you think.
Are you over staffed? Yet?
I disagree with those who see people reinventing wheels everywhere. A wheel could be a database server, an operating system or a programming language. However things like a ORM framework or this log4net thing aren't in the market enough time to be considered wheels.
Many of these products have a short life cycle, they are replaced by new approaches, just consider how many ORM frameworks have you seen, and then comes Microsoft and launches LINQ.
Logging is not a solid discipline you can learn and it is very platform dependent.
So considering using a logging framework which could come obsolete (log4net vs nlog), wasting your time learning it, does not exclude the option of build your own logging.
I have done this with ORM mapping, for me has been better building a few ORM classes than learning nHybernate.
I wrote my own one because I thought (A) it is based on a TraceListener which is a standard .NET class and (B) it is little and simple to use and maybe because I wanted to write one anyway.
But now I am using NLog in my new projects and replacing it in some old ones!
Am I wrong? Both works for me fine and the reason for using NLog for me was that I wanted a feature that needed an almost rewriting of my custom TraceListener. It turned out a 1 or 2 hour tutorial with a sample app was cheaper for me. This is not a universal situation; but helps with having a more clear image about logging problems.
if your logging solution has such special requirements that an off the shelf solution doesn't work, than maybe making a custom version might be worthwhile.
If this is the argument though, one could also consider downloading an opensource framework and try to customize it.

Writing API in C# for My Application

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.

Extensibility without Open-Source

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.

Common C# source code for Windows and Windows Mobile

I have a goal to build an application with UI that would run on both Windows Mobile and "normal" desktop Windows. The priority is for it to "look good" under Windows Mobile, and for desktop Windows it is OK if it distorted. Before I invest days trying, I would like to hear if that is possible to begin with. There are several parts to this question:
Is .NET Compact Framework a subset of "normal" (please, edit) .NET Framework? If not, does MSDN have any information anywhere on classes that are in .NET Compact Framework, but not in "normal" (again, please, edit) framework?
Is behavior of shared classes same in both frameworks?
Is it possible to have a single Visual Studio 2005 solution / project for both platforms? If yes, how do to set it up?
Any other comments and advice? Any relevant links?
The CF contains a subset of the full framework (FFx), but it is not a pure subset. There are actually several things available in the CF that aren't in the FFx, which makes it a bit more difficult. CF apps also, except in the most rudimentary cases, use P/Invoke. Those calls are never the same from the desktop to the device, so they are not directly portable (though with a little abstraction you can have a platform-agnostic interface).
For the most part, behavior is the same. I've seen some cases where it's not, and I recall some event ordering not always being identical though, so trust but verify.
It's possible through very careful massaging of the configurations, but I certainly don't recommend it. It's difficult to maintain and very fragile. Instead have two project files, one for CF and one for FFx. You're likely to have code file differences anyway. Add the code files as links to each project so they both use the same physical source file. I'd recommend using some form of CI to help ensure they both build at all times.
Take a look at Dan Moth's MSDN article and blog entries on sharing code assets.
P.S. I found the poster online - it'll show you all the classes that are CF. I ordered it fro Microsoft because Kinkos wanted $65 to print it out in color for me! Microsoft sent me a couple of copies free - all I had to do was ask:
http://www.microsoft.com/downloads/details.aspx?familyid=7B645F3A-6D22-4548-A0D8-C2A27E1917F8&displaylang=en
I have it hanging in my cubicle and it's a godsend when trying to remember which namespaces classes can be found in.
Nice multi-part question:
Differences between the Full Framework and the Compact Framework
The article above has links to relevant documentation about how class behavior differs (it definitely DOES differ in some situations)
Very simple! Create a single solution with a set of base functionality in a Class Library, then create two client projects (one for your desktop app and one for the windows mobile app). Finally, add references to the class library to both client projects.
Depending on the breadth of the project you are working on, you may want to check out the Model View Controller pattern. It may be a bit much for your project, but if you want to share UI behavior between projects, it can be a life saver.
Hope that helps!
CF, in general contains a subset of the classes from the regular framework - but you can't directly execute code from one on t'other. Additionally, rather than just being a subset, there are probably a few things in compact that aren't in the regular version, such as the GUI things specific for mobile devices (soft keys, etc) - assuming you are writing a winform exe, and not a web page (which might be the simplest way to get compatibility).
With some effort, it it possible to share logic code, in particular utility dlls - but they need different csproj files (since they have completely different compile-time "targets"). To reduce maintenance, you can often cheat by hacking the csproj to use wildcards, like from here:
<ItemGroup>
<Compile Include="..\protobuf-net\**\*.cs" />
</ItemGroup>
For UI, things get a lot tricker. In general the expectation would be to have shared business logic and separate UI for different target devices.
1). There is a Compact Framework so yes; And it is a subset of the full .NET framework. I've got a poster on my wall at the office that denotes a whole bunch of classes that work in CF... I don't recall off the top of my head if there are any that are purely CF, but I suppose there must be some. There are a couple of good books on the subject - one by Paul Yao that I have and another by Andy Wigley - both are available on Amazon.
2). As far as I'm aware, the classes that are CF and full framework work the same but need to be compiled for different targets.
3). I would hazard a guess that providing you only use classes that are common to both, that you could use the same solution, I don't know the extent you would have to go to make it compile for the compact device and the full version though, nor can I say with complete certainty that it can be done. I'd hazard a guess that the process isn't simple.
4). Go to your local book store and have a flick through those two books I mentioned. Like I said, I have the one by Paul Yao and it seems to cover most of what I could imagine needing on a compact device.

Categories