我正在尝试确定将依赖项注入控制器的正确方法,其中要注入的具体类型是基于路由数据参数的变量。
到目前为止,我有以下设置,它完全适用于正常请求:
控制器
public class OrdersController : ODataController
{
private IOrderService ErpService { get; }
public OrdersController(IOrderService orderService)
{
ErpService = orderService;
}
[EnableQuery(PageSize = 100)]
public IQueryable<OrderDto> Get(ODataQueryOptions<OrderDto> queryOptions)
{
return ErpService.Orders(queryOptions);
}
...
// Post
// Patch/Put
// Delete
}
使用以下OData路由配置,我可以指定路由模板应该包含一个&#39;公司&#39;参数:
配置
config.MapODataServiceRoute( "ODataRoute", "data/{company}", model, new DefaultODataPathHandler(),
conventions, new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
这允许我使用静态方法从URL中读取公司ID:
public static string GetSalesCompanyFromRequest()
{
var salesCompany = "";
if (HttpContext.Current == null) return "";
var routeData = HttpContext.Current.Request.RequestContext.RouteData;
if (routeData.Values.ContainsKey("company"))
{
salesCompany = routeData.Values["company"].ToString();
}
return salesCompany;
}
然后,使用Ninject,我可以选择使用哪个具体的IOrderService实例(简化为简洁):
kernel.Bind<IOrderService>()
.To<SageOrderService>()
.When(ctx => GetSalesCompanyFromRequest() == "101").InRequestScope();
kernel.Bind<IOrderService>()
.To<DynamicsAxOrderService>()
.When(ctx => GetSalesCompanyFromRequest() == "222").InRequestScope();
kernel.Bind<IOrderService>()
.To<SapOrderService>()
.When(ctx => GetSalesCompanyFromRequest() == "333").InRequestScope();
连接器配置
Id ErpType ConnectionString
--------------------------------------------
111 Sage "connectionstring1"
222 DynamicsAx "connectionstring2"
333 SAP "connectionstring3"
以下是处理以下网址的方法:
http://odata-demo/data/101/Orders
创建SageOrderService
到OrdersController
DynamicsAxOrderService
http://odata-demo/data/ 222 /订单
创建OrdersController
到HttpContext.Current
HttpContext.Current
同样的逻辑适用于许多不同的服务,例如:
注意:的 我选择将公司ID放在URL中,这样我就可以配置反向代理将请求转发到更靠近目标数据库的本地Web服务器。
这一切都完美无缺,直到我尝试使用OData Batching。
当我发送批量请求时,似乎没有var myOptions = {
zoom : currentZoomLevel,
center : latlng,
disableDefaultUI: true,
minZoom: 2,
maxZoom: 20,
mapTypeId : google.maps.MapTypeId.SATELLITE,
};
map = new google.maps.Map(document.getElementById("googlemap"), myOptions);
(它为空)。
This question询问类似的内容但不考虑OData批量请求。
Comments在这个答案中建议按路线数据注入代码气味,但没有详细说明。
那么,问题是,如何获得批量OData请求的var styleArray = [
{
featureType: "all",
stylers: [
{ visibility: "off" }
]
}/*,{
featureType: "road.arterial",
elementType: "geometry",
stylers: [
{ hue: "#00ffee" },
{ saturation: 50 }
]
},{
featureType: "poi.business",
elementType: "labels",
stylers: [
{ visibility: "off" }
]
}*/
];
var latlng = new google.maps.LatLng(24.91654, 15.31326);
var myOptions = {
zoom : currentZoomLevel,
center : latlng,
disableDefaultUI: true,
minZoom: 2,
maxZoom: 20,
mapTypeId : google.maps.MapTypeId.SATELLITE,
styles :styleArray /*[ { "featureType": "administrative.country", "elementType": "labels", "stylers": [ { "visibility": "on" } ] } ]*/
};
map = new google.maps.Map(document.getElementById("googlemap"), myOptions);
?或者,有没有更好的方法来做我想做的事情?
答案 0 :(得分:0)
由于公司已经在路线数据中,我可以为每一个动作添加一个额外的公司参数,如下所示,以允许公司号码被传入,然后使用工厂获得正确的具体类型:
public class OrdersController : ODataController
{
[EnableQuery(PageSize = 100)]
public IQueryable<OrderDto> Get(ODataQueryOptions<OrderDto> queryOptions, string company)
{
var erpService = ErpServiceFactory.GetService(company);
return erpService.Orders(queryOptions);
}
...
// Post
// Patch/Put
// Delete
}
这意味着我还必须在每个动作中初始化OrderService,这有点气味。
如果我使用ActionFilter定位并将正确的具体类型传递给动作,我想这可能不那么臭:
public class RequiresOrderServiceAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
string salesCompany = "";
var data = actionContext.Request.GetRouteData();
if (data.Values.ContainsKey("company"))
{
salesCompany = data.Values["company"].ToString();
var orderService = ErpServiceFactory.GetService(company);
actionContext.ActionArguments.Add("erpService", orderService);
}
}
}
public class OrdersController : ODataController
{
[EnableQuery(PageSize = 100)]
public IQueryable<OrderDto> Get(ODataQueryOptions<OrderDto> queryOptions, IOrderService erpService)
{
return erpService.Orders(queryOptions);
}
...
// Post
// Patch/Put
// Delete
}
思想?