Press "Enter" to skip to content

8 – MiniSqlAgent – Definire un entity serializzabile per memorizzare un Job , versione 1.0 dati minimali.

Un post per definire la classe entity che contiene i dati di base per costruire un Job che permetta di eseguire uno statement SQL ad intervalli regolari. Propedeutica allo sviluppo dell’interfaccia di gestione e del servizio Mini SQL Agent.

Il Progetto MiniSqlAgentEntities

Considerato che le entità dati dei Job dovranno essere utilizzate sia dalla Console del servizio, per permettere di generarle e modificarle, sia dal Servizio, per eseguire i Job, è opportuno che siano contenute in un progetto condiviso fra le due applicazioni, inserirle nel progetto del Service Layer sarebbe probabilmente la cosa più semplice da fare, però queste entity potrebbero servire anche ad altro (ad esempio potrebbero essere inviate ad un servizio remoto o ulteriori sviluppi futuri) quindi tenere separato il progetto che contiene le entità dati da tutti gli altri è consigliabile in ogni applicazione. Pertanto abbiamo creato un nuovo Progetto nella Solution MiniSqlAgent che abbiamo chiamato MiniSqlAgentEntities.

minisqlagententities_01

Abbiamo modificato il progetto secondo il pattern usato per tutti i progetti precedenti quindi nome della DLL, Namespace di Default, Icona, Firma dell’assembly e modifica della configurazione di compilazione per produrre un assembly x86.

minisqlagententities_02

la configurazione del progetto della DLL

minisqlagententities_03

La configurazione della compilazione accessibile dal menu di visual studio come qui sotto riportato.

minisqlagententities_04

Ricordatevi che ci possono essere dei problemi di compatibilità fra le librerie x86 e AnyCpu se mescolate. Quindi io preferisco avere tutto compilato in x86 o tutto in AnyCpu. La compilazione x86 è stata imposta solo perché l’edit e continue nel debugger non funziona usando AnyCpu sulle macchine a 64 bit, e visto che stiamo costruendo applicazioni è bello poterlo usare. Al termine, l’applicazione da installare potrà essere senza problemi compilata in modalità AnyCpu.

La classe MiniSqlAgentJob

[XmlRoot(ElementName = "MSAJOB", Namespace = "http://www.dotnetwork.it")]
public class MiniSqlAgentJob : IEntity, INotifyPropertyChanged
{

La dichiarazione della nostra classe, abbiamo indicato i parametri necessari alla serializzazione usando XML, in questo caso XML e non JSON perché l’XML è molto più facile poterlo modificare con un editor di testo, per il lavoro che dobbiamo fare avere dati leggibili è più importante che avere dati compatti.

[XmlIgnore]
public string JobFileName
{
	get
	{
		return mJobFileName;
	}
	set
	{
		mJobFileName = value;
		OnPropertyChanged(FLD_JobFileName);
		OnPropertyChanged(FLD_IsValid);
	}
}

[XmlElement(ElementName = "JobDescription")]
public string Description
{
	get
	{
		return mDescription;
	}
	set
	{
		mDescription = value;
		OnPropertyChanged(FLD_Description);
		OnPropertyChanged(FLD_IsValid);
	}
}

[XmlElement(ElementName = "SqlScript")]
public string SqlScript
{
	get
	{
		return mSqlScript;
	}
	set
	{
		mSqlScript = value;
		OnPropertyChanged(FLD_SqlScript);
		OnPropertyChanged(FLD_IsValid);
	}
}

[XmlElement(ElementName = "ExecutionTime")]
public DateTime NextExecutionTime
{
	get
	{
		return mNextExecutionTime;
	}
	set
	{
		mNextExecutionTime = value;
		OnPropertyChanged(FLD_NextExecutionTime);
		OnPropertyChanged(FLD_IsValid);
	}
}

[XmlElement(ElementName = "ExecutionInterval")]
public int ExecutionInterval
{
	get
	{
		return mExecutionInterval;
	}
	set
	{
		mExecutionInterval = value;
		OnPropertyChanged(FLD_ExecutionInterval);
		OnPropertyChanged(FLD_IsValid);
	}
}

[XmlElement(ElementName = "ConnectionID")]
public string ConnectionID
{
	get
	{
		return mConnectionID;
	}
	set
	{
		mConnectionID = value;
		OnPropertyChanged(FLD_ConnectionID);
		OnPropertyChanged(FLD_IsValid);
	}
}

Abbiamo omesso la dichiarazione delle costanti e delle member variables relative agli elementi che rappresentano i dati del Job, abbiamo indicato per ciascuna property l’ElementName per XML in modo tale che se in seguito avessimo la necessità di modificare i nomi delle property, la compatibilità con i file XML già emessi rimarrebbe garantita conservando l’element name originale.

public bool IsValid
{
	get
	{
		return (!this.SqlScript.XDwIsNullOrTrimEmpty()
			&& !this.ConnectionID.XDwIsNullOrTrimEmpty()
			&& ExecutionInterval > 0
			&& !JobFileName.XDwIsNullOrTrimEmpty());
	}
}

La property IsValid, in cui abbiamo indicato le regole di business che rendono valido un Job, valido non vuol dire sintatticamente corretto, per la correttezza sintattica serviranno altri mezzi ma si tratta di cose che potremo sviluppare in seguito come opzioni avanzate per il nostro servizio.

public static MiniSqlAgentJob ReadXml(string xml, bool isXmlData)
{
	MiniSqlAgentJob ret = null;
	try
	{
		if (!isXmlData)
		{
			ret = (MiniSqlAgentJob)XmlHelper.DeserializeFromFile(typeof(MiniSqlAgentJob), xml);
		}
		else
		{
			ret = (MiniSqlAgentJob)XmlHelper.DeserializeFromString(typeof(MiniSqlAgentJob), xml);
		}
	}
	catch (Exception ex)
	{
		EventLogger.SendMsg(ex);
		throw;
	}
	return (ret);
}

public void WriteXml(string xmlPath, bool indentOutput = true, string newlineCharsOutput = "\r\n")
{
	try
	{
		XmlHelper.SerializeToFile(xmlPath, this
			, typeof(MiniSqlAgentJob)
			, noNamespaces: true
			, indent: indentOutput
			, newlineChars: newlineCharsOutput);
	}
	catch (Exception ex)
	{
		EventLogger.SendMsg(ex);
		throw;
	}
}

public string WriteXml(bool indentOutput = true, string newlineCharsOutput = "\r\n")
{
	try
	{
		return (XmlHelper.SerializeToString(this
			, noNamespaces: true
			, indent: indentOutput
			, newlineChars: newlineCharsOutput));
	}
	catch (Exception ex)
	{
		EventLogger.SendMsg(ex);
		throw;
	}
}

Le funzioni di serializzazione e deserializzazione della classe in XML.

La nostra classe Entity è pronta, nel prossimo post della serie creeremo la User interface per generare un Job e ne testeremo la funzionalità. Nel prossimo post anche il link per lo scaricamento del codice esempio relativo a questo post.