Sonntag, 3. April 2011

Javascript aus WebParts für Sharepoint und Web Projekte registrieren

Javascript, wie etwa JQuery,  aus WebParts heraus zu rendern ist eine häufige Anforderung. Wie so etwas, beispielsweise mit Hilfe eines DelegateControls, gelöst werden kann, zeigt ein Artikel von Thorsten Hans.

Nun stand ich aber vor der Anforderung den WebPart in Sharepoint sowie eine WebForms Seite einzubinden. Grundsätzlich ist dies auch mit dem DelegateControl zu realisieren. Mein Vorgehen ist aber etwas Quellcode-zentrischer und ich möchte alles Renderverhalten in einem WebPart aus dem Quellcode heraus steuern.

Für Sharepoint gibt es hierfür die Klasse ScriptLink, in Web Projekten hingegen wird aber der ScriptManager verwendet. Um dennoch beide bedienen zu können habe ich einen Kontrakt IScriptRegistrar erstellt, der nur eine Methode RegisterScript beinhaltet.

public interface IScriptRegistrar
{
    void RegisterScript(IScriptRegistrationParameters registrationParameters);
}

Als Parameter wird eine Klasse erwartet, die die zur Registrierung des Skripts notwendigen Informationen beinhaltet. Der Kontrakt dazu sieht wie folgt aus.

public interface IScriptRegistrationParameters
{
    Page Page { get; set; }
    Type Type { get; set; }
    string Key { get; set; }
    string Url { get; set; }
    bool Localizable { get; set; }
}

In dem Sharepoint Projekt wird nun die konkrete Implementierung SharepointScriptRegistrar mit der Klasse ScriptLink hinzugefügt.

public class SharepointScriptRegistrar : IScriptRegistrar
{
    public void RegisterScript(IScriptRegistrationParameters registrationParameters)
    {
        ScriptLink.Register(
        registrationParameters.Page, 
        registrationParameters.Url, 
        registrationParameters.Localizable);
    }
}

Das Webprojekt dagegen erhält eine weitere Klasse WebScriptRegistrar, die das Skript mit Hilfe des ScriptManagers registriert.

public class WebScriptRegistrar : IScriptRegistrar
{
    public void RegisterScript(IScriptRegistrationParameters registrationParameters)
    {
        var scriptManager = registrationParameters.Page.ClientScript;
        scriptManager.RegisterClientScriptInclude(
        registrationParameters.Type,
        registrationParameters.Key,
        registrationParameters.Url);
    }
}

Der Aufruf des jeweiligen Registrars erfolgt kontextabhängig durch einen IoC Container. So halte ich das Wissen über die Implementierung aus dem WebPart raus und die Registrierung erfolgt nur in der Konfiguration des Containers. Als IoC Tool nutze ich in diesem Fall StructureMap.

So beschreibt der folgende Ein-Zeiler die Konfiguration innerhalb des Sharepoint Projekts.

For<IScriptRegistrar>().Use<SharepointScriptRegistrar>();

Die Registrierung für das Web Projekt sieht dem entsprechend angepaßt aus.

For<IScriptRegistrar>().Use<WebScriptRegistrar>();

Mit Hilfe eines ServiceLocators wird dann der registrierte IScriptRegistrar aus dem Container geholt und die Skriptregistrierung mit dem Aufruf RegisterScript ausgeführt.

var scriptRegistrar = ServiceLocator.Get<IScriptRegistrar>();
IScriptRegistrationParameters scriptRegistrationParameters = new ScriptRegistrationParameters
{
    Page = this.Page,
    Type = this.GetType(),
    Key = "javascript",
    Url = "necrtt/jsgantt.js",
    Localizable = false
};
scriptRegistrar.RegisterScript(scriptRegistrationParameters);

Falls es noch andere Ideen gibt, wie dieses Szenario auch umgesetzt werden könnte, bin ich immer daran interessiert…

Kick It on dotnet-kicks.de