Внедрение конкретной реализации WCF ServiceContract на основе значения off в файле конфигурации димамно
Скажем, у меня есть следующий контракт на обслуживание и две конкретные реализации:
[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...
}
}
Это связано с ServiceBehavior
так что я могу создать экземпляр, пока служба работает на основе файла конфигурации:
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();
}
}
Мой вопрос: как я могу внедрить конкретную реализацию, используя Ninject, основываясь на изменяющемся значении в файле конфигурации? Кажется, я должен сделать следующее:
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>();
}
}
А потом в InstanceProvider
:
public object GetInstance(InstanceContext instanceContext, Message message) {
return _kernel.Get<ISearchService>();
}
Однако привязки в Ninject не меняются после того, как я изменяю значение в файле конфигурации. Есть ли способ изменить привязку на основе значения в файле конфигурации? Я что-то здесь не так делаю?
2 ответа
Ваш модуль работает не так, как вы ожидаете, потому что есть поле и локальная переменная с тем же именем.
Также взгляните на условные привязки. .Когда()
Вы самостоятельно размещаетесь в службе Windows. Сохранение файла.config не приводит к автоматической перезапуску службы Windows и обнаружению изменения.config (в отличие от IIS). Так что, если вы собираете ядро при запуске, нет триггера, который заставил бы его перестраиваться.
Вам придется изменить свою реализацию, чтобы использовать .When()
метод для обеспечения реализации на основе параметров конфигурации. Это будет выглядеть примерно так:
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;
}