是否可以使用Ninject在注入的类构造函数中解析URL ?
本文关键字:构造函数 URL 可以使 Ninject 注入 是否 | 更新日期: 2023-09-27 17:50:52
我有一个在ASP中使用的服务类。Net MVC 5 web应用程序和控制台应用程序。我们叫它MyService。当MyService对象被Ninject实例化并传递给web环境中的控制器时,我希望使用如下的内容来解析URL
url = Request.Url.GetLeftPart(UriPartial.Authority) + Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Emailer" });
当我的控制台应用程序实例化MyService时(也使用Ninject,但在非web上下文中),我希望它从AppSettings中获取url,如下所示:
url = ConfigurationManager.AppSettings["EmailerUrl"];
这可行吗?我认为它可能是使用WithConstructorArgument()在NinjectWebCommon适当的参数。RegisterServices(IKernel内核)创建绑定时,但我不知道究竟如何。
我的猜测是,MyService构造函数必须知道它被注入的控制器类,并且能够从该控制器调用方法。如果没有已知的控制器类,那么它将使用应用程序的设置。
当然,我也可以在传入MyService对象的每个控制器构造函数中设置url参数,也可以在控制台应用程序的其他地方设置url参数,但我不希望每次实例化MyService对象时都要设置这个属性。我们从:
开始public interface IUrl
{
Url Url { get; }
}
internal class ControllerBasedUrl : IUrl
{
public ControllerBasedUrl(string controllerName)
{
this.Url = null; // implement
}
public Url Url { get; private set; }
}
internal class AppConfigBasedUrl : IUrl
{
public AppConfigBasedUrl()
{
this.Url = null; // implement
}
public Url Url { get; private set; }
}
有多种方法可以使用:
a)让应用程序知道你是在运行web应用程序还是控制台应用程序,然后使用条件绑定:
var kernel = new StandardKernel();
if (runningInConsoleApplication)
{
kernel.Bind<IUrl>().To<AppConfigBasedUrl>();
}
else
{
kernel.Bind<IUrl>().ToMethod(ctx =>
{
IRequest controllerRequest = ctx.Request.TraverseRequestChainAndFindMatch(x => x.Target.Name.EndsWith("Controller"));
return new ControllerBasedUrl(controllerRequest.Target.Type.Name);
});
}
b)使url的绑定以是否注入到控制器为条件:
var kernel = new StandardKernel();
kernel.Bind<IUrl>().ToMethod(ctx =>
{
IRequest controllerRequest = ctx.Request.TraverseRequestChainAndFindMatch(x => x.Target.Name.EndsWith("Controller"));
if (controllerRequest != null)
{
return new ControllerBasedUrl(controllerRequest.Target.Type.Name);
}
return new AppConfigBasedUrl();
});
同时使用扩展名:
public static class RequestExtensions
{
public static IRequest TraverseRequestChainAndFindMatch(this IRequest request, Func<IRequest, bool> matcher)
{
if (matcher(request))
{
return request;
}
if (request.ParentRequest != null)
{
return request.ParentRequest.TraverseRequestChainAndFindMatch(matcher);
}
return null;
}
}