2010-10-05 8 views
4

Je développe actuellement une application dans laquelle j'utilise un système de plugin. Pour fournir un accès unifié à un écran de configuration j'ai ajouté une classe de paramètres à chaque plugin qui doit implémenter une interface de paramétrage. De plus, chaque classe doit mettre en œuvre les paramètres du modèle singleton comme indiqué ci-dessous:C# - est-il possible d'implémenter le modèle singleton en utilisant une interface?

public sealed class PluginSettings : IPluginSettings 
{ 

    private static readonly PluginSettings instance = new PluginSettings(); 
    private PluginSettings() { } 

    public static PluginSettings Instance 
    { 
     get 
     { 
      return instance; 
     } 
    } 

    # region interface implementation 
    # ... 
    # endregion 

} 

Est-il possible de mettre en œuvre le modèle singleton déjà dans l'interface?

Toute aide appréciée - merci d'avance!

Répondre

11

Vous pouvez éventuellement utiliser une classe abstraite au lieu d'une interface et implémenter le singleton dans la classe abstraite de base.

Vous pouvez utiliser des génériques pour créer l'instance singleton du type de la classe héritée.

+0

Je vais essayer de cette façon - toutes ces solutions semblent soit surdimensionnées ou ne conviennent pas à mon problème. Je dois continuer à apprendre ... ;-) – dhh

+0

Gardez la pression, l'apprentissage prend toute une vie ...;) –

6

Désolé. Les interfaces n'ont pas d'implémentation.

1

Vous pourriez avoir une interface générique, quelque chose comme:

public interface Singleton<T> 
{ 
    T Instance { get; } 
} 
+0

Je pense que vous avez mal lu la question. – Bobby

+0

Hum, cela ne semble pas fonctionner car le champ "Instance" défini pour le pattern singleton est statique. Une idée de comment résoudre ce problème? – dhh

0

Vous pouvez étendre votre interface comme suit:

public interface IPluginSettings 
{ 
    IPluginSettings Instance 
    { 
     get; 
    } 
} 

et dans la classe concrète de PluginSettings mettre en œuvre une logique de la méthode get.

+3

Mais alors vous ne pouvez pas obtenir le PluginSettings jusqu'à ce que vous ayez un PluginSettings, et vous ne pouvez pas l'obtenir parce que vous n'avez pas encore de PluginSettings. –

0

Il semble que vous feriez mieux d'avoir une usine pour construire quelque chose (Singleton) qui implémente l'interface.
MISE À JOUR
Vous pouvez utiliser IoC comme Ninject et lier l'interface à la constante. Essayez:

Bind<IPluginSettings>().ToConstant(PluginSettings); 
-1

Je ne l'ai pas essayé par peut-être vous pouvez créer une interface comme

public interface ISingleton<T> 
{ 
    T Instance 
    { 
     get; 
    } 
} 

Un singleton générique classe

public class Singleton<T> where T : new(){ 
     Singleton() { } 

     public static T Instance 
     { 
      get { return SingletonCreator.instance; } 
     } 

     class SingletonCreator 
     { 
      static SingletonCreator() { } 

      internal static readonly T instance = new T(); 
     } 
} 

Et puis

public class xxx: ISingleton<xxx>{ 
    public Singleton<xxx> Instance... 
} 
+1

L'implémentation statique de l'interface ne correspondra pas, elle doit être implémentée en tant que méthode d'instance, ce qui signifie que vous ne pouvez pas obtenir une instance tant que vous n'avez pas d'instance. –

+0

Jon, tu as raison – pgr

1

Vous ne peut pas l'appliquer à travers un inter le visage, parce que si vous aviez une interface comme:

public interface ISingleton 
{ 
    ISingleton GetInstance(); 
} 

Tout d'abord, l'interface ne couvre que les méthodes d'instance, et non pas statiques, ce qui est ce que vous voulez pour le modèle singleton. Deuxièmement, il n'y a rien à appliquer que GetInstance renvoie un singleton; il pourrait, mais il pourrait aussi renvoyer un nouvel objet à chaque fois, un objet groupé, et ainsi de suite. Ceci est raisonnable, le singleton est un modèle d'implémentation, plus qu'un motif de conception global (une raison pour laquelle il est souvent considéré comme un anti-pattern dans la plupart des cas), donc il n'y a pas grand intérêt à avoir une interface (au sens général) promettent une implémentation, il vaudrait mieux que l'interface (encore une fois, au sens général) promette de renvoyer une instance utilisable, et laisse l'implémentation à la classe en question.