3

Je suis dans une situation où nous avons besoin de modifier ce qui est renvoyé à partir du référentiel statique dans une application open source tierce (NopCommerce). Le problème est qu'ils utilisent des dépôts statiques, donc je ne peux pas simplement hériter d'une interface et DI mon propre dépôt. J'essaye de faire ceci sans modifier le code-base de NopCommerce ... de nouvelles idées? Editer: Je veux que NopCommerce utilise mes repos, plutôt que d'utiliser mon code.Référentiel statique ... ne peut pas utiliser DI, que faire?

+0

encapsuler à l'aide de classe (s) wrapper (s)? – Tahbaza

+0

Ensuite, je n'aurais pas à modifier le code NopCommerce pour utiliser les classes wrapper à la place? –

+0

@ jbarker7: non, vous ne le feriez pas. Anna Lear et Goblin (en utilisant une terminologie différente) suggèrent la création de votre propre bibliothèque de classes wrapper autour des statiques que vous ne pouvez pas modifier; vous devez sélectionner l'une des deux réponses comme correcte. – Tahbaza

Répondre

3

Nous sommes actuellement dans un délai très, très serré, et ce problème n'était pas prévu. Donc, je pense d'abord à partir de l'interface statique d'un homme pauvre/DI de pauvre comme le suivant (donc je ne dois pas modifier toute la solution). Puis plus tard, quand nous sommes pas si pressés par le temps, passer à utiliser une injection d'interface et de la dépendance et de soumettre un patch à NopCommerce:

// Poor-man's static interface (DI). 
public static class OriginalBuiltInStaticClass { 
    private static IMyNewClass _myNewClass; 

    public static void Inject(IMyNewClass myNewClass) { 
     _myNewClass = myNewClass; 
     A = _myNewClass.A; 
     B = _myNewClass.B; 
     C = _myNewClass.C; 
    } 

    public static Action A = CopySimpleRenameBuiltInStaticClass.A; 
    public static Func<int, string> B = CopySimpleRenameBuiltInStaticClass.B; 
    public static Action C = CopySimpleRenameBuiltInStaticClass.C; 
} 

// Original vendor class which was copied and renamed. 
public static class CopySimpleRenameBuiltInStaticClass { 
    public static void A() { 
     Console.WriteLine("OriginalBuiltInStaticClass.A()"); 
    } 

    public static string B(int id) { 
     Console.WriteLine("OriginalBuiltInStaticClass.B()"); 
     return id.ToString(); 
    } 

    public static void C() { 
     Console.WriteLine("OriginalBuiltInStaticClass.C()"); 
    } 
} 

// Creating an interface to merge into trunk of NopCommerce (convert static repositories) 
public interface IMyNewClass { 
    void A(); 
    string B(int id); 
    void C(); 
} 

// Implementation of interface. 
public class MyNewClass : IMyNewClass { 
    public void A() { 
     Console.WriteLine("MyNewClass.A()"); 
    } 

    public string B(int id) { 
     Console.WriteLine("MyNewClass.B()"); 
     return id.ToString(); 
    } 

    public void C() { 
     CopySimpleRenameBuiltInStaticClass.C(); 
    } 

} 

Toute pensée?

+0

Cela a fonctionné parfaitement ... J'ai créé un modèle T4 et généré automatiquement l'interface, le wrapper et la classe d'implémentation. Maintenant, je place juste: NopRepo.Inject (new MyExtClass.MyNopRepo()); dans Global.asax dans Application_Start et al ... DI pour les classes statiques. –

+0

Pour ceux qui sont intéressés par le template T4 et les mises à jour de ce code: http://joshbarker.net/?p=33 –

3

Vous pouvez abstraire leur substance en créant une interface de votre choix et une implémentation de classe qui délègue à NopCommerce. Ensuite, demandez à votre code d'utiliser l'interface au lieu d'accéder directement aux classes de NopCommerce. Vous pouvez modifier la sortie de NopCommerce dans votre classe avant que le résultat ne soit renvoyé à votre application.

Et comme bonus supplémentaire, vous pouvez également vous moquer de l'interface pour effectuer des tests qui ne nécessitent pas les implémentations de référentiel à part entière.

Quelque chose comme ça, dans le code:

public interface IRepository 
{ 
    MyItem GetItem(int id); 
} 

public class MyNopCommerceWrapper : IRepository 
{ 
    public MyItem GetItem(int id) 
    { 
     // I have no idea what NopCommerce API looks like, so I made this up. 
     var myItem = NopCommerce.GetItem(id); 

     ModifyMyItem(myItem); 

     return myItem; 
    } 
} 
+0

Je suppose que j'essaie de comprendre ce que vous dites ici. Essentiellement, nous devons modifier le fonctionnement de NopCommerce et ce qui est retourné à NopCommerce. Il n'y a pas d'autre application. J'ai simplement besoin de modifier le dépôt comme si je pouvais DI mon propre ou comme s'il était marqué comme virtuel et je pourrais le remplacer. –

+0

On dirait que cela fonctionnerait, mais je devrais encore modifier NopCommerce pour utiliser ce wrapper au lieu d'utiliser le référentiel statique, non? –

+0

Non. Votre application ne saura rien de la bibliothèque NopCommerce. Il sera enveloppé par votre classe wrapper et votre application n'appellera que la méthode wrapper. Seul le wrapper dépend de NopCommerce. Votre application sera en mesure d'utiliser DI en injectant une enveloppe. Il n'y a aucune raison de modifier la base de code de NopCommerce - il n'a pas besoin de connaître le wrapper. –