Instanțiind o clasă dinamic c #

Lucrez la dezvoltarea unui cadru plug-and-play în ASV.Net MVC, prin care pot defini module ca proiecte separate de proiectul Principal. Deci, un dezvoltator poate crea cât mai multe module pe care le doresc.

Ceea ce am nevoie este ca să fie capabil să actualizeze setările oricăror astfel de module. Pentru aceasta, în proiectul principal, am definit o clasă de bază pentru unele setări comune, plus fiecare modul are propriile setări personalizate. Când există o editare pe un modul, trebuie să instanțiate instanța acelui modul în proiectul principal. Dar, proiectul principal nu are cunoștințe despre module.

Cum pot realiza acest lucru?

Mulțumiri!

0
acest lucru sună ca un loc de muncă pentru cadre precum unitatea sau spring.net (injecție de dependență)
adăugat autor deostroll, sursa
cât de familiar sunteți de reflecție?
adăugat autor Marc Gravell, sursa

2 răspunsuri

Puteți utiliza injecția de dependență și puteți injecta acele module la aplicația dvs. la rădăcina compoziției. Pe configurație puteți folosi codul sau xml (fișier de configurare). Puteți face cablare automată, legare târzie etc, în funcție de ceea ce aveți cu adevărat nevoie.

De asemenea, puteți avea inițializatoare la fiecare modul, de fiecare dată când înregistrați un modul, acesta ar trebui să inițializeze modulele dvs. înregistrate și să injecteze dependențe etc.

0
adăugat
Îmi puteți oferi un exemplu de legătură care face acest lucru? Pentru moment, orice exemplu IOC ar trebui să fie bine. Odată ce am o idee, o pot schimba mereu în funcție de CIO pe care o voi folosi.
adăugat autor annantDev, sursa

În funcție de nevoia dvs., va trebui să creați o soluție bazată pe interfețe.

În esență, aplicația expune o DLL API cu o interfață numită IModule. IModule are o metodă numită Run (). Aplicația dvs. principală va încărca ansamblul modulului, va căuta ceva care implementează IModule, face unul dintre acele obiecte și solicită Run() pe el.

Here is an old article describing how to host a sandbox to run modules inside. http://msdn.microsoft.com/en-us/magazine/cc163701.aspx

namespace MyApplication.Api 
{
    public interface IModule
    { 
       void Run();
    }
}

Dezvoltatorul ar crea ceva de genul asta

public class MyObject : MarshalByRefObject, IModule
{
    public void Run()
    {
       //do something here    
    }
}

Aplicația o va încărca cu un fel de Reflecție.

public void LoadModule()
{
     var asm = System.Reflection.Assembly.Load(/* Get the developer module name from somewhere*/);
     var types = asm.GetExportedTypes();
     foreach(var t in types)
     {
         foreach(var i = t.GetInterfaces())
         {
             if(i == typeof(IModule))
             {
                 var iModule = System.Activator.CreateInstance(t);
                 iModule.Run();
             }
         }
     }
}

Ar fi mai bine să rulați codul într-un alt appDomain, dar adaugă o mulțime de complexitate.

public void LoadModuleInAppDomain()
{
   //Spin up a new AppDomain

   //Load the assembly into the app domain

   //Get the object

   //Call the Run Method

}
0
adăugat
Mulțumesc pentru soluție. Totuși, aceasta rezolvă parțial problema mea. Încă nu sunt sigur cum proiectul principal va trece obiectul la Run (), astfel încât fiecare modul să poată lua acțiuni adecvate cu valorile obiectului (cum ar fi actualizarea valorilor în DB etc.)?
adăugat autor annantDev, sursa