Hi folks,

I've created an application in VS2008 Express Edition. Some of my customers could potentially want slightly different features so I had the idea of moving the relavent stuff to a seperate dll (which works).

The problem is when I swap the dll with a different one I get the error:
"The located assembly's manifest defination does not match the assembly reference"

I'm guessing it's looking for a different version number of the dll.

Any ideas on how to over come this?
If this is just impossible with .NET, can anyone give me some other tips of maybe going about this an alternative way? Like maybe instead of call methods inside a dll, call a seperate application and get the 2 to talk to each other?

Cheers

Have you checked your reference properties for the DLL, and make sure it is not set to version specific ?

Simple solution is that remove the references of old dll from your project and add reference of new dll, build it and deploye it.

I think what Jonny wants to do is have two dlls with the same name. Some customers get the one version , and other customers get the other one.

Many programmers have a debug version of a class library, and the production version, and this is exactly what we do is to replace the production DLL on the target machine with the Debug version. Same file name is referenced in the project.

The property settings for the referenced class library is important to make this work.

Another approach, however more complicated is to dynamically load the DLL that you want to use, and deliver both. This is commonly referred to as Plugins or in VS lingo, Add-ons.

I write most of my large projects using the plugin approach because some customers need some extra feature, or want some feature totally different, so we just setup the main application configuration so they can pick the File they want to use from a menu or button, or preload the filename to use in a configuration file, and just load it for them. Another advantage, is that many programmers can work on the project at the same time without bumping into each other, and you can upgrade a customer site with just the changed libraries instead of monolythic exe.

There are many examples of building plugins for C# on the net, but if someone is truely interested in this approach, I can point them to the websites I used, and/or give them a hand in developing this capability into their own application. Its not difficult.

// Jerry

I think what Jonny wants to do is have two dlls with the same name. Some customers get the one version , and other customers get the other one.

Many programmers have a debug version of a class library, and the production version, and this is exactly what we do is to replace the production DLL on the target machine with the Debug version. Same file name is referenced in the project.

The property settings for the referenced class library is important to make this work.

Another approach, however more complicated is to dynamically load the DLL that you want to use, and deliver both. This is commonly referred to as Plugins or in VS lingo, Add-ons.

I write most of my large projects using the plugin approach because some customers need some extra feature, or want some feature totally different, so we just setup the main application configuration so they can pick the File they want to use from a menu or button, or preload the filename to use in a configuration file, and just load it for them. Another advantage, is that many programmers can work on the project at the same time without bumping into each other, and you can upgrade a customer site with just the changed libraries instead of monolythic exe.

There are many examples of building plugins for C# on the net, but if someone is truely interested in this approach, I can point them to the websites I used, and/or give them a hand in developing this capability into their own application. Its not difficult.

// Jerry

Jerry!

Thanks exactly what I want to do! I got this issue sorted (It was actually a referance naming problem) however I would like to take your advice and go with the "Add-On" method.

I'm really scratching my head over this. Is there any way to dynamically tell the main exe which functions to call? I mean, if a customer wants new features, and drops the new dll into the directory how do you:

a) Tell the main exe to find and load the new dll (keeping in mind that the dll file name will not be hard coded)
b)How would one dynamically ask the exe to call new functions in this new dll?

I'll give oyu my example. I'm writing ePOS software. I would like different payment modules for some customers. If a customer want me to integrate it with their fancy giftcard system, and assuming I know how to interface with it and have the required methods, how would i tell my program to call those new functions?

I'm sorry if I'm not explaining myself clearly.

Cheers,

Jonny

a) Tell the main exe to find and load the new dll (keeping in mind that the dll file name will not be hard coded)

What some plugin systems use is the file extension or a subdirectory where it knows add-ons will be located.

I use a configuration (XML) file that tells my program which files it is authorized to load. The configuration file has additional information for each plugin like the Menu text it will have, and under what menu it should appear.

b)How would one dynamically ask the exe to call new functions in this new dll?

There are two ways of doing this. I have seen some examples, where the main application will use reflection to find all the public methods in the plugin. The second method is what I use, and that is to create an interface, and have all of my plugins use that interface (and I only allow the main application to load plugins that are of this interface). Then your main application will know exactly what methods will be in every plugin.
Obviously we don't want to re-write the interface everytime we need to add some new method, therefore it is common to put a generic catch all method that we can pass a command to (a phrase with parameters). Example: All of my plugins have this method:

public void ExecuteCommand(IPlugin sender, string command, params Object[] Params)

Sender can be null, and is null when called by the main application (yes other plugins can call the method as well). If a plugin sent the command, then it will supply (this) as the sender.

The string command can be anything you want. The method can act upon this command, or ignore it, so that you can build a method in your main application to send a command to all currently loaded plugins.

Params is setup so you can pass as many parameters of any type you desire for the command to work with. There is even a way of sending the parameters, and have the plugin return values in the parameters you sent. For example I can send a command that asks a question:

object[] answers = new object[3];
Plugin.ExecuteCommand(null, "Get Customer Name and Phone", answers);

string firstName = (string)answers[0];
string lastName = (string)answers[1];
string phoneNo = (string)answers[2];

If you just want to send some instruction with some data:

Plugin.ExecuteCommand(null, "Print Report", "GeneralLedger.rpt");

A plugin offers polymophism because all of the Plugins that are of this interface will have the ExecuteCommand method. Two different plugins can take a totally different approach to the command and parameters passed to it. "Goto Customer","123" Could cause plugin #1 go to this record in a DataGridView, and plugin #2 could send an email to customer #123.

Plugins can be loaded into a form, panel, or any container, or they can be used as a service library for a variety of methods.

Sound interesting so far ?

Here are a couple links to read up on, and then if you want to take this route, let me know, and I can help you get started. The examples on these websites are just generic samples. They don't reveal some of the easier ways of implementing it, but good reading just the same.

http://www.codeproject.com/KB/cs/pluginsincsharp.aspx
http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx
http://msdn.microsoft.com/en-us/magazine/cc164072.aspx

// Jerry

Hi Jerry,

Thanks for the great advice! I def want to go down this route. I will tell you what I'm currently doing now and you can either suggest that I scrap it or modify it.

My Form (I belive you call this an interface) has buttons. Hard Coded into the program are button types. Here is what I have so far:

0) Product
1) Tender
2) quantity
3) void
4) till menu
5) Payment Module
6) Refund
7) Sale Module
8) Discount Module

N.B. When you see module, this is located in my seperate "modules.dll".

I have a Sqlite database which has a buttonmap table. In it are these fields:
buttonid
buttontype
value1
value2
buttontext

At program launch, the Form will read this database and looking at the button id and button type, it can tell what to do with them.

So for example if its a refund, it will call the refund method. If it's a "payment module", it will call the modules.payment.init(int value1) method (located in the seperate dll). This dll, given whats in value1, will know that this is for, for example, a giftcard. Then, using a series of return(1) and return(0), the main application can tell weather everything was sucessful or not.

I have to got to work now (On a sunday!) but I'll chat later this evening about this.

Please let me know how similar this is to your method and how good it is. This would be very much appreciated.

I am very keen to go down your route!

Cheers,

Jonny

Jonny,

Too bad you had to work today... got to pay the bills though :)

Plugins will certainly work in your case. Before jumping into that, let me offer another option for your situation.

Your reply in regards to "My Form (I belive you call this an interface)" makes me want to explain a little more about what an interface is.

Let me do that by providing an example of a program I am currently working on. I am building a communications driver for a piece of hardware that is capable of communicating either by TCP (sockets) or by Serial (COM1, etc). The user can set in the database which method of communications will be done for each board. The driver will handle both types of communication at the same time.
Both the Serial and TCP versions must have the same events, and methods definitions (at least those that are publicly visible).
What I did was create an interface named CommunicationsInterface

public [U][B]interface[/B][/U] CommunicationsInterface
{
        event ReceiveData onReceiveData;
        event SendData onSendData;
        event SocketConnect onSocketConnect;

        bool Open();
        bool Close();
..... many more
}

I placed all of the prototype methods and events into this interface file. Next I created two more classes TCPCom and SerialCom. These new classes derive from the CommunicationsInterface.

public class TCPCom : CommunicationsInterface
{
       public event ReceiveData onReceiveData;
        public event SendData onSendData;
        public event SocketConnect onSocketConnect;

        public bool Open(){...}
        public bool Close(){...}
}

-- Same for the SerialCom class as above

Now in the main application I can use either one of those classes by simply instanciating one of type CommunicationsInterface

private CommunicationsInterface _com;

public void SetComType( string comType )
{
      if( comType == "TCP" )
           _com = new TCPcom();
      else
           _com = new SerialCom();

      if( _com.Open() )
          MessageBox.Show("Connected");
}

Because both classes derive from CommunicationsInterface, the main application can call any of the methods without knowing anything more about the underlying class that will do the real work.
Obviously in this example, the Open() method is going to operate totally different in the TCPcom class as the one in SerialCom.

That is what an interface gives you. Plugins do the same thing, because each plugin must be of the same interface type so that the main application can call those primary methods we have to have to make plugins work, and the main application has no concern on which DLL it is working with, only that it is derived from the main Interface definition .

Hope that helps you understand what an interface is.

------
Okay, looking at your project requirements, sound fine to me, I build all of my menu and buttons from a database as well. I use the Tag property to hold special information such as the filename of the plugin to launch. So, I see nothing wrong with your approach.

I assume that all of your processing logic is inside the modules.dll
The modules.dll is referenced, and therefore all of the calls are validated during the compile. To replace the modules.dll file with a special version that has additional methods, means a recompile, and therefore the main application itself has become a special version.

Two options come to-mind. Create an interface with all possible methods and events for both the special and production versions, and just stub the special methods out in the production version.
OR
Create a generic command method like I posted earlier so that you can pass special commands to handle anything in the future.
You see, the compiler only looks at the public method prototypes of the referenced file during the compile. What the method does within each version of modules.dll is up to that file.

Hope this helps. If you are ready to get into plugins, let me know, and we will start off with creating an interface that all plugins will derive from, then we will create a simple hello world plugin, and third we will build a light weight plugin manager that will load the plugin on demand. Finally, the main application will be setup to use the plugin manager class.

Cheers,
Jerry

Hi Jerry!

I really appreciate your help!

With regards to my method.dll, the way I'm doing it is similar to the second way you mentioned. I have 3 public classes inside modules.dll:

Payment
Discount
Sale

And each of these classes has 2 public methods:
init
callback.

All the other processing is within private method in modules.dll and the "production version" (or in my case the "dummy version"), init and callback for all 3 classes are just blank. For an idea of what the init and callback methods in the payment class does, please goto http://dl.abpni.co.uk/eft-1.jpg (please ignore the red boxes). The harder ones are the discount and sale classes.

The problem (which makes my code very messy), is the returns from these public methods inside modules.dll as I have to account for lot of future plugins.

I'm ready to get started with plugins if your willing to help me :) I really appreciated your willingness to help me get this going!

I'm a VERY messy coder. Everything is all over the place. Just learning really. If you promise not to laugh, I can even show you my code if your willing to take a look at it. I understand if you do not want to do this - I'm sure your time is precious.

Cheers,

Jonny

Jonny,

You can send your code to me at shawjh@meadowcrk.com
Using the forum is more difficult to work out the details, so we can do it through emails.

// Jerry

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.