Posts
154
Comments
233
Trackbacks
6
venerdì 2 dicembre 2011
Eseguire un assembly in un AppDomain separato

 Nello sviluppo di architetture a plugin può diventare necessario eseguire assembly in un AppDomain separato, magari recuperando gli assembly (con relative dipedenze) da una sottocartella.
In rete si trovano tantissimi esempi, che usano metodi recenti o datati e che sfruttano varie tecniche. Sono però riuscito ad arrivare ad una soluzione che mi soddisfacesse, solo dopo molti tentativi e molte ricerche e quindi mi sembra giusto condividere i risultati della mia ricerca sperando che possano facilitare la vita a qualcuno.

Prima di andare avanti vorrei però esplicitare le mie necessità:

- Eseguire i metodi di una o più classi contenute all’interno di un assembly, in un AppDomain separato;
- Poter caricare nell’AppDomain assembly con reference ad altri assembly “locali” o memorizzati nella GAC; 
- Memorizzare l’assembly (con tutte le sue dipendenze) in una sotto directory;
- Poter passare parametri al costruttore delle classi da creare.
 
La funzione seguente, seppur molto semplice, soddisfa tutte le mie necessità:

   1: Public Sub ExecuteOnAppDomain(ByVal typeName As String, ByVal assemblyName As String)
   2:     Dim domainSetup As AppDomainSetup = New AppDomainSetup
   3:     domainSetup.ApplicationBase = Environment.CurrentDirectory
   4:     domainSetup.PrivateBinPath = "RELATIVE_FOLDER"
   5:     ' Copia delle policy dall'appdomain corrente
   6:     Dim adevidence As Evidence = AppDomain.CurrentDomain.Evidence
   7:     ' Creazione nuovo appdomain
   8:     Dim domain As AppDomain = AppDomain.CreateDomain("SomeAppDomain", adevidence, domainSetup)
   9:  
  10:     ' Argomenti costruttore
  11:     Dim constructorArgs As New List(Of Object)
  12:     constructorArgs.Add("PARAM1")
  13:     ' ....
  14:     ' ....
  15:     constructorArgs.Add(10)
  16:     ' Bindings
  17:     Dim bindings = BindingFlags.CreateInstance Or BindingFlags.Instance Or BindingFlags.Public
  18:     ' Creazione della classe dato il nome completo e l'assembly di riferimento
  19:     Dim obj = domain.CreateInstanceAndUnwrap(assemblyName, typeName, False, bindings, Nothing,
  20:                                              constructorArgs.ToArray, Nothing, Nothing, Nothing)
  21:     obj.DoWork()
  22:     ' Unload dell'appdomain
  23:     AppDomain.Unload(domain)
  24:   End Sub


Alcune note:

- Nella proprietà PrivateBinPath dell’AppDomainSetup è possibile specificare le sottodirectory da utilizzare per il probing degli assembly;
- I parametri del costruttore devono essere specificati nello stesso ordine e devono avere lo stesso tipo di quelli presenti nel costruttore della classe da istanziare;
- L’assembly name non deve contenere il suffisso “.dll” ma solo il nome dell’assembly;
- Il typeName deve contenere il nome completo del tipo della classe da istanziare;
- Tutti gli assembly referenziati devono essere inseriti nelle sottodirectory o nella directory principale del nostro applicativo (o nella GAC);
- La risoluzione delle dipendenze viene fatta in automatico senza dover implementare nessun meccanismo manuale di risoluzione.

posted @ venerdì 2 dicembre 2011 11.16 | Feedback (0)
venerdì 14 ottobre 2011
Publish da linea di comando di un web project ASP.NET

 A volte quando si hanno molti progetti ASP.NET o quando sono necessarie delle azioni aggiuntive da fare dopo la pubblicazione di un’applicazione ASP.NET diventa molto comodo poter pubblicare un web project ASP.NET da linea di comando.

Utilizzando msbuild è possibile ottenere la stessa cosa che si otterrebbe facendo il publish da Visual Studio. L’esempio seguente utilizza msbuild del Framework 4.0 ed è quindi equivalente al Publish fatto da Visual Studio 2010 (indipendentemente se poi si utilizzi il Framework 4.0 o meno nel web project):

msbuild.exe" /t:Rebuild /p:OutDir=DEST_PATH\bin\;WebProjectOutputDir=DEST_PATH\;Configuration=Release;
UseWPP_CopyWebApplication=True; PipelineDependsOnBuild=False "PROJECT_SOURCE_PATH\joshProtocolWebAdmin.vbproj"

L’effetto del comando precedente è:

  1. Compilare le .DLL del progetto web nel path DEST_PATH\bin\
  2. Pubblicare il contenuto del progetto web (pagine ASPX, immagini, CSS, etc, etc) nel path DEST_PATH
  3. Compilare il progetto in Release applicando pre e post build events
  4. Applicare le web.config transformations se presenti

Unica nota: se avete dei path con degli spazi utilizzare i doppi apici classici, ma sostituire gli slash (‘\’) che normalmente si utilizzerebbero con i backslash (‘/’).

posted @ venerdì 14 ottobre 2011 15.33 | Feedback (0)
martedì 6 settembre 2011
Tip: disabilitare il tab design durante l’editing dello XAML

Eccomi di ritorno qui sul blog dopo una lunga assenza con quello che spero sia un utile tip.
In questo periodo sto lavorando molto con Silverlight e quindi con l’editor dei file XAML e sono stato anche io falcidiato da rallentamenti, errori, crash di Visual Studio 2010, insomma da situazioni “poco piacevoli”.

La prima ottimizzazione, per chi come me lavora direttamente sullo XAML, è quella di aprire i file XAML in Visual Studio direttamente nella view del codice. Questo post spiega come abilitare l’opzione.

Anche facendo così si possono “sperimentare” tutti i problemi sopra indicati in quando il tab Design rimane comunque abilitato e in quanto “qualcosa” viene comunque fatto in sottofondo.

Per ovviare anche a questo problema è possibile aprire i file XAML direttamente con il source editor al posto dell’editor standard. Per fare questo:

1) Selezionare un file XAML qualsiasi
2) Tasto destro e selezionare dal menu “Open with”
3) A questo punto selezionare “Source code editor” e settarlo come editor di default

Se non avete bisogno di nessun designer ed editate lo XAML credo che sia la soluzione migliore e la più semplice per lavorare in modo decente.

P.S. L’intellisense continua comunque a funzionare

posted @ martedì 6 settembre 2011 12.06 | Feedback (0)
martedì 12 luglio 2011
Silverlight: Errore “Invalid or malformed application: Check manifest”

Se come nel mio caso ogni volta che create un nuovo progetto Silverlight avete puntualmente questo messaggio di errore, la soluzione è abbastanza semplice: controllate che lo Startup Object del progetto Visual Studio punti ancora ad un oggetto esistente.

Nel mio caso puntualmente modifico i namespace e puntualmente mi dimentico di andare ad aggiornare lo Startup Object che punta al vecchio namespace.

posted @ martedì 12 luglio 2011 14.39 | Feedback (0)
giovedì 10 marzo 2011
Rilasciato NHibernate 3.1.0

La giornata inizia bene! Ho appena appreso che è stata rilasciata la versione 3.1.0 di NHibernate. Qui il link al download, mentre a questo indirizzo potete trovare la release note con le modifiche introdotte.

posted @ giovedì 10 marzo 2011 8.52 | Feedback (0)
martedì 22 febbraio 2011
NHibernate: utilizzare lo 0 per rappresentare l’assenza di entità


Quando si ha a che fare con database legacy, potrebbe saltar fuori la necessità di non inserire nel database valori nulli per le relazioni many-to-one nulle, ma bensì il valore zero.

Questo post su NHForge, discute la problematica e definisce una soluzione. Per chi avesse bisogno della versione in VB.NET ecco il codice convertito:

   1: Public Class NullableTuplizer
   2:     Inherits PocoEntityTuplizer
   3:  
   4:     Sub New(ByVal entityMetamodel As EntityMetamodel, ByVal mappedEntity As PersistentClass)
   5:         MyBase.New(entityMetamodel, mappedEntity)
   6:     End Sub
   7:  
   8:     Public Overrides Function GetPropertyValuesToInsert(ByVal entity As Object, ByVal mergeMap As IDictionary,
   9:                             ByVal session As NHibernate.Engine.ISessionImplementor) As Object()
  10:         Dim values() As Object = MyBase.GetPropertyValuesToInsert(entity, mergeMap, session)
  11:         ' Dirty hack 1
  12:         For i As Integer = 0 To values.Length - 1
  13:             If (values(i) Is Nothing AndAlso GetType(IEntity).IsAssignableFrom(getters(i).ReturnType)) Then
  14:                 values(i) = ProxyFactory.GetProxy(0, Nothing)
  15:             End If
  16:         Next
  17:         Return values
  18:     End Function
  19:  
  20:     Public Overrides Function GetPropertyValues(ByVal entity As Object) As Object()
  21:         Dim values() As Object = MyBase.GetPropertyValues(entity)
  22:         ' Dirty hack 2
  23:         For i As Integer = 0 To values.Length - 1
  24:             If (values(i) Is Nothing AndAlso GetType(IEntity).IsAssignableFrom(getters(i).ReturnType)) Then
  25:                 values(i) = ProxyFactory.GetProxy(0, Nothing)
  26:             End If
  27:         Next
  28:         Return values
  29:     End Function
  30:  
  31:     Public Overrides Sub SetPropertyValues(ByVal entity As Object, ByVal values() As Object)
  32:         ' Dirty hack 3
  33:         For i As Integer = 0 To values.Length - 1
  34:             If GetType(IEntity).IsAssignableFrom(getters(i).ReturnType) Then
  35:                 Try
  36:                     ' Provo ad accedere alla proprietà id
  37:                     If CType(values(i), IEntity).ID = 0 Then
  38:                         values(i) = Nothing
  39:                     End If
  40:                 Catch ex As Exception
  41:                     ' Errore. Il proxy ha restituito un errore
  42:                     values(i) = Nothing
  43:                 End Try
  44:             End If
  45:         Next
  46:         MyBase.SetPropertyValues(entity, values)
  47:     End Sub
  48:  
  49: End Class

Due note: l’interfaccia IEntity è un’interfaccia base implementata dalle mie entità. Nel mio caso definisce solo la proprietà ID, ma potrebbe anche essere completamente vuota o avere altre proprietà comuni.

La funzione SetPropertyValues è invece leggermente diversa da quella proposta sul post linkato in precedenza. In particolar modo, nel mio caso quando provavo ad accedere all’ID della mia entità, veniva sempre lanciata un’eccezione in quanto il proxy non riusciva a trovare l’entità con ID 0. Forse è un mio errore e forse la soluzione proposta (il try-catch) non è il massimo della vita, ma al momento la soluzione funziona.

posted @ martedì 22 febbraio 2011 13.52 | Feedback (0)
venerdì 18 febbraio 2011
Alternative a Reflector

La notizia che la Red Gate, nonostante quanto avesse promesso, distribuirà la prossima versione di Reflector (la 7) solo a pagamento, ha destato molto “rumore”.

Non entro nel merito di tale notizia, ne voglio giudicare la decisione della compagnia. Voglio solo linkare questo post in cui vengono presentate due alternative:

  • ILSpy dagli autori di SharpDevelop
  • Un nuovo tool sviluppato dalla JetBrains di prossima pubblicazione

Che dire, ben vengano le alternative! Ho provato ILSpy e devo dire che mi sembra funzionare bene. Unico problema, il fatto che non mi sembri che supporti Visual Basic, ma solo C#.

posted @ venerdì 18 febbraio 2011 16.53 | Feedback (0)
martedì 25 gennaio 2011
Intercettare la fine del download di un file in un’applicazione Web

L’esigenza penso sia piuttosto comune: notificare una pagina web, alla fine del download di un file.
Nel mio caso specifico l’esigenza è quella di far apparire una dialog in un’applicazione Silverlight quando l’utente inizia il download di un file, e nasconderla quando la finestrella di Save del Browser viene visualizzata.

Utilizzando Silverlight, la mia soluzione è un po’ particolare, ma il seguente articolo mostra un’interessante “trucco” per risolvere il problema all’interno di un’applicazione ASP.NET.

http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx

Che dire, proprio un bel trucco!

posted @ martedì 25 gennaio 2011 11.30 | Feedback (0)
mercoledì 5 gennaio 2011
Visual Studio 2010, Framework 3.5 e l’errore di compilazione sui RESX

Oggi è saltata fuori una questione piuttosto interessante: nel caso in cui si utilizzi Visual Studio 2010 targettizzando il Framework 3.5 e si sia obbligati a tergettizzare anche la piattaforma x86, potrebbe saltare fuori un errore di compilazione relativo ai file di risorse RESX delle form.

L’errore è facilmente riproducibile con le seguenti indicazioni:

  • Utilizzare ovviamente Visual Studio 2010
  • Creare un progetto A che utilizzi il Framework 3.5
  • Creare un progetto B di tipo Windows Form e referenziare il progetto A. Anche questo progetto devo utilizzare il Framework 3.5.
  • Nella form che viene creata di default aggiungere una imagelist e inserire qualche immagine
  • Cambiare la piattaforma di compilazione da Any CPU a X86
  • Compilare la soluzione

Fatto tutto ciò non dovreste più essere in grado di compilare. Su Connect esiste un item ben definito con descrizione del problema e soluzioni alternative:

http://connect.microsoft.com/VisualStudio/feedback/details/554759/error-in-control-resx-file-when-adding-imagelist

In particolare una nota sulle soluzioni alternative può dare uno spunto per eventuali fix al problema (uno lo trovate anche in allegato su Connect):

After editing the form search the resx for "j00L" on the first line of the imagelists block and change to "j0yL".
You have to do it everytime you make a change though.

Effettivamente facendo questa semplice modifica tutto torna a compilare correttamente. Il problema è che tale modifica va fatta su ogni form in cui viene inserita una Imagelist.

Il problema descritto non si manifesta con il Framework 4.0 o utilizzando come piattaforma di compilazione Any CPU. Nel nostro caso però non possiamo ne usare il Framework 4.0 ne usare Any CPU a causa di librerie esterne che non vengono più caricate correttamente.
Sfruttando il “trucco” precedente ci siamo fatti un programmino che va a “scandagliare” tutti i file RESX del progetto, verifica se contengono delle imagelist e nel caso va ad applicare il fix precedente.
Richiamando il tutto in fase di Prebuild, si torna a lavorare decentemente direttamente con Visual Studio.

Mi piacerebbe sapere se il recente SP1 Beta di Visual Studio 2010 includa già la correzione a questo problema. Qualcuno ha già verificato?

posted @ mercoledì 5 gennaio 2011 9.37 | Feedback (0)
lunedì 6 dicembre 2010
Rilasciato NHibernate 3.0

Ci siamo! E’ stato ufficialmente rilasciata la versione finale di NHibernate 3.0.
Per scaricarlo il solito link.

posted @ lunedì 6 dicembre 2010 12.10 | Feedback (1)
Silverlight: ottimizzare i data contracts

L’articolo seguente descrive in che modo si possono ottimizzare i data contracts per ottimizzare le performance di comunicazione tra Silverlight e WCF.

http://blog.thekieners.com/2010/05/04/optimize-data-contracts-for-better-wcf-performance/

Prove alla mano nel mio progetto Silverlight le dimensioni dei messaggi si riducono di più del 50%.
Un bel risparmio!

posted @ lunedì 6 dicembre 2010 12.10 | Feedback (0)
lunedì 6 settembre 2010
Amletico dilemma: Silverlight o ASP.NET?

Sfrutto un po’ il mio blog per cercare di risolvere un dilemma nato in questi giorni.
Sono in procinto di iniziare lo sviluppo della nuova versione di un applicativo già esistente. L’applicativo suddetto è realizzato in ASP.NET, gira in intranet, non è strettamente necessario che sia multibrowser (anche se non sarebbe male) e per lo più consente la visualizzazione e l’inserimento di dati, quindi classiche griglie, form più o meno complesse, etc, etc.

Con queste premesse ci siamo chiesti se convenga continuare ad utilizzare ASP.NET o non sia meglio passare a Silverlight.
Uno dei requisiti della nuova versione è quella di avere un’interfaccia grafica più user-friendly.

Voi cosa fareste al posto mio?

posted @ lunedì 6 settembre 2010 9.51 | Feedback (10)
lunedì 23 agosto 2010
NH Day: annullamento iscrizione ?

Causa spostamento matrimonio e del relativo viaggio di nozze, non potrò partecipare al prossimo NH Day (mannaggia alla pupazza!!!).

Devo annullare semplicemente l'iscrizione o è possibile girare il posto a qualcun altro?
Qualcuno mi sa dare informazioni?

posted @ lunedì 23 agosto 2010 11.09 | Feedback (0)
mercoledì 18 agosto 2010
NHibernate 3 Alpha 2

Le ferie sono già un ricordo per me, ma almeno qualche buona notizia c'e'!
Durante questo periodo di inattività è stata rilasciata l'alpha 2 di NHibernate 3.  Qui il link per il download:

http://sourceforge.net/projects/nhibernate/files/

 

posted @ mercoledì 18 agosto 2010 12.55 | Feedback (0)
NHibernate Designer from Mindscape


Pur non essendo un fan sfegatato dei designer devo ammettere che in certi casi possono essere molto utili e soprattutto possono accelerare alcuni progetti.

Apprendo quindi con estrema felicità che è disponibile l’NHibernate Designer sviluppato dalla Mindscape. Non ho avuto modo di provarlo ancora, ma da quello che leggo si integra con Visual Studio 2010, supporta sia il model first sia il database first e ha un costo relativamente basso ($ 249 a sviluppatore).

posted @ mercoledì 18 agosto 2010 12.52 | Feedback (2)
News
Se volete sapere con chi avete a che fare eccomi qui in uno "scatto" lavorativo.
La mia foto

Logo MCAD
Logo MCTS

Visite dal 16/03/2007:

Il mio stato su Messanger: