Un bel post di Ivar Jacobson


Bellissimo (e lunghissimo) post di IJ: In need of a theory for software engineering
Emblematica la frase “Are we working in engineering or in a fashion industry?”

Mi ha fatto venire in mente Andrea nel suo intervento al “Community Tour: UgiDotNet –Windows&Web”. In realtà Andrea ha detto delle cose molto serie nella prima mezz’ora… poi si è contraddetto illustrandoci un case history in cui ha fatto esattamente il contrario! :)

Si è contraddetto volutamente: prima ci ha detto “non dovete fare sempre le cose con l’ultima tecnologia disponibile solo per appagare il vostro ego”. Poi con il progetto ha aggiunto “a meno che i requisiti lo richiedano”.

author: Antonio Santise | posted @ mercoledì 17 febbraio 2010 1.46 | Feedback (5)

LINQ to SQL: “error-prone”?


Per chi si avvicina a LINQ, consiglio di stare attenti alla seguente frase (fonte):

L'esecuzione della query è distinta dalla creazione della query. La creazione della query definisce la query, mentre l'esecuzione viene attivata da un meccanismo diverso. Una query può essere eseguita appena definita (esecuzione immediata) oppure è possibile archiviare la definizione ed eseguire la query in un secondo momento (esecuzione posticipata).

Lo sanno anche i muri, ma fra il sapere e ricordarselo (o accorgersene), ce ne corre :)
Detto questo, cosa ci aspetteremmo dal seguente blocco di codice (vetusto, lo so, ma spero sia chiaro)?
Riformulo meglio la domanda: cosa conterrà il repeater?

var sectionId = 10;
var posts = from a in myDataContext.Articles
where a.SectionId == sectionId
select new Article { Id = a.Id, Title = a.Title };
myRepeater.DataSource = posts;

sectionId = 20;
var title = (from a in myDataContext.Articles
where a.SectionId == sectionId
select a.Title).First();
myLabel.Text = title;

this.DataBind();

La risposta è facile, e ovviamente non si vince nulla :)

Per forzare l’esecuzione immediata, si potrebbe ricorrere ai metodi ToList() o ToArray() o gli n-altri. Ovviamente si perderebbe uno dei maggiori vantaggi di LINQ:

Se la query non contiene un metodo che causa l'esecuzione immediata, l'esecuzione effettiva della query viene posticipata fino a quando non si esegue un'iterazione della variabile di query in un ciclo foreach (ad esempio). L'esecuzione posticipata consente di combinare più query o di estendere una query. Una query estesa viene modificata in modo da includere nuove operazioni. Le modifiche vengono quindi applicate all'eventuale esecuzione.

hth,
a.

Technorati Tag: ,

author: Antonio Santise | posted @ sabato 21 novembre 2009 0.23 | Feedback (2)

IIS 7: autenticazione e configurazione FTP #2


Nel precedente post avevo introdotto (spero) IIS7 e la modalità di autenticazione "embedded", ossia senza far ricorso ad account Windows locali per l'autenticazione. In questo vedremo come configurarne uno. (continua)

author: Antonio Santise | posted @ venerdì 13 novembre 2009 2.02 | Feedback (0)

IIS 7: autenticazione e configurazione FTP #1


Fra le tante novità di IIS7 e suo fratello 7.5, sicuramente quella che ho apprezzato maggiormente è l'integrazione di una nuova modalità di autenticazione: IIS Managar Authentication. (continua)

author: Antonio Santise | posted @ giovedì 12 novembre 2009 19.36 | Feedback (2)

Linux appliances in Visual Studio


Questa decisione è destinata a lasciare il segno, imvho :)

In pratica: Novell rilascia uno “strumento” (riduttivo definirlo tale, lo so) per realizzare applicazioni in ambiente Linux, stand-alone, senza bisogno di setup, tutto già bello e pronto per l’utente finale. Dicasi software appliance, per l’appunto.

SUSE Studio generates appliances as Live CD/DVD, VMware and XEN virtual images, HDD and USB images, and will support Amazon EC2 images soon.

Mono rilascia un plug-in per realizzare questo genere di applicazioni in Visual Studio

The purpose of the plug-in is to allow Windows developers to create Linux appliances containing .NET applications. This is especially helpful for Windows developers who might find it difficult to test their .NET applications on Linux.

Da leggere alla fonte: http://www.infoq.com/news/2009/07/Linux-Appliance-Visual-Studio
Altre info qui: http://www.go-mono.com/monovs/

HTH,
a.

Technorati Tag: ,,

author: Antonio Santise | posted @ giovedì 30 luglio 2009 15.59 | Feedback (0)

[OT] – Il politecnico di Milano


Scusate l’OT, ma questa la devo condividere con i miei compagni di merenda (leggi ex-colleghi) :)

http://nonciclopedia.wikia.com/wiki/Politecnico_di_Milano

La più bella, per chi ha fatto lezione nell N02:

“Questa sedia è asintotica al mio culo!”

author: Antonio Santise | posted @ mercoledì 8 luglio 2009 23.12 | Feedback (1)

log4net – SQLite appender


A volte non è necessario scomodare SQL Server per fare un minimo di tracing/logging. A volte basta il tracing di ASP.NET. A volte vogliamo un file di testo o un file XML. Io ho avuto bisogno di configurare un appender per SQLite.

La documentazione ufficiale di log4net utilizza un appender configurato per un driver abbastanza datato (Finisar.SQLite.SQLiteConnection) che a me non andava.  
Dopo varie vicissitudini, sono riuscito a configurare un appender (funzionante) con un assembly leggermente recente.

<appender name="ADONetAppender" type="log4net.Appender.AdoNetAppender">
<connectionType
   value="System.Data.SQLite.SQLiteConnection, System.Data.SQLite" />
<connectionString value="Data Source=|DataDirectory|Trace.db3" />
<commandText
   value="INSERT INTO Log (Date, Thread, Level, Logger, User, Message)
          VALUES (@date, @thread, @level, @logger, @user, @message)" />
<commandType value="Text"/>
<bufferSize value="100" />
<parameter>
    <parameterName value="@date" />
    <dbType value="DateTime" />
    <layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
    <parameterName value="@thread" />
    <dbType value="String" />
    <size value="255" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern
value="%thread" />
    </layout>
</parameter>
<parameter>
    <parameterName value="@level" />
    <dbType value="String" />
    <size value="50" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%level" />
    </layout>
</parameter>
<parameter>
    <parameterName value="@logger" />
    <dbType value="String" />
    <size value="255" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%logger" />
    </layout>
</parameter>
<parameter>
    <parameterName value="@user" />
    <dbType value="String" />
    <size value="50" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%X{user}" />
    </layout>
</parameter>
<parameter>
    <parameterName value="@message" />
    <dbType value="String" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%m" />
    </layout>
</parameter>
</appender>

HTH,
a.

author: Antonio Santise | posted @ sabato 27 giugno 2009 18.46 | Feedback (0)

log4net – ConversionPattern


Sul fatto che log4net sia potente, non si discute.
Sul fatto che sia leggermente ostico… qualcosina si potrebbe dire.
Io, ad esempio, ho avuto difficoltà a trovare come configurare i layout pattern (quelle stringhe fatte di tanti % e lettere, come “%C %F %L %l %M”). Paradossalmente sono riuscito a trovare prima la versione originaria della documentazione a supporto dei pattern di concatenazione dei messaggi per log4j e finalmente questa per log4net.

Di solito, nei miliardi di esempi di configurazione che circolano per la rete, si trovano dei pattern +/- standard come il seguente: “%date %thread %level %logger %message%newline”.
Dando un’occhiata al link di cui sopra, ci si accorge delle forti customizzazioni che si possono fare sul logging (o tracing, che dir si voglia).

HTH,
a.

author: Antonio Santise | posted @ sabato 27 giugno 2009 18.30 | Feedback (0)

[OT] Quando “sempre online” vuol dire “…quando possibile”


Prendo spunto da un post di Andrea Benedetti e cito anche quello di Andrea Saltarello che, a modo suo, parla di qualità del software per un piccolo sfogo su un disservizio che non dovrebbe esserci, per un sacco di buone ragioni:

  • una banca online deve essere online sempre (sempre, secondo me, vuol dire almeno 9 volte su 10; se capita 2 volte di fila a distanza di qualche giorno che io non possa accedere al mio conto online, personalmente comincio a dubitare della efficienza con la quale vengono amministrati i miei risparmi)
  • mi ripeto: una banca online _non_ può permettersi di andare offline perché i soldi che si spendono in consulenze, outsourcing ecc sono davvero tanti

Veniamo a 2 esempi concreti.
Conosco una nota banca online (esiste solo online) che è sempre giù dalle 23.30 circa in poi (sono arrivato a provare anche alle 2.00 di notte). “Sempre giù” significa che non ti fanno accedere al tuo conto corrente o, nelle migliori delle ipotesi, accedi ma non vedi nulla… qualunque voce di menu risulta attiva ma il dettaglio ti rimanda ad una pagina di errore con un messaggio del tipo “servizio temporaneamente non disponibile”.
“temporaneamente” pensavo volesse dire qualche minuto, qualche ora al massimo… per qualche giorno, magari per attività straordinarie sui sistemi… ma non che ci fossero gli stessi problemi tutte le notti, negli stessi orari… allora mettete sul sito un messaggio del tipo “banca online solo nelle ore diurne”.
Ho contattato il servizio di assistenza, giusto per chiedere (e rompere un po’) e mi è stato detto che ogni notte, “siccome ci sono pochi utenti che usano il conto”, fanno operazioni di backup…

LA (prima) banca online italiana è sempre online, tranne qualche mattina presto (massimo le 10.00), pbmente perché qualche operazione di backup o manutenzione è andata a p...ne non è andata a buon fine e il poverino dell'application management (un help desk evoluto) che si trova in turno di mattina deve risolvere i problemi :) Ne ho visto qualcuno di questi all’opera, e vi assiuro che non è gradevole trovarsi nei paraggi quando il poverino fa query su query per capire cosa sia successo. Specie se tu sei cattolico e a lui piacciono i calendari :s

Due esperienze diverse, usano tecnologie differenti, la seconda banca è nettamente più affidabile della prima, IMHO, ma non per il taglio tecnologico, bensì per la filosofia che ha sempre adottato. Inoltre, in più di 10 anni non ho mai visto un messaggio del tipo “il server IIS o Apache non risponde” o “le operazioni di backup non sono terminate”… o messaggi tecnici di questo tipo.

Per tornare al messaggio di Andrea... all'utente che cavolo gliene frega del "DATA BASE non disponibile"?

author: Antonio Santise | posted @ venerdì 5 giugno 2009 0.14 | Feedback (0)

NHibernate – inverse attribute


Il mapping in file hbm è un’attività che non faccio spesso, ma quando la faccio mi scordo sempre se e come usare l’attributo “inverse” nelle collection.

A futura memoria segnalo questo post  di Brian Chavez che mi sembra più esauriente della documentazione ufficiale di NH.

Suppose you have ParentTable (parentId PK, parentcol1, parentcol2) and ChildTable(childid PK, parentid FK, childcol1, childcol2).  In a one-to-many relationship, you will have one parent and many children.  The ChildTable has a primary key and foreign key.   The foreign key is a reference to the primary key in the ParentTable.  If you look at the ChildTable, you will notice that the ChildTable stores extra information about a row in the ParentTable via the ChildTable's parentId foreign key.  Using this perspective, the "child" owns (knows about) the relationship it has with its parent row.  So, the child will be the owner of the relationship in this one-to-many relationship.

Quindi “the child will be the owner of the relationship in this one-to-many relationship” e di conseguenza, siccome il parent non è l’owner della relazione, è considerato l’inverso (il “target”).

In Hibernate, you might encounter the inverse="true" attribute being used in the definition of a bidirectional relationship. If so, don't worry, because this feature is equivalent to ... the non-owner of the relationship whose table doesn't have the foreign key. Similarly, the Hibernate inverse="false" attribute is equivalent to the ... owner of the relationship whose table has the foreign key.

La cosa più importante è che

[…] a Hibernate mapping with inverse="true" set on the many-to-one side of a bidirectional relationship. If you find such a mapping, you should change it ..., as it is not a best practice in Hibernate and does not generate optimal SQL. For instance, if the many-to-one side is set to inverse="true" then every time you create a child, Hibernate will execute two SQL statements, one to create the child and one to update the child with the foreign key of the parent.

hth

Technorati Tag:

author: Antonio Santise | posted @ lunedì 25 maggio 2009 17.18 | Feedback (0)