2010-07-29 7 views
6

J'essaye de développer un cadre pour plusieurs applications que nous développons ici et l'une des classes de framework que j'essaye de construire est pour créer une base de données. Idéalement, j'aurais une méthode où je pourrais passer les deux méthodes suivantes: CreateDatabaseTables() et ResetDatabaseValues ​​(); Par exemple, je pourrais avoir trois applications que j'appellerai Application1, Application2 et Application3; chacune de ces applications aurait un schéma de base de données différent que j'incorporerais dans le code (par exemple, CreateDatabaseTables a un tas de commandes "Create Table"). Je veux créer une seule méthode de base de données qui peut être utilisé par chacun d'entre eux de sorte qu'il ressemblerait à quelque chose comme:Passer plusieurs méthodes (déléguer?)

Application1

BuildLocalDatabase(CreateTablesForApp1(),ResetDatabaseValuesforApp1()) 

Application2

BuildLocalDatabase(CreateTablesForApp2(),ResetDatabaseValuesforApp2()) 

demande3

BuildLocalDatabase(CreateTablesForApp3(),ResetDatabaseValuesforApp3()) 

La méthode BuildLocalDatabase ferait quelque chose comme:

publid bool BuildLocalDatabase(CreateTablesForApp(),ResetDatabaseValuesforApp()) 
{ 
    - see if database file exists; if it does, delete it 
    - create a new database file 
    - call CreateTablesForApp 
    - if the tables were created successfully, call ResetDatabaseValuesForApp 
} 

Toutes les pensées sur comment j'irais capable de faire cela. Il y a un tas de choses de validation et d'autres choses que je voudrais faire dans la fonction BuildLocalDatabase et évidemment mon but ici est de minimiser la quantité de code de duplication dans chaque application ... des suggestions sur la façon de procéder. Je pense en C++, je pourrais avoir juste passé les méthodes CreateTablesForApp et ResetDatabaseValuesForApp en tant que points de fonction, mais il ne semble pas y avoir un moyen de faire cela en C#. Et les délégués semblent bien le gérer car je ne suis vraiment limité qu'à une seule méthode (et la multidiffusion semble vouloir exécuter les méthodes deux fois).

+1

Vous voudrez peut-être envisager de formater le code dans votre question, afin que les gens puissent le lire plus facilement. –

Répondre

4

Vous voulez utiliser des délégués:

public bool BuildLocalDatabase(Func<Database, bool> createTables, Action<Database> resetValues) 
{ 
    // Do initialization 
    if (createTables(db)) 
    { 
      resetValues(db); 
    } 
} 

Vous aurait ensuite appeler cela comme: paramètre

BuildLocalDatabase((db) => CreateTablesForApp1(), (db) => ResetDatabaseValuesforApp1()); 

(je mets dans une « base de données » dans le cas où vous en avez besoin - si vous ne pouvez pas, vous pouvez simplement utiliser Func<bool> et Action, sans ce paramètre, et juste passer le nom de la méthode directement à la place de lambdas.En général, les méthodes comme ceci ont besoin d'une forme de paramètre, comme une connexion DB, etc, si- mettez-le dedans.)

+0

Reed, Merci pour votre réponse - c'était parfait. Cependant, en pensant à cela, je me demandais si vous aborderiez le problème de cette façon ou différemment (puisque vous avez répondu à ma question initiale "spot on", je vais faire l'hypothèse que vous savez ce que je suis essayer de faire). Donc, pensez-vous que je devrais utiliser l'approche "Func" que vous avez décrite ou créer une classe de base de données "base" que je pourrais "dériver" une nouvelle classe pour chaque application. Cette classe "dérivée" aurait le code "spécifique à l'application" ... Merci encore ... – user405965

+0

@ ed92620: Cela dépend vraiment. Utiliser une classe (ou une interface!) Pour cela à la place de 2 délégués peut être plus approprié, mais ce n'est pas forcément le cas. Il est difficile de savoir ce qu'il y a de mieux sans des informations beaucoup plus détaillées et un bon sens de votre projet. Personnellement, si la quantité de code est petite, j'aime les délégués - si c'est globalement, l'utilisation d'une classe est probablement meilleure, si pour aucune autre raison, c'est beaucoup plus testable. –

1

Eh bien, fondamentalement, vous pouvez. Si la question est sur le délégué Syntac, vous devez perdre quelques () et définir un délégué:

public delegate void MyDelegate(); 

publid bool BuildLocalDatabase(MyDelegate CreateTablesForApp, MyDelegate ResetDatabaseValuesforApp) 
{ 
    CreateTablesForApp(); 
    ... 
    ResetDatabaseValuesforApp(); 
} 

et l'appeler comme:

BuildLocalDatabase(CreateTablesForApp1,ResetDatabaseValuesforApp1); 
+2

Pour un délégué vide comme celui-ci ne devriez-vous pas simplement utiliser le délégué intégré 'Action'? –

+0

@Gordon: Oui, mais je décide de montrer la syntaxe complète impliquée. –

+1

Je préfère la syntaxe de délégué complet dans la plupart des cas - un délégué correctement nommé indique au programmeur quelque chose sur ce que le délégué est pour et comment il devrait être mis en œuvre. Une simple "Action" n'a pas cette description - vous finissez par le laisser au nom de l'instance pour décrire cela aussi - mais l'instance devrait se décrire elle-même. –

Questions connexes