首页 / C# / c# – Ninject动态绑定到实现
c# – Ninject动态绑定到实现
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – Ninject动态绑定到实现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5234字,纯文字阅读大概需要8分钟。
内容图文
![c# – Ninject动态绑定到实现](/upload/InfoBanner/zyjiaocheng/809/c79caa4fe21f4a929d69f35dbf9af91d.jpg)
关于SO的几个问题是相似的,但不完全是我正在寻找的.我想基于运行时条件进行Ninject绑定,这在启动时是不可预知的.关于动态绑定的SO的其他问题围绕基于配置文件或某些类似的绑定 – 我需要在处理特定实体的数据时基于数据库值有条件地发生.例如.,
public class Partner
{
public int PartnerID { get; set; }
public string ExportImplementationAssembly { get; set; }
}
public interface IExport
{
void ExportData(DataTable data);
}
在其他地方,我有2个dll实现IExport
public PartnerAExport : IExport
{
private readonly _db;
public PartnerAExport(PAEntities db)
{
_db = db;
}
public void ExportData(DataTable data)
{
// export parter A's data...
}
}
然后为伙伴B;
public PartnerBExport : IExport
{
private readonly _db;
public PartnerBExport(PAEntities db)
{
_db = db;
}
public void ExportData(DataTable data)
{
// export parter B's data...
}
}
目前的Ninject绑定是;
public class NinjectWebBindingsModule : NinjectModule
{
public override void Load()
{
Bind<PADBEntities>().ToSelf();
Kernel.Bind(s => s.FromAssembliesMatching("PartnerAdapter.*.dll")
.SelectAllClasses()
.BindDefaultInterfaces()
);
}
}
那么如何设置绑定以便我可以做到;
foreach (Partner partner in _db.Partners)
{
// pseudocode...
IExport exportModule = ninject.Resolve<IExport>(partner.ExportImplementationAssembly);
exportModule.ExportData(_db.GetPartnerData(partner.PartnerID));
}
这可能吗?它似乎应该是,但我不知道如何去做.上面的现有绑定配置适用于静态绑定,但我需要一些我可以在运行时解决的东西.以上是可能的还是我只是想绕过Ninject并使用旧式反射加载插件?如果是这样,我如何使用该方法通过Ninject解析任何构造函数参数,如同静态绑定对象一样?
更新:我已经使用BatteryBackupUnit的解决方案更新了我的代码,以便我现在拥有以下内容.
Bind<PADBEntities>().ToSelf().InRequestScope();
Kernel.Bind(s => s.FromAssembliesMatching("PartnerAdapter.*.dll")
.SelectAllClasses()
.BindDefaultInterfaces()
.Configure(c => c.InRequestScope())
);
Kernel.Bind(s => s.FromAssembliesMatching("PartnerAdapter.Modules.*.dll")
.SelectAllClasses()
.InheritedFrom<IExportService>()
.BindSelection((type, baseTypes) => new[] { typeof(IExportService) })
);
Kernel.Bind<IExportServiceDictionary>().To<ExportServiceDictionary>().InSingletonScope();
ExportServiceDictionary dictionary = KernelInstance.Get<ExportServiceDictionary>();
在2个测试模块中实例化导出实现可以正常工作并实例化PADBEntites上下文.但是,我的服务层中的所有其他绑定现在不再适用于系统的其余部分.同样,如果我将PADBEntities变量/ ctor参数更改为ISomeEntityService组件,则无法绑定导出层.似乎我错过了配置绑定以使其工作的最后一步.有什么想法吗?
错误:“激活ISomeEntityService时出错.没有匹配的绑定可用且类型不可自绑定”
更新2:最终使用BatteryBackupUnit的解决方案进行了一些试验和错误,虽然我对跳跃思路不太满意.欢迎任何其他更简洁的解决方案.
我更改了原来的约定绑定;
Kernel.Bind(s => s.FromAssembliesMatching("PartnerAdapter.*.dll")
.SelectAllClasses()
.BindDefaultInterfaces()
);
更加冗长和明确;
Bind<IActionService>().To<ActionService>().InRequestScope();
Bind<IAuditedActionService>().To<AuditedActionService>().InRequestScope();
Bind<ICallService>().To<CallService>().InRequestScope();
Bind<ICompanyService>().To<CompanyService>().InRequestScope();
//...and so on for 30+ lines
不是我最喜欢的解决方案,但它适用于基于显式和约定的绑定,但不适用于两个约定.任何人都可以看到我的绑定错误在哪里?
更新3:忽略Update 2中绑定的问题.看来我在Ninject中发现了一个与引用库中有多个绑定模块有关的错误.模块A的更改,即使从未通过断点命中,也会使用不同的模块B明确地破坏项目.
解决方法:
重要的是要注意,虽然实际的“条件匹配”是运行时条件,但实际上您事先知道可能的匹配集(至少在构建容器时启动时) – 这可以通过使用约定来证明.这就是条件/上下文绑定的含义(在Ninject WIKI中有描述,并在几个问题中有所介绍).所以你实际上不需要在任意运行时间进行绑定,而只需要在任意时间进行分辨率/选择(分辨率实际上可以提前完成=>提前失败).
这是一个可能的解决方案,其特点是:
>在启动时创建所有绑定
>提前失败:验证启动时的绑定(通过实例化所有绑定的IExport)
>在任意运行时选择IExport
.
internal interface IExportDictionary
{
IExport Get(string key);
}
internal class ExportDictionary : IExportDictionary
{
private readonly Dictionary<string, IExport> dictionary;
public ExportDictionary(IEnumerable<IExport> exports)
{
dictionary = new Dictionary<string, IExport>();
foreach (IExport export in exports)
{
dictionary.Add(export.GetType().Assembly.FullName, export);
}
}
public IExport Get(string key)
{
return dictionary[key];
}
}
组成根:
// this is just going to bind the IExports.
// If other types need to be bound, go ahead and adapt this or add other bindings.
kernel.Bind(s => s.FromAssembliesMatching("PartnerAdapter.*.dll")
.SelectAllClasses()
.InheritedFrom<IExport>()
.BindSelection((type, baseTypes) => new[] { typeof(IExport) }));
kernel.Bind<IExportDictionary>().To<ExportDictionary>().InSingletonScope();
// create the dictionary immediately after the kernel is initialized.
// do this in the "composition root".
// why? creation of the dictionary will lead to creation of all `IExport`
// that means if one cannot be created because a binding is missing (or such)
// it will fail here (=> fail early).
var exportDictionary = kernel.Get<IExportDictionary>();
现在IExportDictionary可以注入到任何组件中,就像“必需”一样使用:
foreach (Partner partner in _db.Partners)
{
// pseudocode...
IExport exportModule = exportDictionary.Get(partner.ExportImplementationAssembly);
exportModule.ExportData(_db.GetPartnerData(partner.PartnerID));
}
内容总结
以上是互联网集市为您收集整理的c# – Ninject动态绑定到实现全部内容,希望文章能够帮你解决c# – Ninject动态绑定到实现所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。