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
IValueeIConfigurableValueda soli. Parte del mio codice libreria crea un'istanza diAutoGeneratedValue. Se l'utente fornisce un'attuazioneIConfigurableValuepersonalizzata, viene passata a miaAutoGeneratedValue, l'utente decide se ignorarla o meno. Un'altra parte API accetta un'istanza diIValuee 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 :
-
IConfigurableValueestenderà una IValueConfiguration separata e ancheIValuepublic interface IConfigurableValue : IValue, IValueConfiguration { void CopyFrom(IValue source); } public interface IValueConfiguration { Int32 Value { set; } } -
e un
IConfigurableValueche 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?