I seguenti frammenti di codice sono semplificati per dimostrare il contesto! Le interfacce e le classi effettive sono POCO con proprietà aggiuntive. I tipi sono parte della libreria su cui sto lavorando, le interfacce sono API pubbliche, le API interne delle classi.
Ho:
-
un'interfaccia IValue
public interface IValue { Int32 Value { get; } }
-
2 diverse interfacce IConfigurableValue (2 rami separati di git) che estendono
IValue
, vedi più avantipublic interface IConfigurableValue : IValue { void CopyFrom(IValue source); // is always part of the interface }
-
un'implementazione AutoGeneratedValue
internal class AutoGeneratedValue : IConfigurableValue { public Int32 Value { get; set; } public void CopyFrom(IValue source) { Value = source.Value; } }
-
codice che deve accedere al solo getter (tramite
IValue
) e al codice che richiede unIConfigurableValue
(nessuna implementazione nota in fase di compilazione)Gli utenti esterni della libreria possono implementare
IValue
eIConfigurableValue
da soli. Parte del mio codice libreria crea un'istanza diAutoGeneratedValue
. Se l'utente fornisce un'attuazioneIConfigurableValue
personalizzata, viene passata a miaAutoGeneratedValue
, l'utente decide se ignorarla o meno. Un'altra parte API accetta un'istanza diIValue
e fa qualcosa. Ha solo bisogno di leggere le proprietà dell'istanza. Questa parte dell'API può essere invocata senza richiedere mai alcuna istanza diIConfigurableValue
.
Il mio obiettivo per la libreria è a) di offrire metodi che richiedono un'istanza IValue
ist e b) metodi per generare automaticamente% istanze diIValue
o popolare istanze fornite da IConfigurableValue
che possono essere usato per la parte a.
Al momento ho 2 rami con le seguenti definizioni di IConfigurableValue
:
-
IConfigurableValue
estenderà una IValueConfiguration separata e ancheIValue
public interface IConfigurableValue : IValue, IValueConfiguration { void CopyFrom(IValue source); } public interface IValueConfiguration { Int32 Value { set; } }
-
e un
IConfigurableValue
che definisce il setter stesso, senza interfaccia aggiuntivapublic interface IConfigurableValue : IValue { new Int32 Value { set; } void CopyFrom(IValue source); }
Con entrambe le opzioni ho bisogno di lanciare IConfigurableValue
in IValue
per accedere al getter nella parte b della mia libreria.
Con l'opzione no. 1 Ho bisogno di lanciare IConfigurableValue
in IValueConfiguration
per accedere al setter.
Opzione no. 2 mi nega l'utilizzo tramite un'interfaccia setter-only perché qualsiasi IConfigurableValue
è un IValue
,
con no. 1 Potrei usare IValueConfiguration
se ne ho bisogno. - Questo non è un requisito reale della mia API, ma non conosco le future richieste per l'API.
C'è un'altra opzione per raggiungere il mio obiettivo e quale opzione dovrebbe essere preferita?