Stack Overflow 上有几个类似但不完全是我要找的问题。我想根据运行时条件进行 Ninject 绑定,这在启动时并不预先知道。Stack Overflow 上用于动态绑定的其他问题围绕基于配置文件或类似文件的绑定展开——我需要在处理特定实体的数据时根据数据库值有条件地发生它。例如,
public class Partner
{
public int PartnerID { get; set; }
public string ExportImplementationAssembly { get; set; }
}
public interface IExport
{
void ExportData(DataTable data);
}
在其他地方,我有 2 个实现 IExport 的 dll
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:最终使用 's 的解决方案进行了一些试验和错误,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:忽略更新 2 中的绑定问题。看来我在 Ninject 中发现了一个与引用库中具有多个绑定模块有关的错误。模块 A 中的更改,即使从未通过断点命中也会使用不同的模块 B 显式破坏项目。看图。