我有一个创建 pdf 所需的服务类,它需要注入(inject) ControllerContext,以便呈现 html => pdf
。
此服务通过中间层调用,该中间层不引用 web/mvc 项目。这很好,因为 ninject 完成了所有必需的服务注入(inject)等。
这就是服务的样子(为了这些目的而简化)
public class PdfCreatorService : AbstractUrlBasedPdfCreatorService
{
[Inject]
public ControllerContext ControllerContext { get; set; }
public override byte[] CreateReport(int reportId)
{
var result = new PdfController().CreateReport(reportId);
using (var it = new ResponseCapture(ControllerContext.RequestContext))
{
result.ExecuteResult(ControllerContext);
return it.ReadAllContents();
}
}
}
这是简化的调用堆栈:
Ninject 正在访问 PdfCreatorService,没问题,但是:我需要以某种方式将 ControllerContext 从 HomeController(通过中间层)转发到 PdfCreatorService 。
虽然中间层不能对 ControllerContext 有任何引用。
我看过提供者、工厂、解析器等。
但找不到合适的解决方案。
任何帮助表示赞赏!
干杯
最佳答案
好的。我想出了一个我很满意的解决方案。
这是我检索 ControllerContext 的方式:
public class PdfCreatorService
{
[Inject]
public ControllerContextProvider contextProvider { get; set; }
[Inject]
public PdfController pdfController { get; set; }
public override byte[] CreateReport(int reportId)
{
var context = contextProvider.GetControllerContext();
using (var stream = new ResponseCapture(context.RequestContext))
{
// Setup Controller
var routeData = new RouteData(context.RouteData.Route, context.RouteData.RouteHandler);
routeData.Values.Add("action", "CreateReport");
routeData.Values.Add("controller", "Pdf");
routeData.Values.Add("id", reportId);
var pdfContext = new ControllerContext(context.HttpContext, routeData, pdfController);
// Execute Controller
var result = pdfController.CreateReport(reportId);
result.ExecuteResult(pdfContext);
return stream.ReadAllContents();
}
}
}
这是在原始 Controller 中设置上下文的方法:
public abstract class HomeController : Controller
{
[Inject]
public ControllerContextProvider ControllerContextProvider { get; set; }
protected override IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state)
{
ControllerContextProvider.GetControllerContext = () => ControllerContext;
return base.BeginExecute(requestContext, callback, state);
}
}
这是提供程序类的样子:
public class ControllerContextProvider
{
public Func<ControllerContext> GetControllerContext { get; set; }
}
这就是我绑定(bind)它的方式:
public class PortalNinjectModule : NinjectModule
{
public override void Load()
{
Bind<ControllerContextProvider>().ToSelf().InRequestScope();
}
}
仍然有兴趣看看是否有人有更优雅的解决方案。
关于c# - 使用 Ninject 绑定(bind) Controller 上下文,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16790330/