Création d’une méthode générique Save () pour les modèles

J’ai un système assez simple et, aux fins de cette question, il y a essentiellement trois parties: modèles, référentiels, code d’application.

Les modèles sont au cœur. Prenons un exemple artificiel simple:

public class Person { public ssortingng FirstName { get; set; } public ssortingng LastName { get; set; } } 

Dans ce même projet se trouve une interface de référentiel générique. Au plus simple:

 public interface IRepository { T Save(T model); } 

Les implémentations de cette interface sont dans un projet séparé et injectées avec StructureMap. Pour la simplicité:

 public class PersonRepository : IRepository { public Person Save(Person model) { throw new NotImplementedException("I got to the save method!"); // In the repository methods I would interact with the database, or // potentially with some other service for data persistence. For // now I'm just using LINQ to SQL to a single database, but in the // future there will be more databases, external services, etc. all // abstracted behind here. } } 

Donc, dans le code de l’application, si je voulais enregistrer un modèle, je ferais ceci:

 var rep = IoCFactory.Current.Container.GetInstance<IRepository>(); myPerson = rep.Save(myPerson); 

Assez simple, mais il semble que cela pourrait être beaucoup automatisé. Ce modèle est valable dans tout le code de l’application. Par conséquent, ce que je cherche à faire est de créer une seule et unique Save() générique sur tous les modèles, ce qui constituerait simplement un appel abrégé du code de l’application ci-dessus. De cette façon, il suffirait d’appeler:

 myPerson.Save(); 

Mais je n’arrive pas à trouver un moyen de le faire. Peut-être que c’est d’une simplicité trompeuse et que je ne le regarde pas du bon angle. Au début, j’ai essayé de créer une ISaveableModel vide et ISaveableModel voulais que chaque modèle “pouvant être sauvegardé” l’implémente. Ensuite, pour la seule méthode générique Save() , j’aurais une extension sur l’interface:

 public static void Save(this ISaveableModel model) { var rep = IoCFactory.Current.Container.GetInstance<IRepository>(); model = rep.Save(model); } 

Mais cela me dit que rep.Save(model) a des arguments non valides. Il semble que ce ne soit pas le cas, comme je l’avais espéré. J’ai essayé une approche similaire avec une BaseModel dont les modèles hériteraient:

 public class BaseModel { public void Save() { this = IoCFactory.Current.Container.GetInstance<IRepository>().Save(this); } } 

Mais l’erreur du compilateur est la même. Y a-t-il un moyen de réaliser ce que j’essaie de réaliser? Je suis très flexible sur le design, donc si je m’occupe de quelque chose qui ne va pas sur le plan architectural, j’ai de la place pour prendre du recul et changer la vue d’ensemble.

Une méthode d’extension générique pourrait-elle résoudre ce problème?

 public static T Save(this T current) { var rep = IoCFactory.Current.Container.GetInstance>(); rep.Save(current); } 

Vous pouvez ensuite le contraindre à votre ISaveableModel . Le type de retour ci-dessus n’est pas implémenté, mais vous pouvez le mettre dans un booléen ou un indicateur de statut, peu importe.

Dans les deux approches, le paramètre de la fonction Save() n’est pas de type T Dans le premier, il s’agit de ISaveableModel et dans le second, de BaseModel . Comme le référentiel est un générique basé sur T , la méthode Save attend une variable de type T Vous pouvez append une dissortingbution simple à T avant d’appeler Save pour le réparer.

Alternativement, votre IRepostory peut être changé en

 public interface IRepository { T Save(ISaveableModel model); } 

ce qui a plus de sens.