Separate class-library initialization for each client assembly - c#

I'm writing a set of plugins for a third-party application which are implemented as .NET libraries and are loaded on application start, so they are all in the same application domain. One of the libraries is a collection of utility classes and extension methods that are used by others (including plugins written by other people, so this is basically a meta-library).
The problem is: inside the utility library there is an initialization code that allows to set up things like plugin title and such; which are, obviously, should be set per-client, i.e. per library in that case. This, of course, cannot be achieved using a static configuration class, as there would only be the single instance of it within the domain.
I'm also not allowed to load this library dynamically inside other plugins into a separate domain; and that will be a waste of memory, which is a concern.
The questions are:
Is it even possible/reasonable to implement such per-client runtime configuration for other libraries?
If it is, what approach would you recommend?

I am not sure I understand the question correctly, but you seem to be suggesting that there is an app which loads plugin-dlls at startup. You (the app developer and potentially plugin developer) want to provide a static class which has utility functions, that the plugins can use, without having to "re-invent the wheel" for every plugin. Below is my assessment (based on the above understanding)
Your utility class seems to store plugin specific data - so by definition it cannot be static
Yes, you can potentially load a plugin specific configuration file (file name might have to follow a naming convention to be effortlessly loaded by a static function) and offer the utility services - but I would say that is a bad design
I would rather provide a utility which does not store any plugin specific data, but simply provides services based on method arguments. If you see yourself passing the same parameters a lot of times to the utility, then you should encapsulate those parameters into its own class/struct (like PluginData?)
EDIT
Let me expand a bit on the 3rd approach specified above:
You can represent your plugin configuration using a class, something like below, or you can get fancier.
class PluginConfiguration {
public string PluginName {get; private set;} // This represents a property that all plugins share i.e. well known properties
// all the configurations "private" to the plugin can go here
// You might want to use some XmlDocument or a different data structure for this purpose
public Dictionary<string,string> ConfigItems {get; private set;}
public PluginConfiguration(string configFile) {
// Load the configuration from the config file
}
}
Now your utility library can pass arguments or return data of type PluginConfiguration and help you centralize all repeating code for plugins

Related

How to load third-party implementations at run-time

I'm making a .Net application to manage and install mods. The application itself shouldn't be able to install mods for any particular game but should be able to call 3rd-party extensions to do so.
Let's say my mod manager expects an implementation of the given interface:
interface IGameManager {
// Deploy a modding configuration to the targeted game
void Deploy();
// Remove all managed mods from the targeted game
void Purge();
// ...
}
And someone else, working on a different code base, implement IGameManager to manage a specific game:
class MinecraftManager: IGameManager {
// ...
}
Then this person compiles it, publishes it and everyone could simply feed this extension to the main mod manager so it can manage their mods for the targeted game.
But how? Is there a way for my application to safely load and use such third-party implementations at run-time? And how to facilitate the making of third-party extension (e.g. giving an interface to build on but more elegantly and maintenance-friendly)?
Edit 1: Invalid syntax in MinecraftManager signature
You are essentially trying to design a plugin system. There are many implementations that you could reuse but the general idea is that:
You need your manager to be able to discover extensions. There are many ways to do that but the simplest and most used approach is to place extension assemblies under a well known directory in the file system. Then your manager can enumerate the assemblies in that folder by enumerating the files (or if you prefer that each extension has it own subfolder enumerate the subfolders)
Load the assembly. For that you will use one of the Assembly.Load.. methods. Since it is not possible to unload assemblies, you may want to first load the assembly for reflection only and once you decide that the assembly is valid you can load it in the ApplicationDomain in order to use it.
Use relfection to enumerate all classes of the assembly you just loaded and find the ones that implement the right interface (IGameManager). Altenatively you can require that extensions contains an "entry point" class of known name, then look for that class by name (using reflection).
Create an instance of the class(es) and use it (perhaps also keep it in a collection of loaded extensions)
Regarding the interface that extensions must implement: You should put the interface (and any other supporting interfaces) in a separate assembly. The assembly should contain only interfaces, no implementation. You can then publish the assembly. Once published the interface should never change.
If you need to add functionality you should create a new interface. This way old versions of the manager will work with newer versions of an extension (that is designed to implement the new functionality as well). Also your manager can determine which interfaces are implemented by an extension and act accordingly (thus maintaining compatibility). If the new functionality is mandatory, your manager should discard any extension that does not implement both interfaces.
I just found out dotNet 4 already have an extensibility framework (Documentations here), which is cleaner and safer than using Assembly.Load().
Here's the snippet I use to load my plugins from a given directory, if anyone encounter the same problem:
// Where T is the type you want to retrieve from the assemblies
private static IEnumerable<Lazy<T>> LoadExternalAssemblyFromPath<T>(string path, string pattern) {
CreateDirectoryIfDoesntExist(path);
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(path, pattern));
CompositionContainer container = new CompositionContainer(catalog);
return container.GetExports<T>();
}
// Usage:
LoadExternalAssemblyFromPath("C:/path/to/plugins", "*.dll");
Regarding the implementation of such plugin, Kouvarakis' solution on the matter is correct.

How can I prevent a third party from calling certain methods?

I have an assembly which is being developed to create a facade around some potentially sensitive functionality and I want to allow a third party to call some of the methods contained within it but not others.
How can I prevent the third party calling unauthorised methods given they will have access to the entire DLL (I'm not concerned about them seeing the code, just executing it)?
This has to be compatible with the .net compact framework so unfortunately using the StrongNameIdentityPermission attribute is not possible.
I think you should ship two Facade implementations, one for 'internal' consumers which exposes all methods and another external that exposes only the sub-set. You can achieve this whilst maintaining only one code base by having two separate build processes. One technique that springs to mind is to use compiler directives to exclude a method from the external build, or mark it internal if it is required by other public methods. If you do ship sensitive methods with internal modifiers you may also want to implement obfuscation.
EDIT
Perhaps it would be cleaner, rather than having directives around each method to use partial classes, define a partial class for the sensitive methods and put the entire class implementation in a directive.
public partial class MyClass
{
public void NonSensitive(){}
}
#if INTERNAL_BUILD
public partial class MyClass
{
public void Sensitive(){}
}
#endif
You can have this partial class in the same or a separate file, which might be a nice level of separation as you could prepend the file name x_Sensitive.cs or similar.
Description
Assuming i understand your question.
You can mark your methods with the internal access modifier to make them not
accessable from other librarys.
But this does not help from security persepective, because it is always possible to run the method using reflection.
The internal keyword is an access modifier for types and type members. Internal types or members are accessible only within files in the same assembly
More Information
MSDN - internal (C# Reference)
If a third party can see the code, then they can run it - there is nothing you do to stop this.
Note however you have an application which is loading 3rd party plugins then you could load plugin assemblies with restrictions that prevent it from using reflection - this would mean that you can mark these methods / classes as internal to prevent plugins from being able to call these methods when loaded as a plugin in your application. Depending on the nature of the sensitive functionality this may or may not be useful to you from a security perspective.
For information on how to do this see How to: Run Partially Trusted Code in a Sandbox
Could you offer the functionality that you want the third party to consume as a Web API? They will not have any access to the source code OR the compiled binaries. They will only be able to see exactly what you want them to see. This would also offer additional security features such as Authentication and Authorization of callers.

How to organize code using an optional assembly reference?

I am working on a project and want to optionally use an assembly if available. This assembly is only available on WS 2008 R2, and my ideal product whould be a common binary for both computers with and without the assembly. However, I'm primarily developing on a Windows 7 machine, where I cannot install the assembly.
How can I organize my code so that I can (with minimum changes) build my code on a machine without the assembly and secondly, how do I ensure that I call the assembly functions only when it is present.
(NOTE : The only use of the optional assembly is to instantiate a class in the library and repeatedly call a (single) function of the class, which returns a boolean. The assembly is fsrmlib, which exposes advanced file system management operations on WS08R2.)
I'm currently thinking of writing a wrapper class, which will always return true if the assembly is not present. Is this the right way to go about doing this?
My approach would be to dynamically load the assembly, instead of hard-coding a reference. Your code could then decide whether to use the assembly (if it loaded) or return some other value. If you use the assembly, you'll need to use reflection to instantiate the class and use the method. That way your code will build and run on any platform, but it's behavior will change if it detects the presence of fsrmlib.
The System.Reflection.Assembly documentation has example code for doing this.
Hide the functionality behind an interface, say:
public interface IFileSystemManager
{
void Manage(IFoo foo);
}
Create two implementations:
An implementation that wraps the desired functionality from fsrmlib
A Null Object implementation that does nothing
Inject the IFileSystemManager into your consumers using Constructor Injection:
public class Consumer
{
private readonly IFileSystemManager fileSystemManager;
public Consumer(IFileSystemManager fileSystemManager)
{
if (fileSystemManager == null)
{
throw new ArgumentNullException("fileSystemManager");
}
this.fileSystemManager = fileSystemManager;
}
// Use the file system manager...
public void Bar()
{
this.fileSystemManager.Manage(someFoo);
}
}
Make the selection of IFileSystemManager a configuration option by delegating the mapping from IFileSystemManager to concrete class to the config file so that you can change the implementation without recompiling the application.
Configure applications running on WS 2008 R2 to use the implementation that wraps fsrmlib, and configure all other applications to use the Null Object implementation.
I would recommend that you use a DI Container for the configuration part instead of rolling this functionality yourself.
Alternatively you could also consider treating the IFileSystemManager as an add-in and use MEF to wire it up for you.

C# code re-use via namespaces

I like to create a file full of custom functions which I have made, which I may use in another project or something. Now I don't fully understand how to go about this, normally in a language like php, you'd just create the php file and then go include("cust_lib.php") or whatever the file is called.
Now I think that the process involves the library having its own namespace, then either go using custom_lib; or custom_lib:: within the script (I don't want to get into a discussion over which is the best way to go here).
Is this right? Or should I create the library and convert it to a .dll, if so how do I go about this, what sort of syntax does a dll have inside it etc.
However if its just file within one project then I don't need to go down that route do I? I can just create the namespace and use that?
This is what I'm working for at the moment, and thought it would be something like this
namespace Custom_Lib{
~~functions to go here~~
}
However the functions have to exist within a class don't they? So that becomes something like
namespace Custom_Lib{
class custom_lib{
public string function1(string input){
return input;
}
}
}
So some help, pointers, examples would be appreciated so I can wrap my head around this
Thanks,
Psy.
(Yes I call them functions, that just comes from a long php/js etc background)
The normal approach would be to create a Class Library project, put your classes and methods in that project, making sure that those you want to expose are public. Then you add a reference to the resulting dll file in the client projects and you will have the functionality from the class library available to you.
Even if you decide to put it all into one single file, I would still recommend you to make it a class library since I imagine that will make it easier to maintain. For instance, consider the following scenarios:
You decide to put it in a file and include a copy of that file in all projects where you want to use it. Later you find a bug in the code. Now you will have a number of copies of the file in which to correct the bug.
You decide to put it in a file and include that same file in all projects. Now, if you want to change some behaviour in it, you will alter the behavior for all projects using it.
In those two cases, keeping it as a separate project will facilitate things for you:
You will have only one copy of the code to maintain
You can decide whether or not to update the dll used by a certain project when you make updates to the class library.
Regarding the syntax issues: yes all methods must exist within a class. However, if the class is merely a container of the methods, you can make it (and the methods static):
public static class CustomLib
{
public static string GetSomethingInteresting(int input)
{
// your code here...
}
}
That way you will not need to create an instance of CustomLib, but can just call the method:
string meaningOfLife = CustomLib.GetSomethingInteresting(42);
In addition to Fredrik Mörk's well-written and spot-on response, I'd add this:
Avoid creating a single class that is a kitchen-sink collection of functions/methods.
Instead, group related methods into smaller classes so that it's easier for you and consumers of your library to find the functionality they want. Also, if your library makes use of class-level variables, you can limit their scope.
Further, if you decide later on to add threading capabilities to your library, or if your library is used in a multi-threaded application, static methods will likely become a nightmare for you. This is a serious concern, and shouldn't be overlooked.
There no question here. You answered it yourself. Yes, you have to construct a class to include all helper methods. And yes, you can either compile it to a dll if you want to reuse in multiple projects it or just add the source file to the project.
Usually I declare the helper class and all functions as static to avoid initiating the class each time I use it.

Attributes in C#

I know that C# (and .NET in general) is big on attributes. However, despite the fact I have programmed in C# for many years, I haven't found myself ever using them. Would someone get me started on them, and explain where is the best to use them?
Thanks
From Pro C# 2008 and the .NET 3.5 Platform, Fourth Edition by Andrew Troelsen
Understanding Attributed Programming
One role of a .NET compiler is to generate metadata
descriptions for all defined and referenced types. In addition to this standard metadata contained
within any assembly, the .NET platform provides a way for programmers to embed additional
metadata into an assembly using attributes. In a nutshell, attributes are nothing more than code
annotations that can be applied to a given type (class, interface, structure, etc.), member (property,
method, etc.), assembly, or module.
The idea of annotating code using attributes is not new. COM IDL provided numerous predefined
attributes that allowed developers to describe the types contained within a given COM server.
However, COM attributes were little more than a set of keywords. If a COM developer needed to
create a custom attribute, he or she could do so, but it was referenced in code by a 128-bit number
(GUID), which was cumbersome at best.
Unlike COM IDL attributes (which again were simply keywords), .NET attributes are class types
that extend the abstract System.Attribute base class. As you explore the .NET namespaces, you will
find many predefined attributes that you are able to make use of in your applications. Furthermore,
you are free to build custom attributes to further qualify the behavior of your types by creating a
new type deriving from Attribute.
Understand that when you apply attributes in your code, the embedded metadata is essentially
useless until another piece of software explicitly reflects over the information. If this is not the case,
the blurb of metadata embedded within the assembly is ignored and completely harmless.
Attribute Consumers
As you would guess, the .NET 3.5 Framework SDK ships with numerous utilities that are indeed on
the lookout for various attributes. The C# compiler (csc.exe) itself has been preprogrammed to
discover the presence of various attributes during the compilation cycle. For example, if the C#
compiler encounters the [CLSCompliant] attribute, it will automatically check the attributed item to
ensure it is exposing only CLS-compliant constructs. By way of another example, if the C# compiler
discovers an item attributed with the [Obsolete] attribute, it will display a compiler warning in the
Visual Studio 2008 Error List window.
In addition to development tools, numerous methods in the .NET base class libraries are preprogrammed
to reflect over specific attributes. For example, if you wish to persist the state of an
object to file, all you are required to do is annotate your class with the [Serializable] attribute. If
the Serialize() method of the BinaryFormatter class encounters this attribute, the object is automatically
persisted to file in a compact binary format.
The .NET CLR is also on the prowl for the presence of certain attributes. Perhaps the most
famous .NET attribute is [WebMethod]. If you wish to expose a method via HTTP requests and automatically
encode the method return value as XML, simply apply [WebMethod] to the method and the
CLR handles the details. Beyond web service development, attributes are critical to the operation of
the .NET security system, Windows Communication Foundation, and COM/.NET interoperability
(and so on).
Finally, you are free to build applications that are programmed to reflect over your own custom
attributes as well as any attribute in the .NET base class libraries. By doing so, you are essentially
able to create a set of “keywords” that are understood by a specific set of assemblies.
Applying Attributes in C#
The .NET base class library provides a number of attributes in various
namespaces. Below is a snapshot of some—but by absolutely no means all—predefined
attributes.
A Tiny Sampling of Predefined Attributes
[CLSCompliant]
Enforces the annotated item to conform to the rules of the Common
Language Specification (CLS). Recall that CLS-compliant types are
guaranteed to be used seamlessly across all .NET programming languages.
[DllImport]
Allows .NET code to make calls to any unmanaged C- or C++-based code
library, including the API of the underlying operating system. Do note that
[DllImport] is not used when communicating with COM-based software.
[Obsolete]
Marks a deprecated type or member. If other programmers attempt to use
such an item, they will receive a compiler warning describing the error of
their ways.
[Serializable]
Marks a class or structure as being “serializable,” meaning it is able to persist
its current state into a stream.
[NonSerialized]
Specifies that a given field in a class or structure should not be persisted
during the serialization process.
[WebMethod]
Marks a method as being invokable via HTTP requests and instructs the CLR
to serialize the method return value as XML.
Building Custom Attributes
The first step in building a custom attribute is to create a new class deriving from System.Attribute. Example:
// A custom attribute.
public sealed class VehicleDescriptionAttribute : System.Attribute
{
private string msgData;
public VehicleDescriptionAttribute(string description)
{
msgData = description;
}
public VehicleDescriptionAttribute() { }
public string Description
{
get { return msgData; }
set { msgData = value; }
}
}
As you can see, VehicleDescriptionAttribute maintains a private internal string (msgData)
that can be set using a custom constructor and manipulated using a type property (Description).
Beyond the fact that this class derived from System.Attribute, there is nothing unique to this class
definition.
For security reasons, it is considered a .NET best practice to design all custom attributes as sealed. In
fact, Visual Studio 2008 provides a code snippet named Attribute that will dump out a new System.
Attribute-derived class into your code window.
Attributes get more use in code targeted to other programmers or between distinct parts of a program, rather than code targeted at end users.
For example, you could use attributes to import a dll, indicate how types would interact with visual studio (designer visible, intellisense helps, debugger step-through, etc), how to serialize them, indicate a type is obsolete, describe default values, descriptions, handle COM access, etc.
Those are things that are largely invisible to the end user and that a single programmer could put elsewhere in the source code. But they're useful when only the compiled binary is available and not the source.
I like to use attributes as metadata to my code. We have created some simple attributes that let us tag who wrote what code, when, and why. This lets us have both documented changes in code and in runtime. If there are any exceptions during runtime, we can inspect the callstack, look at any attributes on the methods along the way, and track down the people responsible:
[Author("Erich", "2009/04/06", Comment = "blah blah blah")]
public void MyFunction()
{
...
}
Of course, we could use our source control to look at who checked in what code, but this I've found makes the information more available in the place where you need it. Also, if we ever change source control, that information will not be lost since it is persisted in code.
Attributes are a form of declarative programming, 'similar' to creating your UI in XAML. It 'marks' pieces of code (classes, methods, properties, whatever) with an attribute so that you can later gather all those pieces marked in a specific way and then do something standard with all of them.
Eg. Consider the scenario where you have certain sections of code that you want to run once each time your app starts. In one model of programming (non-attribute) you go to your main method and explicitly call those init methods. With attributes you simply gather all methods which you've marked with your 'init' attribute, and call them via reflection.
The same pattern holds for actions like serialization, persistence and whatnot...
I believe you mean that you do not use (or frequently use) custom defined attributes ?
In my current project, I make heavy use of custom attributes, but, the fact that you need to keep in the back of your mind, is that using attributes should not be a goal on itself.
It is a tool / purpose to get to a given solution.
I sometimes use custom attributes in combination with a weaver like PostSharp, to decorate methods where some weaving should be applied to at compile-time.
In my current project, I also use attributes to decorate certain types with additional info ... But I believe I've posted about this here before:
Cool uses of Attributes or Annotations (CLR or Java)?
I use attributes for the following:
Communicating with a plug-in architecture
Telling another framework what to do with the code (NUnit, for instance)
Adding metadata for use with other code (See PropertyGrid)
Mapping objects to databases (See Castle ActiveRecord)
When writing my own APIs to allow users to communicate metadata
In framework code to tell the debugger to skip over it
Those are off the top of my head. I use them in many other places
Attributes are very good at describing some runtime behaviour of your code that is orthoganal to the code in question. For example, in a class called Customer you would model a customer, right? But you might not want to model or describe the way a Customer object is serialized.
Adding attributes to your Customer class allows you to tell some other part of the runtime how it should deal with your Customer.
MSTest and NUnit makes use of attributes to tell the test framework how it should use classes that define test fixtures.
ASP.NET MVC uses attribute to tell the mvc framework which methods on classes it should treat as controller actions.
So, any place where you have a runtime behaviour that you wish to model attributes can be useful.
Class Attribute definition is available here
ClassInterfaceAttribute : Indicates the type of class interface to be generated for a class exposed to COM, if an interface is generated at all.
ComDefaultInterfaceAttribute : Specifies a default interface to expose to COM. This class cannot be inherited.
ComVisibleAttribute: Controls accessibility of an individual managed type or member, or of all types within an assembly, to COM.

Categories

Resources