动态地注入基于配置文件中的值的 WCF 服务协定的具体实现
本文关键字:服务 实现 WCF 注入 配置文件 动态 | 更新日期: 2023-09-27 18:30:44
假设我有以下服务协定和两个具体的实现:
[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 中的绑定不会更改。有没有办法根据配置文件中的值更改绑定?我在这里做错了什么吗?
您的模块没有按预期运行,因为有一个字段和一个具有相同名称的局部变量。
另请查看条件绑定。当()
您是在 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;
}