我创建了一个自定义格式化程序,以输出为pdf。请参阅以下主题中的更多详细信息:
Dependency Injection to CustomFormatter
根据答案它正常工作。但现在我有2个报告如下;
public interface IPdfFactory {
MemoryStream Create(object model);
}
public class BillReport: IPdfFactory {
private readonly IBusinessLogic _logic;
public PdfFactory(IBusinessLogic logic) {
this._logic = logic;
}
public MemoryStream Create(object model) {
var stream = new MemoryStream();
//...Pdf generation code
//call data update
_logic.update(model);
return stream;
}
}
public class PurchaseReport: IPdfFactory {
private readonly IBusinessLogic _logic;
public PdfFactory(IBusinessLogic logic) {
this._logic = logic;
}
public MemoryStream Create(object model) {
var stream = new MemoryStream();
//...Pdf generation code
//call data update
_logic.update(model);
return stream;
}
}
这里我如何指定依赖注入。我阅读了有关上下文绑定的内容,并认为它解决了这个问题
我刚刚添加了如下注射剂;
kernel.Bind<IPdfFactory>().To<BillReport>().When(request => request.Target.Member.Name.StartsWith("Bill"));
kernel.Bind<IPdfFactory>().To<PurchaseReport>().When(request => request.Target.Member.Name.StartsWith("Purchase"));
kernel.Bind<PdfMediaTypeFormatter>().ToSelf();
在WebApi配置中,
var formatter = (PdfMediaTypeFormatter)config.DependencyResolver.GetService(typeof(PdfMediaTypeFormatter));
config.Formatters.Add(formatter);
运行时,我总是在格式化程序中为null。请帮我找错误
更新
我使用了ninject.extensions.factory。我改变了我的代码,如下所示;
public interface IPdfFactory
{
IReport GetPurchaseReport();
IReport GetBillReport();
}
public interface IReport
{
Task<MemoryStream> Create(object model);
}
现在我的BillReport和PurchaseReport实现了IReport接口。此外,Pdfmapper类仅具有IReport接口
ninject cofiguration代码如下;
kernel.Bind<IReport>().To<PurchaseReport>().Named("PurchaseReport");
kernel.Bind<IReport>().To<BillReport>().Named("BillReport");
kernel.Bind<IPdfFactory>().ToFactory();
kernel.Bind<PdfMediaTypeFormatter>().ToSelf();
在配置中,再次添加自定义格式化程序区域,格式化程序为null
var formatter = (PdfMediaTypeFormatter)config.DependencyResolver.GetService(typeof(PdfMediaTypeFormatter));
config.Formatters.Add(formatter);
新更新:
我的ninject配置:
kernel.Bind<IReport>().To<PurchaseReport>().InRequestScope();
kernel.Bind<IReport>().To<BillReport>().InRequestScope();
kernel.Bind<IPdfFactory>().To<PdfFactory>().InRequestScope();
kernel.Bind<PdfMediaTypeFormatter>().ToSelf();
在webapi配置中:
var formatter = (PdfMediaTypeFormatter)config.DependencyResolver.GetService(typeof(PdfMediaTypeFormatter));
config.Formatters.Add(formatter);
现在格式化程序也为null。什么错过了?
答案 0 :(得分:1)
更新报告界面,以便能够识别它可以处理的模型
public interface IReport {
bool CanHandle(object model);
Task<MemoryStream> Create(object model);
}
假设有一些像这样的示例模型。
class BillModel : IPdf {
//...
}
class PurchaseModel : IPdf {
//...
}
报告实现会有一些类似于格式化程序中的逻辑。
public class BillReport : IReport {
Func<Type, bool> typeisIPdf = (type) => typeof(BillModel).IsAssignableFrom(type);
Func<Type, bool> typeisIPdfCollection = (type) => typeof(IEnumerable<BillModel>).
IsAssignableFrom(type);
private readonly IBusinessLogic _logic;
public BillReport(IBusinessLogic logic) {
this._logic = logic;
}
public bool CanHandle(object model) {
if (model == null) return false;
var type = model.GetType();
return typeisIPdf(type) || typeisIPdfCollection(type);
}
public Task<MemoryStream> Create(object model) {
var stream = new MemoryStream();
if (CanHandle(model.GetType())) {
//...Pdf generation code
//call data update
_logic.update(model);
}
return Task.FromResult(stream);
}
}
public class PurchaseReport : IReport {
Func<Type, bool> typeisIPdf = (type) => typeof(PurchaseModel).IsAssignableFrom(type);
Func<Type, bool> typeisIPdfCollection = (type) => typeof(IEnumerable<PurchaseModel>).
IsAssignableFrom(type);
private readonly IBusinessLogic _logic;
public PurchaseReport(IBusinessLogic logic) {
this._logic = logic;
}
public bool CanHandle(object model) {
if (model == null) return false;
var type = model.GetType();
return typeisIPdf(type) || typeisIPdfCollection(type);
}
public Task<MemoryStream> Create(object model) {
var stream = new MemoryStream();
if (CanHandle(model.GetType())) {
//...Pdf generation code
//call data update
_logic.update(model);
}
return Task.FromResult(stream);
}
}
工厂现在只需要了解IReport
的所有实现。然后它将获得可以处理提供的模型并执行所需功能的报告
public class PdfFactory : IPdfFactory {
private IEnumerable<IReport> reports;
public PdfFactory(IReport[] reports) {
this.reports = reports;
}
public Task<MemoryStream> Create(object model) {
var report = reports.FirstOrDefault(r => r.CanHandle(model));
if (report != null) {
return report.Create(model);
}
return Task.FromResult<MemoryStream>(null);
}
}
使用这种抽象方法的优点是您甚至不必更新格式化程序,并且正在对其他依赖项和实现问题进行所有更改。
确保注册所有IReport
实施,以便在解决后将其传递给IPdfFactory
。
参考Multi injection文档
kernel.Bind<IReport>().To<PurchaseReport>();
kernel.Bind<IReport>().To<BillReport>();
kernel.Bind<IPdfFactory>().To<PdfFactory>();
kernel.Bind<PdfMediaTypeFormatter>().ToSelf();