2015-05-22 16 views
9

Ho il seguente metodo di estensione, che esiste (naturalmente) in una classe statica.Come risolvere la dipendenza della classe statica con Unity?

public static class MyExtensions 
{ 
    [Dependency] 
    private static IMyDataContext _myDataContext { get; set; } 

    public static void MyExtensionMethod(this MyType myType) 
    { 
     // do stuff 

     _myDataContext.DoAwesomeThing(); 
    } 
} 

dell'oggetto _myDataContext è nullo.

Normalmente userei lo UnityContainer per registrare il tipo, ma poiché questa è una classe statica, non posso.

Cosa è necessario per creare un'istanza _ myDataContext in modo che non sia nullo quando è necessario?

risposta

12

Come già accennato, Unity non può essere utilizzato per risolvere la classe perché è statico. Ci sono alcune opzioni per questo. Il mio preferito è usare il pattern Abstract Factory. Tendo a modificare il modello solo un po 'per lavorare bene con DI.

La fabbrica tipicamente tipo di assomiglia a questo:

/// <summary> 
/// Creates an IMyDataContext instance 
/// </summary> 
public static class MyDataContextFactory 
{ 
    /// <summary> 
    /// The factory used to create an instance 
    /// </summary> 
    static Func<IMyDataContext> factory; 

    /// <summary> 
    /// Initializes the specified creation factory. 
    /// </summary> 
    /// <param name="creationFactory">The creation factory.</param> 
    public static void SetFactory(Func<IMyDataContext> creationFactory) 
    { 
     factory = creationFactory; 
    } 

    /// <summary> 
    /// Creates a new IMyDataContext instance. 
    /// </summary> 
    /// <returns>Returns an instance of an IMyDataContext </returns> 
    public static IMyDataContext CreateContext() 
    { 
     if (factory == null) throw new InvalidOperationException("You can not create a context without first building the factory."); 

     return factory(); 
    } 
} 

Nel vostro processo di bootstrap (dove mai si imposta le registrazioni di servizio), è possibile inizializzare la fabbrica per risolvere il vostro dipendenza.

MyDataContextFactory.SetFactory(() => this.Container.Resolve<IMyDataContext>()); 

Ora nel metodo di estensione, si recupera un contesto.

public static class MyExtensions 
{ 
    public static void MyExtensionMethod(this MyType myType) 
    { 
     MyDataContextFactory.CreateContext().DoAwesomeThing(); 
    } 
} 

tua registrazione Unità del contesto, in grado di gestire le diverse configurazioni diverse del servizio, se ci sono le condizioni per risolverlo. Se esiste la possibilità che il contesto possa essere impostato da qualcosa di diverso da Unity, quel proprietario può semplicemente passare un nuovo delegato che verrà utilizzato dal metodo di estensione.

Io tendo ad evitare di passare i contenitori stessi nelle mie fabbriche, poiché questo inizia a strisciante stretto accoppiamento dei contenitori alla mia app. Se ho intenzione di passare qualcosa in fabbrica, preferirei che fosse un delegato di fabbrica usato per risolvere tramite DI, piuttosto che passare il contenitore DI in sé.

+0

Come è possibile rendere generica l'implementazione di cui sopra? Come voglio passare qualsiasi interfaccia? IMyDataContext può essere qualsiasi interfaccia. Potete fornire qualche implementazione? –

+0

Dovreste semplicemente rendere generici i metodi 'SetContext' e' CreateContext'. La tua implementazione risolverebbe '' invece di 'IDataContext'. Dovresti invece archiviare il 'Func 'e poi provare a lanciarlo su' Func 'quando chiami' CreateContext'. A dire il vero, valuterei di utilizzare un metodo di estensione che ha bisogno di restituire dati da una classe statica come questa. DI le dipendenze nel costruttore del chiamante, quindi fornisci la dipendenza nella chiamata al metodo di estensione come parametro del metodo. –

Problemi correlati