Importer une Feuille Excel et de Valider les Données Importées avec un couplage Lâche

Je suis en train de développer un module qui permettra de lire les feuilles de calcul excel (éventuellement à partir d'autres sources de données trop, de sorte qu'il devrait être faiblement couplés) et de les convertir dans d'autres Entités afin d'économiser.

La logique sera présent:

  1. La feuille excel peut être dans un format différent, par exemple les noms de colonne dans la feuille Excel peuvent être différents de mon système doit être en mesure de cartographier les différents champs de mes entités.
  2. Pour l'instant je vais être en supposant que le format défini ci-dessus sera même et codé en dur pour l'instant, au lieu de partir de la base de données dynamiquement après l'ensemble sur un mappage de configuration de l'INTERFACE utilisateur genre de chose.
  3. Les données doivent être validées avant même d'être substitués. Je devrais donc être en mesure de les valider à l'avance contre quelque chose. Nous ne sommes pas en utilisant comme XSD ou autre chose, alors je dois les valider par rapport à la structure de l'objet, je suis en utilisant comme modèle pour l'importation.

Le problème c'est que j'ai mis en place certaines choses ensemble, mais je ne dis pas que j'ai aimé ce que j'ai fait. Ma Question est comment je peux améliorer le code ci-dessous et rendre les choses plus modulaire et résoudre les problèmes de validation.

Le code ci-dessous est un mock-up, et n'est pas censé travailler, juste pour voir la structure de la conception.

C'est le code que j'ai trouvé jusqu'à présent, et j'ai réalisé une chose que je dois améliorer ma conception de modèles de compétences, mais pour l'instant j'ai besoin de votre aide, si vous pouviez m'aider:

//The Controller, a placeholder
class UploadController
{
    //Somewhere here we call appropriate class and methods in order to convert
    //excel sheet to dataset
}

Après nous fichier téléchargé à l'aide d'un Contrôleur MVC, il pourrait y avoir différents contrôleurs spécialisés à l'importation de certains comportements, dans cet exemple, je vais le téléchargement de personne de tables liées,

interface IDataImporter
{
    void Import(DataSet dataset);
}

//On peut utiliser de nombreux autres importateurs d'ailleurs PersonImporter
classe PersonImporter : IDataImporter
{
//On divise l'ensemble de données approprate tableaux de données et d'appeler tous les IImportActions
//liées à la Personne de l'importation de données
//Nous appelons l'insertion de fonctions de base de données d'ici le DataContext depuis cette manière
//on peut faire moins de db aller-retour.

public string PersonTableName {get;set;}
public string DemographicsTableName {get;set;}

public Import(Dataset dataset)
{
    CreatePerson();
    CreateDemograhics();
}

//We put different things in different methods to clear the field. High cohesion.
private void CreatePerson(DataSet dataset)
{   
    var personDataTable = GetDataTable(dataset,PersonTableName);
    IImportAction addOrUpdatePerson = new AddOrUpdatePerson();
    addOrUpdatePerson.MapEntity(personDataTable);
}

private void CreateDemograhics(DataSet dataset)
{
    var demographicsDataTable = GetDataTable(dataset,DemographicsTableName);
    IImportAction demoAction = new AddOrUpdateDemographic(demographicsDataTable);
    demoAction.MapEntity();
}

private DataTable GetDataTable(DataSet dataset, string tableName)
{
    return dataset.Tables[tableName];
}

}

J'ai IDataImporter et spécialisés de la classe de béton PersonImporter. Cependant, je ne suis pas sûr que ça semble bon jusqu'ici puisque les choses devraient être SOLIDE donc, fondamentalement, facile à étendre plus tard dans le cycle du projet, ce sera une base pour de futures améliorations, permet de continuer:

IImportActions sont où la magie se produit principalement. Au lieu de concevoir les choses de la table de base, je suis le développement de ce comportement en fonction de sorte qu'on peut appeler l'un d'eux à l'importation de choses en plus de modèle modulaire. Par exemple, une table peut avoir 2 actions différentes.

interface IImportAction
{
void MapEntity(DataTable table);
}
//A sample import action, AddOrUpdatePerson
class AddOrUpdatePerson : IImportAction
{
//Consider using default values as well?
public string FirstName {get;set;}
public string LastName {get;set;}
public string EmployeeId {get;set;}
public string Email {get;set;}
public void MapEntity(DataTable table)
{
//Each action is producing its own data context since they use
//different actions.
using(var dataContext = new DataContext())
{
foreach(DataRow row in table.Rows)
{
if(!emailValidate(row[Email]))
{
LoggingService.LogWarning(emailValidate.ValidationMessage);
}
var person = new Person(){
FirstName = row[FirstName],
LastName = row[LastName],
EmployeeId = row[EmployeeId],
Email = row[Email]
};
dataContext.SaveObject(person);
}
dataContext.SaveChangesToDatabase();
}
}   
}
class AddOrUpdateDemographic: IImportAction
{
static string Name {get;set;}
static string EmployeeId {get;set;}
//So here for example, we will need to save dataContext first before passing it in 
//to get the PersonId from Person (we're assuming that we need PersonId for Demograhics)    
public void MapEntity(DataTable table)
{
using(var dataContext = new DataCOntext())
{
foreach(DataRow row in table.Rows)
{
var demograhic = new Demographic(){
Name = row[Name],
PersonId = dataContext.People.First(t => t.EmployeeId = int.Parse(row["EmpId"]))
};
dataContext.SaveObject(person);
}
dataContext.SaveChangesToDatabase();
}
}
}

Et de la validation, qui la plupart du temps où je suce à malheureusement. La validation doit être facile à étendre et faiblement couplés et aussi j'ai besoin d'être en mesure d'appeler cette validation à l'avance au lieu d'ajouter de tout.

public static class ValidationFactory
{
public static Lazy<IFieldValidation> PhoneValidation = new Lazy<IFieldValidation>(()=>new PhoneNumberValidation());
public static Lazy<IFieldValidation> EmailValidation = new Lazy<IFieldValidation>(()=>new EmailValidation());
//etc.
}
interface IFieldValidation
{
string ValidationMesage{get;set;}
bool Validate(object value);
}
class PhoneNumberValidation : IFieldValidation
{
public string ValidationMesage{get;set;}
public bool Validate(object value)
{   
var validated = true; //lets say...
var innerValue = (string) value;
//validate innerValue using Regex or something
//if validation fails, then set ValidationMessage propert for logging.
return validated;
}
}
class EmailValidation : IFieldValidation
{
public string ValidationMesage{get;set;}
public bool Validate(object value)
{   
var validated = true; //lets say...
var innerValue = (string) value;
//validate innerValue using Regex or something
//if validation fails, then set ValidationMessage propert for logging.
return validated;
}
}
InformationsquelleAutor Tarik | 2013-07-24