5

Ich erstelle Web User Controls über Code (meine C# -Code-Schreib-Markup-, Code-Behind-und Designer-Dateien auf der Festplatte auf einen Rückruf). Die Steuerelemente sind alle in Ordnung. Ich kann sie zu meinem Webprojekt hinzufügen und sie auf eine Seite stellen.Loading ASCX-Steuerelement dynamisch erstellt (über Code)

Wenn ich versuche, um die Steuerung zu laden LoadControl(path) mit ihm sagt:

Unable to load type 'MyNameSpace.UseControlClass' 

die wegen Kontrolle ist noch nicht erstellt.

Aber meine Anforderung besteht darin, Steuerelemente dynamisch zu laden, ohne die Lösung neu zu kompilieren.

Wie kann ich das Benutzersteuerelement nur kompilieren, wenn ich die Steuerdateien erstelle? Dies scheint der einzige Ausweg zu sein.

BEARBEITEN: - Was meine Vermutung ist, dass, da die Datei noch nicht kompiliert ist, es nicht erlaubt ist, von Laufzeit geladen werden. Ich habe versucht, die Codedatei mit CodeDom Compiler zu kompilieren. Wie:

var filePath = Server.MapPath(path); 
var provider = CSharpCodeProvider.CreateProvider("C#"); 
var opts = new CompilerParameters(new[] { "mscorlib.dll", "System.Web.dll", 
           "Telerik.Web.Design.dll", "Telerik.Web.UI.dll", 
           "Telerik.Web.UI.Skins.dll", "MyCurrentDll.dll"}); 
opts.GenerateExecutable = false; 
opts.GenerateInMemory = true; 
var cr = provider.CompileAssemblyFromFile(opts, new string[] { filePath+".cs" }); 

Aber es klagt cannot find metadata file Telerik.Web.Design.dll über usw. Ich will nicht den telerik Weg codieren, wie es in gehostete System anders sein könnte (obwohl es in den bin des aktuellen Web-App ist). Auch MyCurrentDll.dll ist die DLL der Datei, aus der ich die Codedatei kompiliere. Wie kann ich das beheben?

Meine Idee ist, die Codedatei zu kompilieren, erstellen Sie eine dll dynamisch und kopieren Sie es in Webanwendung bin Verzeichnis. Es könnte das von mir ursprünglich gestellte Problem lösen.

BEARBEITEN 2: - Nach Treffer und Test kann ich die Codedatei dynamisch kompilieren und dll generieren. Auch nachdem ich eine DLL erzeugt habe und sie in bin meiner Anwendung platziert habe, kann ich keine Benutzersteuerung mit virtual path laden. Ich habe den folgenden Ansatz versucht:

var asm = Assembly.Load("ddlPath"); 
var t = asm.GetType(fullTypeName);//NameSpace.Class 
var ctrl = LoadControl(t,null); 

Die Strg wird nach diesem geladen. Ich weise seine Eigenschaft Id zu und füge sie zu einem asp.net Panel Steuerelement hinzu. Aber es ist nicht sichtbar nach dem Postback :(

Jetzt muss ich entweder irgendwie die dynamisch kompilierten DLL-Typen für die Laufzeit zur Verfügung stellen (appdomain, vielleicht), so dass wenn ich die Steuerung mit virtuellen Pfad laden wird es richtig geladen und ich nicht bekommen HtmlParseException oder herauszufinden, warum Verladesteuerung Form Type nicht auftauchend

PS: -. ich habe geladen, um eine Label Steuerung mit Type und es ordnungsgemäß funktioniert

+0

Das ist eine wirklich interessante Frage. Ich kann mir dafür keinen Anwendungsfall vorstellen - aber die Art, wie ich das normalerweise anwende, ist eine andere Assembly, die weiß, wie man Steuerelemente erstellt und zur Laufzeit den HTML-Code usw. ausgibt. Vielleicht wäre hier ein ähnlicher Ansatz möglich, indem Sie Ihre neuen Steuerelemente in eine andere Assembly einbetten, aus der Sie dann kompilieren und laden können. Ich werde diese Frage mit Interesse verfolgen! – dash

+0

@dash Der Use Case erlaubt es dem Benutzer, einige Felder (mit vordefinierten Eingabetypen) zu gruppieren und Eingaben vom Endbenutzer zu erhalten. Ich möchte ein Benutzersteuerelement erstellen und diese Felder einbetten. – TheVillageIdiot

+0

Sind Ihre Steuerelemente und Hosting-Seite in CodeFile anstelle von CodeBehind? – jbl

Antwort

2

Am Ende konnte ich das Problem lösen. Es folgt der Strategie, die ich angenommen:

  1. Textdateien erstellen enthaltende Struktur von CodeBehind, Markup und Designer Code
  2. Lesen Sie die Information, welche Felder zu erstellen.
  3. Setzen Sie Markup für Steuerelemente, die in String-Buildern benötigt werden.
  4. setzen einige andere Informationen in mehr String Builder
  5. schreiben Dateien

Danach ich die dll mit CodeDome Compiler erstellt. Das Hauptproblem bei der Übersetzung konfrontiert, wie in Edit Teil der Frage beschrieben, war nicht referenzierten Assemblys zu finden, die, indem Weg des bin Verzeichnis Pfad zusammen mit DLL-Datei Namen wie aufgelöst wurde:

Server.MapPath("~/bin")+"\\Telerik.Web.dll" 

usw.

Das nächste Problem, das in EDIT2 umrissen wird, war etwas einfacher. Es war ziemlich schwachsinnig. Es gab ein Problem in einem anderen Benutzersteuerelement, das in dynamisch generierte Benutzersteuerung eingebettet ist.

Auch danach konnte ich das Steuerelement nicht in die Seite laden, von wo ich den Code kompiliert habe. Dies wurde behoben, als ich das Steuerelement auf eine andere Seite geladen habe. Die Laufzeit konnte den Typ von dynamisch kompilierten dll auflösen.

+0

Können Sie Ihre Antwort akzeptieren, damit sie aus der unbeantworteten Warteschlange entfernt wird? –

1

hmm .. haben Sie darüber nachgedacht, mit. App_Code folder für diesen Zweck?

Enthält Quellcode für gemeinsam genutzte Klassen und Geschäftsobjekte (für Beispiel-, ..cs- und .vb-Dateien), die Sie als Teil Ihrer -Anwendung kompilieren möchten. In einem dynamisch kompilierten Website-Projekt kompiliert ASP.NET den Code im Ordner App_Code bei der ersten Anforderung an Ihre Anwendung. Elemente in diesem Ordner werden dann neu kompiliert, wenn Änderungen erkannt werden.

+0

das wird mir nicht helfen, da ich ein Benutzersteuerelement erstellen und die Dateien werden auch dynamisch zur Laufzeit erstellt. Das Problem bestand darin, die erstellten Dateien in der App-Domäne zu laden, um ein Steuerobjekt zu erstellen. Ich habe es gelöst und werde bald eine Antwort schreiben. – TheVillageIdiot