Tjena.. jag har börjat lite smått med att programmera C# och tycker det verkar shjysst... men så idag så skulle jag börja skriva på ett program som jag vill ska vara dynamiskt genom att man kan utveckla egna bitar på det så jag vill att det stödjer plugins. http://www.codeproject.com/csharp/C__Plugin_Architecture.asp FixedDialog... tack för den! :D Så här har jag gjort på nåt ställe vet jag: Du gör precis som du har gjort, men skit i att skapa objekt av typen objekt. Jag gör nästa identiskt som du... jag har kollat om det är en klass, jag har även kollat vilken klass samt att det är rätt interface... allt stämmer.. (dock använder jag Activator.CreateInstans, men i det avseendet så funkar båda sätten). Det skiter sig när jag ska typkovertera den... Pluginvariabeln är av samma typ som ditt interface Japp... har gjort precis så... ...det är inte så att du borde använda objType[0] istället för objType[1] Nej... har testat det också :) Jag har skapat ett projekt där jag gör ett plugin till ett huvudprogram.. projektet finns att hämta ner här. Prova det här: tyvärr... ger samma fel :( Du har ju 2 definitioner av IPlugin (en i varje projekt). IPlugin är ju samma interface på båda... dvs jag har 1 definition.. hur annars skall man själv kunna utveckla ett plugin för en applikation om man inte kan använda dess interface? You got mail, har skickat ett exempel till dig. Lägg ditt interface i ett eget project och se till att du har hårdspecat versionsnummret i assemblyinfo.cs Tack alla för hjälpen!Skapa stöd för plugins
Jag har gjort lite efterforskningar osv och kommit halvvägs skulle jag tro...
Jag har specat interfacet, byggt dll:erna och lyckats läsa in dom med Assembly.Load()... problem nu är att jag vet inte vart jag ska ta vägen med assemblyn... jag läste i nått exempel att jag skulle göra i stil med
Type objType = ass.GetType(...);
för att få ut typen, sen ska jag skapa en instans med Activator.CreateInstance(objType); och typecasta den till det interfacet pluginet är i.. men det funkar inte (Jag vet, jag vet :) "Det funkar inte" är en av mina hatmeningar också! :P)
Iaf, jag utlyser ett exempel, steg för steg på ett enkelt litet plugin system så att jag kommer igång och får ett som funkar... nån som kan göra ett exempel?
Till sist 1 liiten fråga... HUR... för GUDS SKULL hindrar jag ett formulär att inte kunna ändra storlek? Jag hittar ingen setresize metod eller resizable eller nått... hur gör man? Sv: Skapa stöd för plugins
http://www.divil.co.uk/net/articles/plugins/plugins.asp
http://msdn.microsoft.com/asp.net/community/authors/royosherove/default.aspx?pull=/library/en-us/dnaspp/html/pluginframework.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp05162002.asp
http://msdn.microsoft.com/msdnmag/issues/03/10/Plug-Ins/default.aspx
Du borde kunna sätta din forms FormBorderStyle till FixedDialog
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformsformclassformborderstyletopic.aspSv:Skapa stöd för plugins
iaf ang länkarna... dom flesta hade jag redan tittat igenom, och jag har hittills kommit fram till följande kod:
...
string path = "plugin";
Assembly ass = Assembly.Load(path);
if (ass != null) {
Type[] objType = ass.GetTypes();
if (objType != null) {
//status_msg = objType[0].ToString();
//status_msg += " - ";
//status_msg += objType[1].ToString();
Object o = (Object) Activator.CreateInstance(objType[1]);
status_msg = "Loaded: " + o.GetType();
} else {
status_msg = "Failed to load DLL";
}
} else {
status_msg = "Unable bla bla...";
}
...
Jag har alltså lyckats läsa in dll:en samt skapa en instans av den i ett objekt av typen object MEN jag får inte typkonvertera den till ett object av det interfacet jag vill.
IPlugInterface är mitt interface... så jag provar:
IPlugInterface e = (IPlugInterface) Activator.CreateInstance(objType[1]);
då får jag "Specified cast is not valid.".
får samma fel om jag försöker
PPlugInterface e = (PPlugInterface) Activator.CreateInstance(objType[1]);
där PPlugInterface är en klass som implementerar interfacet.
så frågan är... hur går jag till väga för att skapa en instans av det inlästa objektet?
Sv: Skapa stöd för plugins
...
Assembly asm=Assembly.LoadFrom(path);
Type[] types=asm.GetTypes();
bool found=false;
for(int i=0;i<types.Length && !found;i++)
{
if(types[i].IsClass && IsInterface(types[i],"MyProgram.IPlugin")) //kolla om det är en klass och implementerar MyProgram.IPlugin
{
try
{
object obj=asm.CreateInstance(types[i].FullName); //skapa instans
if(obj!=null)
{
plugin=(IPlugin)obj;
plugin.OnStart();
found=true;
}
}
catch(Exception e)
{
....
}
}
}
...
private static bool IsInterface(Type type, string interfacename)
{
Type itype=type.GetInterface(interfacename);
if(itype!=null)return true;
else return false;
}
Sv: Skapa stöd för plugins
<code>
public void LoadDaShit(ComponentName)
{
Myinterface.IStuff frm = null;
frm = (Myinterface.IStuff)Activator.CreateInstance(Type.GetType(ComponentName));
frm.DoSomething();
}
</code>
Myinterface.IStuff är interfacet som alla komponenter skall implemntera för att kunna fungera som plugins.
Pluginen finns en databas där de lagras med en sträng, "My.frmFunkyModule, MyModuls" där första delen är vilket objekt som skall laddas och sedan i vilken fil det ligger. Självklart kan man göra en funktion som söker igenom atlla dll'er för att få reda vilka objekt som kan användas som plugins's, har gjort det en gång i tiden,Sv:Skapa stöd för plugins
du skriver:
plugin=(IPlugin)obj;
av vilken typ är "plugin" variabeln? hur deklarerar du den?
IPlugin plugin = null;
...
plugin=(IPlugin)obj;
Jag gör samma fast med mitt interface heter IEncryptionAlgorithm, måste det heta IPlugin?Sv: Skapa stöd för plugins
<code>
IEncryptionAlgorithmplugin = null;
...
plugin=(IEncryptionAlgorithm)obj;
</code>
Eller kortare i ditt fall:
<code>
IEncryptionAlgorithm o = (IEncryptionAlgorithm) Activator.CreateInstance(objType[1]);
</code>Sv:Skapa stöd för plugins
det är det som är konstigt... att det inte funkar. 2 pers har kollat på det och har konstaterat att det "borde" funka.... det är nått som inte stämmer... kanske postar hela koden här så småningom...
tills vidare, tack för hjälpen!Sv: Skapa stöd för plugins
</spånar>Sv:Skapa stöd för plugins
objType[0] returnerar IEncryptionAlgorithm, alltså interfacet, när jag använder det så står det att jag inte kan skapa ett objekt av ett interface...Sv: Skapa stöd för plugins
http://student.chl.chalmers.se/~it3mazh/ptest.zip
om någon vill testa och säga ifall det funkar för er eller inte, ev hitta några fel... för mig funkar det inte ... Skriv något här på forumen om det är så att ni är osäkra på vad jag gjort men det bör vara väldigt straight forward..
Programmet ska funka fint men för att få fram problemet så ska man fixa lite.
I filen Form1.cs i metoden Form1_Load ska man ta bort kommenten för dessa rader:
...
// This should work... But I get "Specified cast is not valid."
IPlugin ipi;
ipi = (IPlugin) o;
...
detta generar för mig ett exception med meddelandet "Specified cast is not valid."
Nån som har någon aning om varför?
Sv:Skapa stöd för plugins
private void Form1_Load(object sender, System.EventArgs e) {
Assembly ass = Assembly.Load("Plugin1");
foreach (Type type in ass.GetTypes()) {
if (type.GetInterface("IPlugin") != null)
{
try {
IPlugin plugin = (IPlugin)ass.CreateInstance(type.FullName);
break;
}
catch (Exception ex) {
textBox1.Text = ex.Message;
}
}
}
textBox1.Text = "OK";
}Sv: Skapa stöd för plugins
i din kod, byt ut:
textBox1.Text = "OK";
med
textBox1.Text += "OK";
så ser du att felmeddelandet dyker upp...
eller det kanske fungerar för dig? Tack iaf för svaret.Sv:Skapa stöd för plugins
Jag använde den som fanns i Host-projektet och gjorde om den till en medlem i Host-namespacet. (obs public interface)
namespace Host
{
public interface IPlugin
{
int getNumber();
}
}
Ändrade lite på deklarationen av Plugin1
public class Plugin1 : Host.IPlugin {
public int getNumber() {
return 5;
}
}
och tog bort IPlugin från Plugin1-projketet
Då fungerade detSv: Skapa stöd för plugins
när jag försöker mig på ditt exempel så får jag problem med Host.IPlugin... den säger att den inte hittar namespacet... skulle du kanske kunna spara ner projektet som du får att fungera och zippa ihop det och maila det till mig? (it3mazh@ituniv.se)
Jag försökte ett annat sätt att lägga till en existerand fil och valde den som finns i Host projektet men det funkade inte heller.... börjar tappa hoppet på C# :P heheSv:Skapa stöd för plugins
Definera Interfacen i ett eget projekt, på så vis kan du distribuera Interfacet till andra utvecklare utan att behöva distribuera någon konkret klass som implementerar interfacet. På detta vis så använder alla samma definition av interfacet.
Du har Iplugin.cs både i Host- och i Plugin1 projekten och även om definitionen är lika så är de inte SAMMA Interface. Jämför ett enäggs-tvillingpar, det har likadan definition (gener) men de är inte en och SAMMA person utan två olika individer som kan ha olika kunskaper och färdigheter.Sv: Skapa stöd för plugins
om du inte har det så kommer du få precis de fel du beskriver ,för om ett projekt kompileras om så kan det bli så att det vet att det har en ref till interfacet med v 0.0.xxx medans något annat av dina projekt har en ref till v 0.0.xxy
och då kommer den skrika när du försöker typecasta.
//RogerSv: Skapa stöd för plugins
Det löste sig till slut, så som så många av er har föreslagit så gällde det att göra ett eget projekt för interfacet och sedan kompilera det till en dll, sen lägga till den som referens... sen är det bara att typecasta :)