Pass object from one dll to another on the runtime - c#

I have 2 projects, in one project I have one form and class with different information, this information is acquiring only during runtime, now in another project I have another form, that will use the object of the first class to get the information and to put it inside form.
Basically I did some research and tried using Reflection for that, but all of the examples I found didn't work properly (actually didn't work at all).
Assembly a = Assembly.LoadFile("Server.GUI.LocalGUI.dll");
object o = a.CreateInstance("ServerManager");
Type t = o.GetType();
this is the code that I tried, not sure if it's correct...
I am using .net 2.0
Is anyone have working example of how to use data of one object in another dll on the runtime?

I have 2 projects : MyForm1 and MyForm2. Take reference of project MyForm1 in MyForm2. Fill MyForm1. Create a instance of the MyForm1 in MyForm2 and access the method and its value.
Or create another Library project. Expose a static variable in it. Take reference of this library in both the Forms projects. Assign some value from MyForm1 and access the same property in MyForm2.
But if you really want your code to be a managed code, try learning and implementing MVP. It may give you a new way to look at solutions for your problems.
You can even create both forms in same project. Process the data in a separate library.

if that is want you want to do - the you could do it like this:
Assembly a = Assembly.LoadFile("Server.GUI.LocalGUI.dll");
dynamic o = a.CreateInstance("ServerManager");
o.Method();
But i don't recommend this, unless you absolutly have to. Using the dynamic keyword can be at shortcut - but sometimes a shortcut to a place you don't want to go..

Related

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.

visual c# 2010 communicating between two projects

I am trying to create a windows form project, and use speech recognition for the Kinect with the Kinect to Windows SDK. I have
the form application project (p1) and
the Kinect speech project (p2) which is a command prompt.
I made it a command prompt because it was the easiest way to do things. Anyway, I have read and found two things about this.
1)I found out how to run two projects at the same time in the same solution.
2) I also found out how to add references to get classes from each project to the other.
So, how would I get variables from each project? Just by using project references, or something? P2 can recognize speech and save it to variables, if that counts for anything.
I made it a command prompt because it was the easiest way to do things.
That sounds like the problem. It sounds like really you should be looking at making your Kinect project a class library. Then you can just call into that class library from the Windows Forms application.
If you want a "test bed" console app, you can always write one which also references the class library.
Note that generally you shouldn't be sharing variables between projects - they're implementation details in most well-encapsulated systems - but you would create types which expose properties, appropriate methods etc.
Here's a couple of options if I'm understanding you right:
Add those variables to your classes as properties then
using Solution.MyNamespace;
in the class that uses the other project
If you have variables that need to be independent, consider adding a class library project called Abstract or something that both projects reference
I hope this might help,
Cheers
Another method is to use named pipes for interprocess communication.
MSDN has the references to use the name pipes API here.
Named pipes are part of the .NET framework and are a reliable method for communication without having to worry about access permissions on files.
To go down the static variable path, you would need to run a single process and turn one project into a dll and load the Program Main manually.
Of course you dont even need to use static variables but use synchronisation on reference variables passed in at load time. I would probably go this method if you didnt need to run two separate processes.
Just depends on what your goal is for having the projects separate processes.
Like #JonSkeet said, create a class library, then you can save the information like this:
public class SpeechRecognizer
{
public List<string> SpeechRecognized = new List<string>
{
};
public void SaveRecognizedSpeech(string foundSpeech)
{
SpeechRecognized.Add(foundSpeech);
}
}
In code:
SpeechRecognizer sr = new SpeechRecognizer();
sr.SaveRecognizedSpeech("blah blah");
sr.SaveRecognizedSpeech("BLAH BLAH");
Console.WriteLine("{0}, {1}", sr.SpeechRecognized[0], sr.SpeechRecognized[1]);
Console.Read();
Oh and to make your whole program know variables(I hope these are both in the same solution!) make them public. Hope this helps!

How can I pass a reference type between Assemblies referencing a common DLL?

High level: I am trying to build a console app (e.g. ConsoleApp.exe) which can perform some processing on any given DLL which references a certain type defined in ConsoleApp.exe.
I decided, maybe mistakenly, that I would need a companion DLL for ConsoleApp which contained the type or types (e.g. ConsoleClass) which were intended to be referenced by arbirary DLLs. To pull this off, as I don't know of a better way, I have two projects in the ConsoleApp solution, one is a class library (Proving ConsoleApp.dll) and the other is a console application which references the class library project.
At this point, I now am able to copy my ConsoleApp.dll to another relatively unrelated project in a separate solution (e.g. OtherApp.dll), reference it, and write a method which consumes a ConsoleClass instance as a parameter.
Now, in order to arbitrarily process this OtherApp.dll, the ConsoleApp.exe loads that Assembly, instantiates the proper class in that Assembly, and then calls the proper method on that instance. Pertinent lines below hopefully provide context to how I am doing this:
Assembly.LoadFrom(path_to_OtherApp_dll);
...
var x = (dynamic)Activator.CreateInstance(type_inside_OtherApp_dll);
...
var instance = new ConsoleClass();
x.some_method_call(instance);
Ultimately this fails. It seems to be because even though the two projects (ConsoleApp.exe and OtherApp.dll) are referencing the same DLL to define ConsoleClass, the runtime still considers them to be different types.
Any thoughts?
Define the public interface. Put it to its own interface.dll.
Reference interface.dll in your plugin. Let the main class in your plugin.dll implements your interface.
Reference interface.dll in your exe.
Use Assembly.Load() or Assembly.LoadFrom() to load plugin into your exe.
Use CreateInstance() to create instance of your plugin class.
Simply cast created plugin to your interface type.
So you don't need "dynamic" or other complicated things. Just easy, go step by step as I wrote and it will work. Good luck.
Yes, this will happen when ConsoleApp.dll gets loaded twice. Once by the main app, again by a plugin, using its local copy. A type's identity is determined by the assembly it was loaded from.
It isn't that clear to me how that happened. Your first weapon of choice is Fuslogvw.exe, set it up to log all the binds. First thing to do is to doctor the plugin project and set the Copy Local property of the ConsoleApp.dll reference to False so that extra copy isn't there to get accidentally used.
Copying the plugin DLLs to the main app build folder is the never-have-trouble solution, you can load them with Assembly.Load(). Or a subdirectory with a .config file that uses the <probing> element to allow the CLR to find them.
What do you by "runtime is considering them to be of differnt type"? does setup ends with some exception of error? does method in x variable receives something it does not recognize or what?

How to Create a C# Library that is Loaded into Memory only Once?

I would like to create a Class Library DLL in C#, that will have a Static Class in it.
That static class has 1 private static member(int), with a public static property for it.
What I want is, that for Every C# Application that references this DLL, it will get the same static class.
Meaning If Application1 changes the static member's value to be 5,
and then Application2 tries to get the value of the propery, it will get: 5.
Despite the fact that those are two different applications(EXEs).
In simply words, I want this whole class library to be "static",
so only once will be loaded of it to memory, and then its single value will be shared accross different EXEs that reference it.
Thank you
An attractive solution to shared data amongst all processes on the same computer is shared memory. You will have to rewrite your properties to retrieve the shared value, and the class will be loaded multiple times into each process that uses your library, but it will behave as though there were only one copy, if you do it correctly.
Here is a StackOverflow question to help you get started:
How to implement shared memory in .NET ?
It links to a complete shared-memory library you can use.
What you're looking for is some form of IPC or RPC. One option is .NET Remoting.
I am Omer, I registered so it looks as if I am a different user.
Regarding what Damien_The_Unbeliever said, allow me all to describe what I generally want to do, so you can direct me towards the best solution for that case.
I have created a nice application.
This application has a GUI.
I want to add another way to operate this application, which will be via exposing an API for it - methods and properties that other applications can use, to operate my application.
And what I plan to do is:
Create a DLL with a static class,
put the core of my application in that class,
and then have the GUI, and potentially all other applications, use that class.
please note that this class will hold not only data that can be stored,
but also references to "live" objects(i.e. open coomunication ports, etc etc),
so storing to disk, and reading from it will not be a good solution here.
I need this 1 static class, to be accessible from all applications that want,
and that all of them will get the same static class.
So, I need this class to be static, and I need the library to be "static".
(no such thing in .NET as "static library", I know. please note that I am not talking about static library like in C++ - there it's something else.. I am talking about a DLL that is created once only, for all applications who use it).

Using Scripting.Dictionary from C#

I need to pass a Scripting.Dictionary between my C# app and another app. I would like to be able to create instances of and modify the dictionary in my C# app.
I know little about Scripting.Dictionary and ActiveX in general. Various forums suggest that I should use functions like System.Type.GetTypeFromProgID() and System.Activator.CreateInstance() to create an instance. Unfortunately this means that it's an opaque object to the rest of my code.
Is this really how it's supposed to be done or is there a better way? Ideally I'd like to import a compile-time type and just use it like any other type. Is this possible?
This article suggests I obtain a "metadata assembly" from the vendor - does anyone know if such an assembly exists for Scripting.Dictionary?
I've just tried the easiest approach, and it seems to work:
Add a COM reference to the scrrun.dll in Visual Studio (it should show up in the COM tab of the Add References dialog), and Visual Studio will automatically create the interop files for you. You can then write code like this:
Scripting.Dictionary d = new Scripting.DictionaryClass();
d.Add( ref myKey, ref myValue );
MyComType.Method( d );
If you have any trouble with that, I can post some more examples, or perhaps a clarification.
Create a wrapper dictionary class which implements IDictionary and which uses the Scripting.Dictionary as its internal storage implementation. Use the wrapper in your .NET code and pass the inner Scripting.Dictionary via COM to the other app.

Categories