2012-04-11 4 views
1

sagen, dass ich die folgende Service-Vertrag und zwei konkrete Implementierungen haben:eine konkrete Implementierung eines WCF Servicecontract basiert off-Wert in einer Konfigurationsdatei Injizieren dymamically

[OperationContract] 
public interface ISearchService { 
    public ICollection<string> Search(string text); 
} 

[SearchServiceBehaviour] 
public class SolrSearchService : ISearchService { 
    public ICollection<string> Search(string text) { 
     // Implementation... 
    } 
} 

[SearchServiceBehaviour] 
public class SqlSearchService : ISearchService { 
    public ICollection<string> Search(string text) { 
     // Implementation... 
    } 
} 

Diese mit einem ServiceBehavior zugeschrieben werden, so dass ich das schaffen kann Beispiel während der Dienst eine Konfigurationsdatei basiert weg läuft:

public class SearchServiceBehaviour : Attribute, IServiceBehavior { 
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { 
     foreach (var item in serviceHostBase.ChannelDispatchers) { 
      var dispatcher = item as ChannelDispatcher; 

      if (dispatcher != null) { 
       dispatcher.Endpoints.ToList().ForEach(e => { 
        e.DispatchRuntime.InstanceProvider = new SearchServiceInstanceProvider(); 
       }); 
      } 
     } 
    } 
} 

public class SearchServiceInstanceProvider : IInstanceProvider { 
    public object GetInstance(InstanceContext instanceContext, Message message) { 
     // Should cache and only do this at an interval. 
     ConfigurationManager.RefreshSection("appSettings"); 
     var index = ConfigurationManager.AppSettings["UseSolr"] as string; 

     bool UseSolr; 
     bool.TryParse(index, out UseSolr); 

     if (UseSolr) 
      return new IndexedSearchService(); 
     else 
      return new SearchService(); 
    } 
} 

Meine Frage ist, wie kann ich die konkrete Umsetzung injizieren mit Ninject einen sich ändernden Wert in einer Konfigurationsdatei basiert weg? Es scheint zu mir folgend tun soll:

public class SearchServiceModule : NinjectModule { 
    private bool UseSolr; 

    public SearchServiceModule() { 
     // Should cache and only do this at an interval. 
     ConfigurationManager.RefreshSection("appSettings"); 
     var index = ConfigurationManager.AppSettings["UseSolr"] as string; 

     bool.TryParse(index, out UseSolr); 
    } 

    public override Load() { 
     if (UseSolr) 
      Bind<ISearchService>().To<SolrSearchService>(); 
     else 
      Bind<ISearchService>().To<SqlSearchService>(); 
    } 
} 

Und dann in den InstanceProvider:

public object GetInstance(InstanceContext instanceContext, Message message) { 
    return _kernel.Get<ISearchService>(); 
} 

jedoch die Bindungen in Ninject nicht ändern, nachdem ich den Wert in der Konfigurationsdatei ändern . Gibt es eine Möglichkeit, die Bindung basierend auf dem Wert in der Konfigurationsdatei zu ändern? Mache ich hier etwas falsch?

+0

Ist dieser Dienst in IIS gehostet oder in einem Konsolen/Windows-Dienst selbst gehostet? –

+0

@DrewMarsh Selbst in einem Windows-Dienst gehostet. – Soliah

Antwort

4

Ihr Modul verhält sich nicht wie erwartet, da ein Feld und eine lokale Variable mit demselben Namen vorhanden sind.

Siehe auch bedingte Bindungen. .When()

+0

Der Fehler wurde behoben. Triff es von Hand. – Soliah

1

Sie sind in einem Windows-Dienst selbsthostend. Durch das Speichern einer .config-Datei wird der Windows-Dienst nicht automatisch wiederverwendet und Ihre .config-Änderung wird bemerkt (anders als bei IIS). Wenn Sie also Ihren Kernel beim Start erstellen, gibt es keinen Trigger, der das Kernel neu aufbauen würde.

Sie müssen Ihre Implementierung ändern, um die .When()-Methode zu verwenden, um die Implementierung basierend auf der Konfigurationseinstellung bedingt bereitzustellen. Das würde ungefähr so ​​aussehen:

public override Load() 
{ 
    Bind<ISearchService>().To<SolrSearchService>().When(r => ShouldUseSolr()); 
    Bind<ISearchService>().To<SqlSearchService>().When(r => !ShouldUseSolr()); 
} 

private static ShouldUseSolr() 
{ 
    // Should cache and only do this at an interval. 
    ConfigurationManager.RefreshSection("appSettings"); 
    var index = ConfigurationManager.AppSettings["UseSolr"] as string; 

    bool result; 

    bool.TryParse(index, out result); 

    return result; 
} 
+0

Ich rufe 'ConfigurationManager.RefreshSection (" appSettings ");', um die Konfigurationsdatei erneut zu lesen. – Soliah

+0

Ich habe meine Antwort basierend auf dem, was ich denke, dass du jetzt los bist, aktualisiert. –

Verwandte Themen