c# plugin system question - c#

so I implemented a really simple plugin system.
i have the following Assemblies:
MainApp
IPlugin
PluginApp
Both MainApp and PluginApp conatin a reference to the IPlugin. Now, in MainApp I scan a plugins folder and search for things that implement the IPlugin interface.
However, it is not working because both MainApp and PluginApp reference their own copy of IPlugin.dll so they are not recognized as a match when using Type.IsAssignableFrom()!
help?

You could try putting your code that defines the plugin into a satellite dll assembly. That way both your main code and the plugins reference the same types.
If the plugin can maintain it's own dll instead of using the same dll as the application you will run into versioning issues. How will your main app handle calling plugins that don't implement the same interface?
When we did this in our own software we had to resort to reflection method calls instead of casting to the interface. It wasn't elegant.
What about adding the assemblies dll into the plugin directory. They have to reference the dll when they create their application, but force them to use the main assemblies version of the dll when the plugin is actually run?

Related

How can I reference a com visible C# dll in a vb6 library project using a manifest?

I have a c# com visible dll and I want to call this dll in vb6 project, which also generates a dll.I am not using regasm.exe to do this call, instead of that I am using manifest generation for the c# dll and then creating its tlb and calling it from vb6.
I have created two interfaces in c# dll one is Itest and another is Itest2,made both interfaces comvisible and added Guid to both interfaces,there are two classes named testimp and classimp which implement both the interfaces respectivly.These both classes are comvisible, Classinterface type as none and have their respective GUID.
The problem is that I am able to instantiate only testimp class from my vb6 project not classimp class.
COM registrations are usually referenced from the TLB GUID - which is to be registered in the registry
How to register a legacy typelib (.tlb) on Windows 7?
Note that on Windows Vista and up (IIRC) it's also possibly to deploy with application-local COM registrations in a .manifest file:
Registration free COM Interop
If your problem is per user install, use Regasm to create a regfile, then edit the regfile to change references to HKCR to HKCU\Software\Classes.

How to organize references for plugin DLLs in .NET

I'm working on an application that loads in plugins through Assembly.Load. I want to make sure plugins DLLs don't contain more compiled code then they need. Currently I've got 2 projects:
Application
MyPlugin
MyPlugin has a class implementing IPlugin from the Application project, and references the project to do so.
Is this the correct way to do it or should I put IPlugin (along with interfaces for anything plugins need access to) in a separate project, or is there some other better way to do it?
I would definitely create a new project containing only the contracts (interfaces) which could be referenced by the plugin projects. Besides, take a look at MEF
this is a great way to create a plugin architecture in .NET. And it also is a part of .NET.

Using tlbimp without needing a second assembly?

I am trying to implement a COM interface in my C# dll for others to consume. I have defined an interface in foo.idl.
I've run foo.idl through tlbimp to produce foo.dll, a .Net assembly. Now to implement my interface, I can reference foo.dll in my dll to implement the interface.
This works perfectly as it stands with one exception: I now have to distribute two dlls instead of one. This actually goes against the requirements of the project I'm working on: deliver one DLL.
Is there a way to merge the tlbimp dll into mine, or any other way to do this (implement a COM interface in C# without the second dll)?
A good disassembler gets the job done, like Reflector. You can simply disassemble the interop assembly and copy the generated C# interface declarations into your source code. Of course you should only do this if the interface declarations and IIDs are stable.
And definitely consider upgrading to VS2010. Its "embed interop types" feature allows you to ship your assembly without the interop assembly.
You could probably cheat by using a .tlb instead of the 'glue' dll.
I'd suggest you create a mixed-mode assembly using MSVC++/CLR
http://msdn.microsoft.com/en-us/library/k8d11d4s(v=vs.100).aspx
Interop (How Do I in Visual C++)
This might have the drawback that you can't use C# in the same assembly. Should you want to add C# code to the mix, you might be able to squeeze out of your tough situation using
IlMerge
For other, possibly interesting, thoughts see my earlier answer:
Is it possible to compile a console application into a single .dll file?

Converting .exe project to class library

I have a semi-large C# .exe project in visual studio 2010 Ultimate, and I would like to convert it to a DLL class library. Is there an easy way to do this that doesn't involve creating a new class library project? Thanks beforehand.
Project > Properties > Application tab, change Output type to "Class Library".
For the record, this isn't actually necessary. An EXE project works fine as an assembly reference. Assuming classes were declared public, something you might have to fix anyway to make them work in a library.
In .NET, an .exe and a .dll are both legal as references. This is because in .NET, there exists two type of assemblies:
process assemblies - known in public as executables, or exe
library assemblies - known in public as dll
An assembly in .NET holds many modules, that in turn holds one or more classes (the guideline is one class per module). These modules is turned into IL code at compile time and JIT'd at runtime.
The important part for both types of assemblies is that each assembly holds meta data like
modules
methods
types
there exists in an assembly. And because of that the runtime, and compiler, can easily determine how to fx call a certain method in a process assembly.
I think, without being an expert on the subject, that the major difference between process assemblies and library assemblies is that process assemblies holds some extra code, telling the runtime how to load, and what to load.
Go into My Project in your solution, select the Application tab, and change the Application type to Class Library.
right click on project and goto its properties and look for the Configuration type in Configuration Properties then change it to .lib from .exe ... this changes the application type from executable to library

How can I use a C# (managed) dll that I don't have?

How can I correctly reference a C# DLL that I don't have physical access to? (I actually have the DLL, just not all it's dependencies.)
Background:
On the target computer, there is a program and many interdependent dll files installed in C:\FancyProgram.
I need to write a simple application that will be deployed on the target computer to C:\SimpleProgram.
This simple program will need to make some calls into one of the dll files under C:\FancyProgram. It is a .net managed DLL
On my development machine, I do not have a copy of FancyProgram. I do have that one DLL file, but I do not have any of it's many dependencies. I also can not bundle that DLL into SimpleProgram.
What is the correct method to use and reference this DLL in my Visual Studio project such that my SimpleProgram will correctly compile but load the DLL at runtime from the correct location?
Thank you
My recommendation is to create a Facades for the functionality you want to use from that dll. And don't use (reference) it directly - resolve and load it dynamically:
C# - Correct Way to Load Assembly, Find Class and Call Run() Method
Load Assembly at runtime and create class instance
.Net will do late binding anyway. As long as you don't reference the .dll in any way until you actually mean to load it this will work.
Simply encapsulate all references (fields, properties, methods, instances) into a spearate class or project and make an instance only when you have to. You can then try-catch the load error.
See Visual Studio Output window when your app is run, it will tell you when its is attempting to load what .dll.
You may also want to look at these events to make your app handle errors gracefully:
AppDomain.CurrentDomain.AssemblyLoad += ...;
AppDomain.CurrentDomain.AssemblyResolve += ...;
AppDomain.CurrentDomain.UnhandledException += ...;
AppDomain.CurrentDomain.FirstChanceException += ...;
You may also want to take the MEF approach. It is a framework for doing late loading/binding.
You might want to look at the details of LoadLibrary, GetProcAddress and Marshal.GetDelegateForFunctionPointer.
I would also build dll for testing locally, with the same interface as your external dll. How much functionality yo put in there depends on the complexity of the interface and your SimpleProgram.
There were some excellent answers to my old question about importing external dlls.
Uhhhh, what are you going to do about testing it? Assuming you've figured that out you need to make sure that either the .dll is in the GAC and reference it that way (ideally) or the .dll needs to be in the same place on all computers. Add the .dll in your references and mark it as Copy Local: false, so you don't deploy it. Good luck.

Categories