.NET 3.5: Dynamically adding classes without recompiling - c#

I'd like to build an infrastructure that will monitor a server and check ping, response time, and more.
The catch is that future checks (for example: does a certain file exist) will be added without recompiling the infrastructure.
How do I build it in such a way that will enable me to attach inherited classes with different functionality, and execute them without recompiling?
Thanks!

In addition to creating an interface and defining a single entry point for your new library, you could create an attribute which identifies the classes that you need to load or the methods that you need to call. You then use reflection to look at all the DLLs in a certain path, and instantiate / run whatever contains your attribute.
I've built a similar application that had to perform a number of health checks on a system, and needed to be extensible. The application started, looked through all the DLLs in a specified path and for each class with the 'TestAttribute' decoration it would create an instance and run the 'Execute' method.
The use of an attribute means that you don't need to specify which DLLs to process (doesn't need to be in config / database) because it's safe to process every DLL, and only those decorated with the attribute will do anything.

Implement an interface, and the provider pattern, then you can plug anything in that you like. MSBuild is a great example of this, with a simple interface you can add any type of task you like to your build process - follow the same sort of pattern.

Sounds like you could use some kind of 'plugin' mechanism. Define a basic interface and you can compile every "check/action" into a separate assembly. Load all your assemblies dynamically from file and call execute the check/action via the defined interface.
The interface could be just as simple as this, for starters:
public interface IMonitorAction
{
bool Exectute();
}
This infrastructure allows you to add more checks by just creating another assembly file implementing the interface next to the existing ones.

Of the top of my head.
I presume you can re-start you application.
Have a file that lists all the DLL's to load that implement your required functionality. Each DLL should have the same name entry point. Load each DLL, call the method, unload DLL. loop.
Caveat: I've never done anything like this, so I may be talking hot air.

Adding to #slugsters answer, instead of building your own extensibility infrastructure, take a look at extensibility libraries like MEF.

Related

Ensure only one class can access a reference dll?

I have a project where I want only one class to have access to a dll. I would be content with hiding the dll from intellisense, but still having access to it if that is an option. Either way, I want only one class to use the dll and for it not to be seen and/or accessible otherwise.
I'm using C# in visual studios.
Simply said: You can't do that (but keep reading).
Basically, a DLL (From the .NET perspective) is a bunch of code and config files. No more than that. So, given that you'll need to make public those classes in order to be used from another ones outside that assembly then you can not.
What you can do (I ended up doing this a few years ago) is to use some kind of reflection to determine which class (and namespace) is trying to access your assembly and only permit the proper one.
Other way is to implement a key negotiation between your DLL and the permitted assembly. You'll need to implement those manually, as far as I know.
Anyway, keep in mind there's always a way to bypass this kind of protection by disassembling and modifying your code. So, at least, don't forget to obfuscate the file. Anyway, this will just make it a little more painful, but still possible.
An alternate approach, if you goal is to stop people using the functionality of the dll by accident is to push your wrapper class into an intermediary assembly. Your project then references that intermediary project, rather than the underlying dll which effectively hides it. So your project structure would change to something like this:
Main Project -> references API Wrapper Project -> references API DLL
For this to work, your wrapper project needs to make sure that it doesn't accidentally expose any of the API DLL classes through its public interface.
Obviously this doesn't stop your developers from going in and adding a reference to the API DLL so that they can use the library directly, but if the goal is to stop accidental access to the API DLL classes because intellisense has helped the developer out a bit too much then it might be a viable option.

Winform application program interface "Argument type is not assignable to parameter type"

I have a Winform application where I would like to implement some sort of an interface for the customer, so parts of the code is changeable by customer later on if they need to. I believe my approach is wrong, because I get an error in Visual Studio after recompiling my Winform application. The error is "Argument type MyClass is not assignable to parameter type MyClass", but I'm still able to recompile it. I'm worried this would break later on...
This is how I have implemented it until now:
In my winform application I have created an abstract class with a virtual method.
I'm "releasing" an open source project dll assembly for the customer where this abstract class is implemented and the method is calling the base method in the abstract class. If customer would like to change the method, they simply implement it themselves.
This open source project is then referenced and implemented in my winform application.
When customer would like to change the method they implement the method, recompile the dll and replace the new dll with the one I distributed with my assembly.
My winform application has it's own strong name, and the open source project has it's own strong name.
However, when I recompile my Winform application after having referenced the open source project, i get this error: "Argument type MyClass is not assignable to parameter type MyClass". I can still recompile the project. But I'm concerned the implementation has some serious flaws and will break later on. Especially also since I have implemented WyBuild where I will distribute updates for the Winform application.
I need to provide a way for the customer to change some methods in the application without having access to all the source code. How can this be achieved if my implementation is wrong, what is your suggestion?
Thanks.
I'd say that approach itself is a bad way to do it. To me, this sound very error prone, and you state yourself that you have a bad feeling about it. If so, then really don't do it this way.
There sure is a couple of other solution thinkable, but given your descriptions I might do it as follows, which would stay your your original intention.
Have a look at Microsoft's Managed Extensibility Framework (MEF), which could help you in several ways.
Simply put, it would work like this:
You define the interface that the custumer has to implement.
The client then creates an assembly that implements exactly that interface and puts it a location that is monitored by MEF
MEF loads the assembly automatically (no need to reinvent the wheel)
MEF gives you a lot of control over how you want it to work. Like, like should it allow loading only or multiple assemblies that implement that interface at the same time, or should only look for plugins only at the start of the application or monitor the plugin location during the full life-time of it.
Also by doing it this way you get rid of the custom solution you are assembling here and instead use a mature framework that provides a standadized way to do it. Just have look at some tutorials on the net, it is really easy to get into.

What options do I have to dynamically access a class in another assembly?

I have a ASP.NET MVC application and a plugin that needs to write to the web.config file. For various reasons, I've found that the most appropriate way to do this is during compilation using MSBuild configuration, so I have created an executable distributed with my plugin to be called here with appropriate parameters for resolving consumer-application dependencies like the path to the config file.
The plugin is configurable, and the definition for this must be in the consumer application in a specific class.
Now the plugin-executable has to be able to read this class, but we can not have any hard-coded dependencies since the plugin should be distributable and used in many different applications.
I have found this answer here on SO about dynamically loading/unloading DLLs, and my question is if this is the approach to use, while passing in the relevant parameters as arguments to the exe, or do I have any other options?
The answer is Yes but you can do it in two different ways.
If you want to unload the class yes you need to create a new AppDomain, use it and unload it in the end, to do this you need a class that implements MarshalByRefObject it's much more complicated.
If the class can live during the lifetime of the client application you just need to load your plugin to the current AppDomain.
AppDomain.CurrentDomain.CreateInstanceAndUnwrap(assemblyName, typeName);
I strongly recommend that the instance you are loading implements a specific Interface so you can inspect a folder for DLL's like this
var ass = Assembly.LoadFrom(path);
ass.DefinedTypes.Where(t => t.ImplementedInterfaces
.Any(i => i.AssemblyQualifiedName ==
typeof(<Defined Interface>).AssemblyQualifiedName))
this will return a list of types that implement your interface so you just need to use the above code to create one instance.
I think that to work with msbuild you need to take the first approach and do all the load unload and usage inside of the class that implements MarshalByRefObject don't quote me on this one.

How to create a pluggable GUI and DLLs in c#

Not sure the exact terms to use here, so any help would be appreciated.
To be the most simplistic, I have a forms application. When I load "form.exe", the form has one control, a menu. This menu has one menuitem, "Exit". What I would like, is when the Form is loading, be able to pass in arguments to this forms app that specify DLLs that could add specialized methods, controls, etc.
Now when I load "form.exe add_plugable.dll", my menu has another menuitem, "Add".
When I load "form.exe add_plugable.dll remove_pluggable.dll", menu has 3 items "Exit", "Add", and "Remove".
Hope this makes sense. What do I need to include in the Forms application and how do I create my DLLs? I am aware I need a common interface, but dont know exactly how to accomplish this with namespaces and interfaces and abstract classes.
Thanks!
I would recommend looking into the Managed Extensibility Framework. It was designed for this exact type of scenario.
For example, it is what Visual Studio uses for its extensibility, so add ins can be dynamically discovered and plugged in at runtime.
You can use a pre-written framework, but if you are looking for a "bare bones" solution, try this:
Create an interface (or set of interfaces, if you prefer) that contains all methods that the forms app will call, e.g. IPlugin. Put the interface(s) in a separate class library.
In each plugin DLL, create a public class that implements IPlugin.
In the forms app, decide what plugins to load and when to call them. This logic is entirely up to you.
Load a plugin like this, then call the interface members to accomplish what you want. You could read the plugin file and class names from app.config, a database, or calculate them via a naming convention, according to your requirements.
var pluginAssembly = Assembly.Load(pluginFileName);
var plugin = (IPlugin) pluginAssembly.CreateInstance(pluginClassName);
These methods have several overloads allowing more control over the process. For example, you can load the plugin assembly using an AssemblyName rather than a simple string. When instantiating the class, you can specify binding flags and a set of parameter values to pass to the class's constructor.

In C#, how to restrict who can call a method at compile time

In C#, is it possible to restrict who can call a method at compile time?
I've looked into directives, but that didn't work since I can't assign values to symbols.
#define WHO VisualStudioUser.Current // does not work
I also looked into Code Access Security (CAS) but that's runtime enforcement, not compile time.
The requirement is to restrict access to a method at compile time for specific developers given the method exists in a pre-compiled assembly.
here's more details...
I'm building a framework or a series or assemblies for a team of developers. Because of our software license restrictions, I can only allow a few developers to write code to make a call to some restricted methods. The developers will not have access to the source code of the framework but they'll have access to the compiled framework assemblies.
The quick answer will be: No this isn't possible, and if you need to do it, you're Doing It Wrong.
How would this even work? Does it depend who who's running the code or who wrote it?
Edit There's kind of a way using InternalsVisibleTo and restricting accessing in source control to the assemblies that InternalsVisibleTo is specified for. See Jordão's answer
The requirement is to restrict access to a method at compile time for specific developers given the method exists in a pre-compiled assembly.
One way is to mark the method private or internal, it won't be callable by anyone outside the assembly. UPDATE: Also take a look at the InternalsVisibleTo attribute, which is used to define which assemblies can "see" internals of your assembly.
Another way is to divide the code you want to distribute from the code you don't want people to call into separate assemblies. Maybe you just share an assembly mostly of interfaces with your users, that they them compile against; and you have a separate assembly with implementations that they shouldn't reference directly. Your internal team would have access to the implementation assembly. This is just a common form of dependency management, the dependency inversion principle.
Draft:
Compile the restricted code into (obfuscated) DLLs: TypeA.dll, TypeB.dll etc.
Define an interface for each type, and compile them into separate DLLs: ITypeA.dll, ITypeB.dll etc.
Create a "guard assembly", and embed all restricted assemblies into it: Guard.dll. This has a ResolveEventHandler, and methods to instantiate different types defined in the embedded restricted DLLs. Instances are returned through their interface.
Developers get the interface DLLs and the Guard.dll. Each developer can get a Guard.dll with special authentication tokens in it. For example, a Guard.dll can be bound to PC, an IP address, a GUID issued to the developer, anything.
The developer can instantiate those types for which she has the proper authentication code, and uses the object instance through an interface.
Sorry this is a bit fuzzy, because it was more than a year ago when I used these techniques. I hope the main idea is clear.
Can you try using Extensible C# developed by ResolveCorp, some of the links for study and implementation are:
http://zef.me/782/extensible-c
http://www.codeproject.com/KB/architecture/DbCwithXCSharp.aspx
http://weblogs.asp.net/nunitaddin/archive/2003/02/14/2412.aspx
http://www.devx.com/dotnet/Article/11579/0/page/5

Categories